压缩Git中的前两个提交? [英] Squash the first two commits in Git?

查看:144
本文介绍了压缩Git中的前两个提交?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 git rebase --interactive< commit> ,您可以将任意数量的提交压缩为一个。



除非你想压缩到最初的提交,否则这很好。这似乎是不可能的。



有没有办法达到它?






中等相关:



在一个相关的问题中,我设法提出了一种不同的方法来抵制第一次提交的压缩需求,好吧,让它成为第二个。



如果您有兴趣:

$ b的插入提交作为首先转移所有其他人$ b

解决方案

2012年7月更新( git 1.7.12+

您现在可以重新提交所有提交到根目录,然后选择第二次提交 Y 被第一个 X 压扁。

  git rebase -i --root master 

pick sha1 X
squash sha1 Y
pick sh a1 Z




  git rebase [ -i] --root $ tip 

现在可以使用此命令来重写所有从 $ tip 直到根提交。

请参阅在GitHub上提交df5df20c1308f936ea542c86df1e9c6974168472 Chris Webb( arachsys






原始答案(2009年2月)

我相信你会在SO问题中找到不同的食谱 如何结合git仓库的前两个提交?



Charles Bailey 在那里提供最多的详细的答案,提醒我们一个提交是一个完整的树(不只是从以前的状态差异)。

在这里旧的提交(初始提交)和新的提交压扁的结果)将没有共同的祖先。

这意味着你不能 commit --amend 初始提交到新的,并且然后重新绑定到新的初始提交上次初始提交的历史记录(大量冲突)

(最后一句不再适用于 git rebase -i --root



相反(使用 A 原始的初始提交和 B 后续提交需要压缩到最初的提交):


  1. 返回到我们想要形成初始提交(detach HEAD)的最后一个提交:

      git checkout< sha1_for_B> 


  2. 将分支指针重置为初始提交,但保持索引和工作树不变:

      git reset --soft< sha1_for_A> 


  3. 使用'B'树修改初始树:

      git commit --amend 


  4. <

      git tag tmp 


  5. 返回原始分支(假设此示例为master):

      git checkout master 


  6. 将所有提交后的B提交到新的初始提交中:

      git rebase --onto tmp< sha1_for_B> ; 


  7. 移除临时标记:

      git tag -d tmp 


通过这种方式, rebase --onto 不会在合并过程中引入冲突,因为它会在 >最后一个提交( B )被压缩到最初的提交(它是 A )到 tmp (表示压扁的新初始提交):仅平凡的快进合并。

这适用于 AB ,而且也是 A -...- ... -B- (任意数量的提交可以用这种方式压缩到最初的提交)

With git rebase --interactive <commit> you can squash any number of commits together into a single one.

That's all great unless you want to squash commits into the initial commit. That seems impossible to do.

Are there any ways to achieve it?


Moderately related:

In a related question, I managed to come up with a different approach to the need of squashing against the first commit, which is, well, to make it the second one.

If you're interested: git: how to insert a commit as the first, shifting all the others?

解决方案

Update July 2012 (git 1.7.12+)

You now can rebase all commits up to root, and select the second commit Y to be squashed with the first X.

git rebase -i --root master

pick sha1 X
squash sha1 Y
pick sha1 Z

git rebase [-i] --root $tip

This command can now be used to rewrite all the history leading from "$tip" down to the root commit.

See commit df5df20c1308f936ea542c86df1e9c6974168472 on GitHub from Chris Webb (arachsys).


Original answer (February 2009)

I believe you will find different recipes for that in the SO question "How do I combine the first two commits of a git repository?"

Charles Bailey provided there the most detailed answer, reminding us that a commit is a full tree (not just diffs from a previous states).
And here the old commit (the "initial commit") and the new commit (result of the squashing) will have no common ancestor.
That mean you can not "commit --amend" the initial commit into new one, and then rebase onto the new initial commit the history of the previous initial commit (lots of conflicts)

(That last sentence is no longer true with git rebase -i --root <aBranch>)

Rather (with A the original "initial commit", and B a subsequent commit needed to be squashed into the initial one):

  1. Go back to the last commit that we want to form the initial commit (detach HEAD):

    git checkout <sha1_for_B>
    

  2. Reset the branch pointer to the initial commit, but leaving the index and working tree intact:

    git reset --soft <sha1_for_A>
    

  3. Amend the initial tree using the tree from 'B':

    git commit --amend
    

  4. Temporarily tag this new initial commit (or you could remember the new commit sha1 manually):

    git tag tmp
    

  5. Go back to the original branch (assume master for this example):

    git checkout master
    

  6. Replay all the commits after B onto the new initial commit:

    git rebase --onto tmp <sha1_for_B>
    

  7. Remove the temporary tag:

    git tag -d tmp
    

That way, the "rebase --onto" does not introduce conflicts during the merge, since it rebases history made after the last commit (B) to be squashed into the initial one (which was A) to tmp (representing the squashed new initial commit): trivial fast-forward merges only.

That works for "A-B", but also "A-...-...-...-B" (any number of commits can be squashed into the initial one this way)

这篇关于压缩Git中的前两个提交?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆