合并 Git 存储库的前两次提交?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/435646/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Combine the first two commits of a Git repository?
提问by Christian
Suppose you have a history containing the three commits A, Band C:
假设您有一个包含三个提交A、B和C的历史记录:
A-B-C
I would like to combine the two commits Aand Bto one commit AB:
我想将两个提交A和B合并到一个提交AB:
AB-C
I tried
我试过
git rebase -i A
which opens up my editor with the following contents:
这会打开我的编辑器,其中包含以下内容:
pick e97a17b B
pick asd314f C
I change this to
我把这个改成
squash e97a17b B
pick asd314f C
Then Git 1.6.0.4 says:
然后 Git 1.6.0.4 说:
Cannot 'squash' without a previous commit
Is there a way or is this just impossible?
有没有办法或者这是不可能的?
采纳答案by kostmo
Use git rebase -i --root
as of Git version 1.7.12.
使用git rebase -i --root
作为的Git版本1.7.12。
In the interactive rebase file, change the second line of commit Bto squashand leave the other lines at pick:
在交互式 rebase 文件中,将 commit B的第二行更改为squash并将其他行保留为pick:
pick f4202da A
squash bea708e B
pick a8c6abc C
This will combine the two commits Aand Bto one commit AB.
这会将两个提交A和B合并为一个提交AB。
Found in this answer.
在这个答案中找到。
回答by David Lichteblau
You tried:
你试过:
git rebase -i A
It is possible to start like that if you continue with edit
rather than squash
:
如果您继续使用edit
而不是这样,则可以这样开始squash
:
edit e97a17b B
pick asd314f C
then run
然后运行
git reset --soft HEAD^
git commit --amend
git rebase --continue
Done.
完毕。
回答by CB Bailey
A
was the initial commit, but now you want B
to be the initial commit. git commits are whole trees, not diffs even if they are normally described and viewed in terms of the diff that they introduce.
A
是最初的提交,但现在你想B
成为最初的提交。git commits 是完整的树,而不是差异,即使它们通常是根据它们引入的差异来描述和查看的。
This recipe works even if there are multiple commits between A and B, and B and C.
即使 A 和 B 以及 B 和 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
回答by Loki
In the case of interactive rebase, you have to do it before A so that the list will be:
在交互式 rebase 的情况下,您必须在 A 之前执行此操作,以便列表为:
pick A
pick B
pick C
to become:
成为:
pick A
squash B
pick C
If A is the initial commit, you have to have a different initial commit before A. Git thinks in differences, it will work on the difference between (A and B) and (B and C). Hence the squash not working in your example.
如果 A 是初始提交,则必须在 A 之前进行不同的初始提交。 Git 考虑差异,它将处理 (A 和 B) 和 (B 和 C) 之间的差异。因此,壁球在您的示例中不起作用。
回答by Loki
In the case that you have hundreds or thousands of commits, using kostmo's answerof
在你已经提交的数百或数千使用情况kostmo的答案的
git rebase -i --root
can be impractical and slow, just due to the large number of commits that the rebase script has to process twice, once to generate the interactive rebase editor list (where you select what action to take for each commit), and once to actually execute the re-application of commits.
可能是不切实际的和缓慢的,只是由于大量提交的是,重订脚本必须处理两次,一次产生互动变基编辑器列表(在其中选择采取什么动作每次提交),而一旦实际执行重新应用提交。
Here is an alternative solutionthat will avoid the time cost of generating the interactive rebase editor list by not using an interactive rebasein the first place. In this way, it's similar to Charles Bailey's solution. You simply create an orphan branchfrom the second commit, and then rebase all the descendant commits on top of it:
这是一个替代解决方案,它可以通过首先不使用交互式 rebase来避免生成交互式 rebase 编辑器列表的时间成本。这样,它类似于Charles Bailey 的解决方案。您只需从第二次提交中创建一个孤立分支,然后将所有后代提交重新建立在它的基础上:
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
Documentation
文档
回答by kch
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?
如果您有兴趣:git:如何将提交作为第一个插入,转移所有其他提交?
回答by Sumit
Git command for squad: git rebase -i HEAD~[number of commits]
小队的 Git 命令:git rebase -i HEAD~[提交次数]
Lets say you have below git commit history:
假设您有以下 git 提交历史记录:
pick 5152061 feat: Added support for saving image. (A)
pick 39c5a04 Fix: bug fixes. (B)
pick 839c6b3 fix: conflict resolved. (C)
选择 5152061 壮举:添加了对保存图像的支持。(A)
pick 39c5a04 Fix: 错误修复。(B)
选择 839c6b3 修复:冲突已解决。(C)
Now you want to squash A and B to AB, perform below steps:
现在要将 A 和 B 压缩为 AB,请执行以下步骤:
pick 5152061 feat: Added support for saving image. (A)
s 39c5a04 Fix: bug fixes. (B)
pick 839c6b3 fix: conflict resolved. (C)
选择 5152061 壮举:添加了对保存图像的支持。(A)
s 39c5a04 修复:错误修复。(B)
选择 839c6b3 修复:冲突已解决。(C)
Note: for squashing commit we can use squash or s.
The end result will be:
pick 5152061 feat: Added support for saving image. (AB)
pick 839c6b3 fix: conflict resolved. (C)
注意:对于压缩提交,我们可以使用 squash 或 s。最终结果将是:
pick 5152061 壮举:添加了对保存图像的支持。(AB)
选择 839c6b3 修复:冲突已解决。(C)
回答by Bombe
You have to perform a bit of command-line magic.
您必须执行一些命令行魔术。
git checkout -b a A
git checkout B <files>
git commit --amend
git checkout master
git rebase a
That should leave you with a branch that has AB and C as commits.
这应该给您留下一个分支,其中包含 AB 和 C 作为提交。