确定两个给定分支之间的最新合并

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

Determine latest merge between two given branches

问题

我需要以一种无依据的方式识别两个分支之间的差异。这些分支经常分歧,只有在我合并它们时才需要它们保持相同(每个冲刺一次)。即使在合并后,如果有人对目标分支进行热修复更改,并且不小心没有带来其他更改,它们似乎仍然会漂移。无论如何,git diff 显示这些分支不同,git merge 表示没有要合并的内容。

我可以使用 git diff 来识别存在哪些更改,我有一个使用 git merge --allow-unrelated-histories 执行无依据合并的脚本。现在我正在努力回退到最后一次合并,以便仅比较合并和父分支。

考虑这个 git 图:

...-A-B---C---D---E---F---G---H
       \                      ↑
...     \                     main
   \     \          
    I-J---K---L---M---N---O
           \   \ /   /    ↑
            \   f   /     release
             \     /
              --d--
                 
我知道 `main` 和 `release` 分支。鉴于 `release` 是 `O`,我想确定 `K` 是它从 `main` 合并的最后一次合并,并且提交 `B` 是其父提交。**如何遍历 `O` 的历史并确定 `K` 是最近的合并,`B` 是其父提交?**

## 确定合并

`git rev-list --min-parents=2 <O>` 将列出所有父提交,并引导我到 `K`,尽管在那之前我需要排除 `N` 和 `M`。

## 确定父提交

*我不知道如何做*(鉴于 `K`,确定 `B` 或 `B` 和 `J` 中的哪一个)。

## 确定父提交的后代

*我不知道如何做*(鉴于 `B`,确定 `H` 是一个后代;鉴于 `J`,确定 `H` 不是一个后代)。

## 遍历过程

如果我使用 `git rev-list` 和类似的命令,我将需要循环遍历返回的每个提交哈希(以测试父提交和父提交的后代)。这不是世界末日,但如果 Git 能替我完成这项工作,那将更不容易出错。

## 确定差异

`git diff --name-only <B> <K>` 将显示 `B` 和 `K` 之间的文件差异。

## 执行无依据合并

呃,这是一个多步骤的脚本,涉及到 `checkout --orphan` 和 `merge --allow-unrelated-histories`。我将略去这部分,但我有一个解决方案。
英文:

I need to identify differences between two branches in a baseless manner. The branches diverge often and only need to be the same when I merge them (once a sprint). They appear to drift even after merging when someone makes a hotfix change to the target branch and it inadvertently doesn't bring some other changes. Either way, git diff shows the branches differ and git merge says there is nothing to merge.

I can use git diff to identify what changes exist, and I have a script that performs a baseless merge using git merge --allow-unrelated-histories. What I'm working on now is backing up to the last merge so I can compare just the merge to the parent.

Consider this git graph:

...-A-B---C---D---E---F---G---H
       \                      ↑
...     \                     main
   \     \          
    I-J---K---L---M---N---O
           \   \ /   /    ↑
            \   f   /     release
             \     /
              --d--

I know the main and release branches. Given release is O I'd like to determine that K is its last merge from main and that commit B was that parent. How do I travese Os history and determine K was the most recent merge and B is its parent?

Determining merges

git rev-list --min-parents=2 &lt;O&gt; would list out all parents and lead me to K though I would need to rule out N and M before that.

Determining parents

I do not know how to do this (given K, determine either B or B & J).

Determine parent's descendents

I do not know how to do this (given B, determine that H is a descendent; and given J, determine that H is NOT a descendent)

Traverse process

If I use git rev-list and similar I'll need to loop over each commit hash returned (to test for parents and parents's descendents). Not the end of the world but if git could do the work for me that would be less error prone.

Determine differences

git diff --name-only &lt;B&gt; &lt;K&gt; would show me file differences between B and K

Perform baseless merge

Meh. A multi-step script involving checkout --orphan and merge --allow-unrelated-histories. I'll leave that out but I have a solution for that.

答案1

得分: 1

当你说“同步”时,你的意思是“当我合并B时,让分支A的内容看起来像B一样”吗?如果是这样,你可以这样做:

git checkout A
git merge --no-commit B
# 我不想处理细节,请让它看起来像B一样:
git restore --staged --worktree --source=B -- .
GIT_EDITOR=true git merge --continue

无论在合并之前A和B的内容是什么样子,你可以确保每次合并完成后,git diff B都将为空。

你甚至可以使用git commit-tree来实现,但这有点更加巧妙。

英文:

When you say synchronize, you mean make branch A look in contents just like B when I merge B? If that is the case, you can do this:

git checkout A
git merge --no-commit B
# I don&#39;t want to deal with the details, make it look like B, please:
git restore --staged --worktree --source=B -- .
GIT_EDITOR=true git merge --continue

You can be sure that regardless of what A and B looked like before the merge, git diff B will be empty every single time when that merge is finished.

You could even pull it off with git commit-tree but that's a little more hackish.

huangapple
  • 本文由 发表于 2023年3月31日 22:39:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/75899804.html
匿名

发表评论

匿名网友

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

确定