合并 Git 存储库的前两次提交?

发布于 2024-07-11 20:00:43 字数 484 浏览 7 评论 0原文

假设您有包含三个提交 A、BC 的历史记录:

A-B-C

我想合并两个提交 AB 到一个提交 AB

AB-C

我尝试

git rebase -i A

用以下内容打开我的编辑器:

pick e97a17b B
pick asd314f C

我将其更改为

squash e97a17b B
pick asd314f C

然后 Git 1.6.0.4 说:

Cannot 'squash' without a previous commit

有办法还是这根本不可能?

Suppose you have a history containing the three commits A, B and C:

A-B-C

I would like to combine the two commits A and B to one commit 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:

Cannot 'squash' without a previous commit

Is there a way or is this just impossible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

孤蝉 2024-07-18 20:00:43

使用 git rebase -i --root
从 Git 版本 1.7.12 开始。

在交互式变基文件中,将提交的第二行 B 更改为 squash 并将其他行保留在 pick 处:

pick f4202da A
squash bea708e B
pick a8c6abc C

这将合并两个提交AB 到一个提交 AB

可以在这个答案中找到。

Use git rebase -i --root
as of Git version 1.7.12.

In the interactive rebase file, change the second line of commit B to squash and leave the other lines at pick:

pick f4202da A
squash bea708e B
pick a8c6abc C

This will combine the two commits A and B to one commit AB.

Found in this answer.

嘿咻 2024-07-18 20:00:43

您尝试过:

git rebase -i A

如果您继续使用 edit 而不是 squash,则可以这样开始:

edit e97a17b B
pick asd314f C

然后运行

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

​​Done。

You tried:

git rebase -i A

It is possible to start like that if you continue with edit rather than squash:

edit e97a17b B
pick asd314f C

then run

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

Done.

╰ゝ天使的微笑 2024-07-18 20:00:43

A 是初始提交,但现在您希望 B 成为初始提交。 git 提交是整个树,而不是差异,即使它们通常是根据它们引入的差异来描述和查看的。

即使 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

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.

This recipe works even if there are multiple commits between A and B, and B and 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
梦纸 2024-07-18 20:00:43

如果您有数百或数千个提交,则使用 kostmo 的答案 可能

git rebase -i --root

不切实际且缓慢,只是因为变基脚本必须处理大量提交两次,一次用于生成交互式变基编辑器列表(您可以在其中选择每次提交要执行的操作),一次用于实际执行重新应用程序的提交。

这是一个替代解决方案,它可以通过首先不使用交互式变基来避免生成交互式变基编辑器列表的时间成本。 这样一来,它就类似于 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

文档

In the case that you have hundreds or thousands of commits, using kostmo's answer of

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 solution that will avoid the time cost of generating the interactive rebase editor list by not using an interactive rebase in the first place. In this way, it's similar to Charles Bailey's solution. You simply create an orphan branch from the second commit, and then rebase all the descendant commits on top of it:

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

滥情空心 2024-07-18 20:00:43

在交互式 rebase 的情况下,你必须在 A 之前执行此操作,这样列表将是:

pick A
pick B
pick C

变为:

pick A
squash B
pick C

如果 A 是初始提交,则在 A 之前必须有一个不同的初始提交。Git 认为存在差异,它会起作用关于(A和B)和(B和C)之间的差异。 因此,南瓜在您的示例中不起作用。

In the case of interactive rebase, you have to do it before A so that the list will be:

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.

一袭水袖舞倾城 2024-07-18 20:00:43

在一个相关的问题中,我设法想出了一种不同的方法来满足压缩第一个提交的需要,也就是说,使它成为第二个提交。

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

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?

明天过后 2024-07-18 20:00:43

小队的 Git 命令:
git rebase -i HEAD~[提交次数]

假设您有以下 git 提交历史记录:

pick 5152061 feat:添加了对保存图像的支持。 (A)

pick 39c5a04 修复:错误修复。 (二)

选择 839c6b3 修复:冲突已解决。 (C)

现在您想将 A 和 B 压缩为 AB,请执行以下步骤:

pick 5152061 feat:添加了对保存图像的支持。 (A)

s 39c5a04 修复:错误修复。 (二)

选择 839c6b3 修复:冲突已解决。 (C)

注意:为了压缩提交,我们可以使用squash 或s。
最终结果将是:

pick 5152061 feat:添加了对保存图像的支持。 (AB)

选择 839c6b3 修复:冲突已解决。 (C)

Git command for squad:
git rebase -i HEAD~[number of commits]

Lets say you have below git commit history:

pick 5152061 feat: Added support for saving image. (A)

pick 39c5a04 Fix: bug fixes. (B)

pick 839c6b3 fix: conflict resolved. (C)

Now you want to squash A and B to AB, perform below steps:

pick 5152061 feat: Added support for saving image. (A)

s 39c5a04 Fix: bug fixes. (B)

pick 839c6b3 fix: conflict resolved. (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)

薄荷梦 2024-07-18 20:00:43

您必须执行一些命令行魔法。

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

这应该会留下一个包含 AB 和 C 作为提交的分支。

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.

眼眸里的快感 2024-07-18 20:00:43

我还想知道如果结构是这样的

X-Y------Z
 \-A-B-C/

并且我希望最终的结构是这样的话,

X-Y-----Z
 \-AB-C/

在这种情况下我如何组合A和B?

I'm also wondering what if the structure is like

X-Y------Z
 \-A-B-C/

and I want the final structure to be

X-Y-----Z
 \-AB-C/

In this case how do I combine A and B?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文