当前位置:  开发笔记 > 编程语言 > 正文

在Git中压缩前两个提交?

如何解决《在Git中压缩前两个提交?》经验,为你挑选了5个好方法。

随着git rebase --interactive 你能够压制任意数量的提交连成一个单一的一个.

除非你想将提交压缩到初始提交中,否则这一切都很棒.这似乎是不可能的.

有没有办法实现它?


中度相关:

在一个相关的问题中,我设法提出了一种不同的方法来解决第一次提交的问题,这也就是说,它是第二次提交.

如果您有兴趣:git:如何插入提交作为第一个,转移所有其他?



1> VonC..:

2012年7月更新(git 1.7.12+)

您现在可以将所有提交重新绑定到root,并选择第二个提交Y与第一个提交压缩X.

git rebase -i --root master

pick sha1 X
squash sha1 Y
pick sha1 Z
git rebase [-i] --root $tip

此命令现在可用于重写从" $tip"到根提交的所有历史记录.

见提交df5df20c1308f936ea542c86df1e9c6974168472在GitHub上从克里斯·韦伯(arachsys).


原始答案(2009年2月)

我相信你会在SO问题" 我如何结合git存储库的前两个提交? "中找到不同的配方.

Charles Bailey在那里提供了最详细的答案,提醒我们提交是一个完整的树(不仅仅是以前状态的差异).
在这里,旧提交("初始提交")和新提交(压缩的结果)将没有共同的祖先.
这意味着你不能" commit --amend"初始提交到新的,然后重新绑定到新的初始提交上一次初始提交的历史(很多冲突)

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

而是(使用A原始的"初始提交",并且B后续提交需要被压缩到初始提交中):

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

    git checkout 
    

    将分支指针重置为初始提交,但保留索引和工作树:

    git reset --soft 
    

    使用'B'中的树修改初始树:

    git commit --amend
    

    暂时标记这个新的初始提交(或者您可以手动记住新的提交sha1):

    git tag tmp
    

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

    git checkout master
    

    重新播放B之后的所有提交到新的初始提交:

    git rebase --onto tmp 
    

    删除临时标记:

    git tag -d tmp
    

这样," rebase --onto"在合并期间不会引入冲突,因为它将最后一次commit()之后的历史记录B重新压缩到初始的(那是A)到tmp(表示压缩的新初始提交):琐碎的快进仅合并.

这适用于" A-B",但也适用于" " A-...-...-...-B(任何数量的提交都可以通过这种方式压缩到最初的提交)



2> 小智..:

我重写了VonC的脚本,自动完成所有操作,而不是向我询问任何事情.你给它两个提交SHA1,它会将它们之间的所有内容压缩成一个名为"压扁历史记录"的提交:

#!/bin/sh
# Go back to the last commit that we want
# to form the initial commit (detach HEAD)
git checkout $2

# reset the branch pointer to the initial commit (= $1),
# but leaving the index and working tree intact.
git reset --soft $1

# amend the initial tree using the tree from $2
git commit --amend -m "squashed history"

# remember the new commit sha1
TARGET=`git rev-list HEAD --max-count=1`

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

# Replay all the commits after $2 onto the new initial commit
git rebase --onto $TARGET $2



3> Ryan C. Thom..:

为了它的价值,我通过始终创建一个"no-op"第一次提交来避免这个问题,其中存储库中唯一的东西是空的.gitignore:

https://github.com/DarwinAwardWinner/git-custom-commands/blob/master/bin/git-myinit

这样,从来没有任何理由搞乱第一次提交.


git应该自动执行此操作,如果它不那么疯狂.有一种很好的方法可以将这样的初始提交INSERT到现有的repo ... http://stackoverflow.com/questions/645450/git-how-to-insert-a-commit-as-the-first-shifting-all -the-人/ 14729121

4> 小智..:

如果您只想将所有提交压缩为单个初始提交,只需重置存储库并修改第一个提交:

git reset hash-of-first-commit
git add -A
git commit --amend

Git重置会使工作树保持原样,所以一切都还在那里.所以只需使用git add命令添加文件,并使用这些更改修改第一次提交.与rebase -i相比,你将失去合并git注释的能力.



5> Antony Hatch..:

这会将第二次提交压缩到第一次提交:

A-B-C-... -> AB-C-...

git filter-branch --commit-filter '
    if [ "$GIT_COMMIT" =  ];
    then
        skip_commit "$@";
    else
        git commit-tree "$@";
    fi
' HEAD

AB的提交消息将从B中获取(尽管我更喜欢A).

与Uwe Kleine-König的答案具有相同的效果,但也适用于非初始A.

推荐阅读
mylvfamily
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有