将多个 Git 提交合并成一个,快进。

huangapple go评论58阅读模式
英文:

Git Squash several commits into one, fast forward

问题

以下是翻译好的内容:

这里有一个示例的 git 日志:

commit_hash_0 - 作者:我
commit_hash_1 - 作者:我
commit_hash_2 - 作者:我
...
commit_hash_n-1 - 作者:我
commit_hash_n - 作者:其他人

我试图将 commit_hash_n 之后(不包括 commit_hash_n)的所有提交合并为一个单独的提交。我发现我可以使用 git rebase -i commit_hash_n 来实现这个目标。然而,我遇到了合并错误。我不明白为什么会发生这种情况。我只是想保留我的项目在我最近提交时的状态。所以这不应该导致任何合并问题,对吧?发生了什么?

git 日志应该是这样的:
commit_hash_new - 作者:我
commit_hash_n - 作者:其他人
英文:

Here's an example git log:

commit_hash_0 - Author: me
commit_hash_1 - Author: me
commit_hash_2 - Author: me
...
commit_hash_n-1 - Author: me
commit_hash_n - Author: some other guy

I am attempting to collapse all commits after (excluding) commit_hash_n into a singular commit. I found out that I could use git rebase -i commit_hash_n to do this. However, I am running into merge errors. I don't understand why this is happening. I simply want to keep the state of my project as it is when I made my most recent commit. So this shouldn't cause any merge issues right? What's going on?

The git log should be:
commit_hash_new - Author: me
commit_hash_n - Author: some other guy

答案1

得分: 3

一种在没有冲突可能的情况下完成这个任务的简单方法是通过重置(软重置或混合重置)到第n个提交,然后进行提交。例如:

git reset --soft <commit_hash_n> # 使用 --soft 保留所有已暂存的更改
git commit -m "进行一些酷炫的工作" # 这是合并提交的消息

至于为什么会出现冲突,如果没有更多信息,我们不能确定,但与交互式变基发生冲突的最常见原因包括:

  1. 您更改了某些提交的顺序,或者删除了某些提交,使得 Git 无法在新指定的顺序中干净地挑选每个提交。
  2. 您的分支不是线性的,并且在变基起始提交后包含了合并提交,这些提交本身解决了冲突。默认情况下,合并提交在变基时不会包含在内,即使您使用 --rebase-merges 选项来包括它们,您仍然需要重新解决最初由这些合并提交解决的冲突。
英文:

One easy way to accomplish this without the possibility of conflicts, is by resetting (soft or mixed) to the nth commit, and then committing. For example:

git reset --soft &lt;commit_hash_n&gt; # using --soft leaves all changes staged
git commit -m &quot;Do cool stuff&quot; # this is the message for the squashed commit

As for why you had conflicts, we can't say for sure without more information, but the most common reasons for conflicts with an interactive rebase are:

  1. You changed the order of some commits, or you dropped some commits, such that Git cannot cleanly cherry-pick each commit in the newly specified order.
  2. Your branch is not linear, and contains merge commits after the rebase starting commit, which themselves resolved conflicts. By default merge commits are not included with a rebase, and even if you use the option --rebase-merges to include them, you'll need to re-resolve the conflicts that were originally resolved by those merge conflicts.

答案2

得分: 3

@TTT的方法非常好(已点赞)。还有一种方法可以做到,对于那些好奇的人,它可以避免让你的头绕得晕晕的重置(顺便说一句,重置是我的最爱之一,我并不是说你应该避免使用它,只是可能会有点棘手)。

git restore --staged --worktree --source <commit_hash_0> -- .
git commit -m "一切一次性搞定"```

此时,您可以将喜欢的分支移动到当前提交。

<details>
<summary>英文:</summary>

@TTT&#39;s approach is very good (upvoted). There is another way to do it, for those curious, which avoids having to wrap around your head around a reset (which is one of my favorite tools, by the way, I do not mean you should avoid using it, it&#39;s just that it might be tricky to _get it_).

    git checkout &lt;commit_hash_n&gt;
    git restore --staged --worktree --source &lt;commit_hash_0&gt; -- .
    git commit -m &quot;Everything in a single shot&quot;

At this point you can move the branch you like to the current commit.

</details>



huangapple
  • 本文由 发表于 2023年6月6日 11:03:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/76411193.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定