使用它们的哈希合并两个提交之间的所有提交。

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

Git combine all commits between two commits using their hashes

问题

在给定的 git 分支上,

-- c1 ---- c2 ------ HEAD

我想将 c1c2 以及它们之间的所有内容合并成一个提交。

要求:

  • 我知道 c1c2 的哈希值,但不知道它们相对于 HEAD 的位置。
  • 我想以编程方式执行此操作(在脚本中调用),因此无法使用交互模式。

我知道这个问题已经被多次提出,但我找不到任何现有的答案能够满足这些要求。

英文:

Given this git branch,

-- c1 ---- c2 ------ HEAD

I want to combine c1 and c2 and everything in between into one commit.

Requirements:

  • I know c1 and c2 hashes, but not their relative positions to HEAD.
  • I want to do this programmatically (call it in a script), so I cannot use interactive mode.

I know this question has been asked several times, but I cannot find any existing answer that satisfies those requirements.

答案1

得分: 2

这将完成它(将您所在的分支称为 originalBranch):

git switch --det c2
git switch -c temp
git reset --soft c1
git commit -msquash  
git rebase --onto temp c2 originalBranch
git branch -D temp

思路如下:

  • 我们回到了 c2,在那里创建了一个名为 temp 的分支,以便以后可以找到它。
  • 然后,我们从 c2 一直压缩到 c1(包括 c1)——这是软重置后紧接着的提交;这是一种类型 1 的后悔。现在,名称 temp 指向这个新的单一压缩提交。
  • 最后,我们返回到原始的 HEAD(我称之为 originalBranch)并将所有从旧的 c2 开始的提交移动到新的单一压缩提交上,这个提交(如我之前所说)由名称 temp 指向。
  • 我们的工作现在已经完成,但是我们不再需要分支名称 temp,所以我们将其删除。

所以我们现在从这个状态:

A -- B -- C1 -- ? -- ? -- C2 -- D -- E -- F <- originalBranch

到这个状态:

A -- B -- C1 -- squash -- D' -- E' -- F' <- originalBranch
            \
             -- ? -- ? -- C2 -- D -- E -- F

从我的图表中可以看出,旧的提交仍然存在,但由于没有名称再指向它们,它们将在下一次垃圾回收期间全部清除。

英文:

This would do it (call the branch you are on originalBranch):

git switch --det c2
git switch -c temp
git reset --soft c1
git commit -msquash  
git rebase --onto temp c2 originalBranch
git branch -D temp

The idea is this:

  • We get ourselves back at c2 and plant a branch name temp there, so that we can find it again.
  • We then squash from c2 all the way back to c1 inclusive — that's the soft reset followed by a commit; this is a type 1 regret. The name temp now points to this new single squash commit.
  • Finally, we return to whatever was the original HEAD (which I have named originalBranch) and move all the commits starting at (but not including) the old c2 onto the new single squash commit, which (as I have already said) is pointed to by the name temp.
  • Our work is now done, but we no longer need the branch name temp for anything, so we delete it.

So we have now gone from this:

A -- B -- C1 -- ? -- ? -- C2 -- D -- E -- F &lt;- originalBranch

To this:

A -- B -- C1 -- squash -- D&#39; -- E&#39; -- F&#39; &lt;- originalBranch
            \
             -- ? -- ? -- C2 -- D -- E -- F

The old commits, as you can see from my diagram, still exist, but they will all be mopped up during the next garbage collection because no name points to them any longer.

答案2

得分: 0

我不认为有任何可以直接完成这个任务的工具,但可以编写脚本来实现。

伪代码:

  • 检出 c1^
  • 进行 c2 的压缩合并并提交结果
  • c2..HEAD 樱桃挑选到结果上

可能的问题:

  • 如果在 c1^HEAD 之间存在任何合并提交,挑选 c2..HEAD 将会导致混乱。
英文:

I don't think there is any tool that does this out of the box, but it can be scripted.

Pseudo code:

  • checkout c1^
  • do a squash-merge of c2 and commit the results
  • cherry pick c2..HEAD onto the results

Potential problem:

  • if there were any merge commits between c1^ and HEAD, cherry picking c2..HEAD will create a mess.

huangapple
  • 本文由 发表于 2023年6月2日 09:13:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/76386588.html
匿名

发表评论

匿名网友

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

确定