Pergunta

Suponha que você tenha um histórico contendo as três commits A, B e C :

A-B-C

Gostaria de combinar os dois commits A e B para um commit AB :

AB-C

Eu tentei

git rebase -i A

que abre meu editor com o seguinte conteúdo:

pick e97a17b B
pick asd314f C

Eu mudar isso para

squash e97a17b B
pick asd314f C

Em seguida, Git 1.6.0.4 diz:

Cannot 'squash' without a previous commit

Existe uma maneira ou isso é simplesmente impossível?

Foi útil?

Solução

Use git rebase -i --root a partir de Git versão 1.7.12 .

No arquivo rebase interativo, altere a segunda linha de cometer B e abóbora e deixar as outras linhas no escolher :

pick f4202da A
squash bea708e B
pick a8c6abc C

Isto irá combinar os dois commits A e B para um commit AB .

esta resposta .

Outras dicas

Você tentou:

git rebase -i A

É possível começar como que se você continuar com edit em vez de squash:

edit e97a17b B
pick asd314f C

, em seguida, executar

git reset --soft HEAD^
git commit --amend
git rebase --continue

Feito.

A foi o commit inicial, mas agora você quer B ser o commit inicial. commits git são árvores inteiras, não diffs mesmo se eles são normalmente descritos e visualizadas em termos do diff que eles introduzem.

Esta receita funciona mesmo se houver vários commits entre A e B, e B e C.

# Go back to the last commit that we want
# to form the initial commit (detach HEAD)
git checkout <sha1_for_B>

# reset the branch pointer to the initial commit,
# but leaving the index and working tree intact.
git reset --soft <sha1_for_A>

# amend the initial tree using the tree from 'B'
git commit --amend

# temporarily tag this new initial commit
# (or you could remember the new commit sha1 manually)
git tag tmp

# go back to the original branch (assume master for this example)
git checkout master

# Replay all the commits after B onto the new initial commit
git rebase --onto tmp <sha1_for_B>

# remove the temporary tag
git tag -d tmp

No caso de rebase interativo, você tem que fazê-lo antes de A para que a lista será:

pick A
pick B
pick C

para tornar-se:

pick A
squash B
pick C

Se A é o commit inicial, você tem que ter uma inicial diferente cometer antes A. Git pensa em diferenças, ele vai trabalhar sobre a diferença entre (A e B) e (B e C). Daí a abóbora não funciona no seu exemplo.

No caso que você tem centenas ou milhares de commits, usando de kostmo resposta de

git rebase -i --root

pode ser impraticável e lento, apenas devido ao grande número de commits que o script rebase tem de processo duas vezes , uma vez para gerar a lista de editor rebase interativo (onde você seleciona quais as medidas a tomar para cada commit), e uma vez para realmente executar a re-aplicação de commits.

Aqui é uma solução de alternativa que irá evitar o custo do tempo de gerar a lista editor rebase interativo por não usar um rebase interativo em primeiro lugar. Desta forma, é semelhante ao do Charles Bailey solução . Você simplesmente criar um órfão ramo a partir do segundo cometer, e depois rebase todos os commits descendentes em cima dela:

git checkout --orphan orphan <second-commit-sha>
git commit -m "Enter a commit message for the new root commit"
git rebase --onto orphan <second-commit-sha> master

Documentação

Em uma questão relacionada, consegui chegar a uma abordagem diferente para a necessidade de esmagamento contra o primeiro commit, que é, assim, para torná-lo o segundo.

Se você estiver interessado: git: como inserir um commit como o primeiro, mudando todos os outros

comando Git para o time: git rebase -i CABEÇA ~ [número de commits]

Vamos dizer que você tem abaixo git commit história:


pegar 5152061 façanha: Adicionado suporte para salvar imagem. (UMA)
escolher 39c5a04 Fix: correções de bugs. (B)
escolher 839c6b3 correção: conflito resolvido. (C)

Agora você quer esmagar A e B AB, execute os passos abaixo:


pegar 5152061 façanha: Adicionado suporte para salvar imagem. (UMA)
é 39c5a04 Fix: correções de bugs. (B)
escolher 839c6b3 correção: conflito resolvido. (C)

Nota: para esmagar cometer podemos usar squash ou s. O resultado final será:
pegar 5152061 façanha: Adicionado suporte para salvar imagem. (AB)
escolher 839c6b3 correção: conflito resolvido. (C)

Você tem que executar um pouco de magia de linha de comando.

git checkout -b a A
git checkout B <files>
git commit --amend
git checkout master
git rebase a

Isso deve deixá-lo com um ramo que tem AB e C como commits.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top