git reset
é tudo sobre mudança HEAD
, e geralmente o ramo ref .
Pergunta: e a árvore de trabalho e o índice?
Quando empregado com --soft
, move HEAD
, na maioria das vezes atualizando o ramo ref, e somente oHEAD
.
Isso difere de commit --amend
:
- não cria um novo commit.
- na verdade, ele pode mover HEAD para qualquer confirmação (como
commit --amend
é apenas não mover HEAD, enquanto permite refazer a confirmação atual)
Acabei de encontrar este exemplo de combinação:
- uma fusão clássica
- uma mesclagem de subárvore
tudo em um (polvo, pois há mais de dois ramos mesclados) confirma a mesclagem.
Tomas "wereHamster" Carnecky explica em seu artigo "Subtree Octopus merge" :
- A estratégia de mesclagem de subárvore pode ser usada se você deseja mesclar um projeto em um subdiretório de outro projeto e, posteriormente, manter o subprojeto atualizado. É uma alternativa aos submódulos git.
- A estratégia de mesclagem de polvo pode ser usada para mesclar três ou mais ramificações. A estratégia normal pode mesclar apenas dois ramos e, se você tentar mesclar mais do que isso, o git volta automaticamente à estratégia do polvo.
O problema é que você pode escolher apenas uma estratégia. Mas eu queria combinar os dois para obter um histórico limpo, no qual todo o repositório seja atualizado atomicamente para uma nova versão.
Eu tenho um superprojeto, vamos chamá-lo projectA
e um subprojeto projectB
, que eu mesclei em um subdiretório de projectA
.
(essa é a parte de mesclagem da subárvore)
Também estou mantendo alguns commits locais.
ProjectA
é atualizado regularmente, projectB
tem uma nova versão a cada dois dias ou semanas e geralmente depende de uma versão específica do projectA
.
Quando eu decido atualizar os dois projetos, eu simplesmente não extrao projectA
e, projectB
como isso criaria dois commits para o que deveria ser uma atualização atômica de todo o projeto .
Em vez disso, eu criar um único merge comprometer que combina projectA
, projectB
e meus commits locais .
A parte complicada aqui é que essa é uma mesclagem de polvo (três cabeças), mas projectB
precisa ser mesclada com a estratégia da subárvore . Então é isso que eu faço:
# Merge projectA with the default strategy:
git merge projectA/master
# Merge projectB with the subtree strategy:
git merge -s subtree projectB/master
Aqui, o autor usou ae reset --hard
, em seguida, read-tree
para restaurar o que as duas primeiras mesclagens fizeram na árvore e no índice de trabalho, mas é aí que reset --soft
pode ajudar:
Como refazer essas duas mesclagens que funcionaram, ou seja, minha árvore de trabalho e índice são tudo bem, mas sem ter que gravar esses dois commits?
# Move the HEAD, and just the HEAD, two commits back!
git reset --soft HEAD@{2}
Agora, podemos retomar a solução de Tomas:
# Pretend that we just did an octopus merge with three heads:
echo $(git rev-parse projectA/master) > .git/MERGE_HEAD
echo $(git rev-parse projectB/master) >> .git/MERGE_HEAD
# And finally do the commit:
git commit
Então, cada vez:
- você está satisfeito com o que termina (em termos de árvore de trabalho e índice)
- você não está satisfeito com todos os commits que levaram para chegar lá:
git reset --soft
é a resposta.
git reset --soft
: stackoverflow.com/questions/6869705/…