如何在 Git 合并中覆盖合并基准?

3
我的代码库中的一些cherry-pick操作被记录为合并操作,这会影响git选择合并基准点。是否可以指定合并基准点?如果可以,怎样指定?
例如:f分支是从A提交的master分支创建的。C被cherry-pick到f分支,但被误导性地作为一个带有K和C父节点的合并提交。
A-B-C   master
\   \  
 K---C'-L   f

当将f合并到主分支时,Git会找到C作为最佳的共同祖先,并将其用作基础。由于B包含在基础中,但在f中缺失,所以它将被合并撤销。使用A作为基础将给出正确的合并结果。
编辑:这个答案排除了下面提到的B计划。因此,希望有人能回答:如何在Git合并中指定合并基础?
编辑,B计划:该存储库通过使用TFS-Git从两个具有挑选工作流程的TFS分支获取而变得如此。一个变更集的“合并选定范围”显示为完全合并。另一种解决方案是以某种方式配置git-tfs,以不创建合并提交。(停止所有挑选不是一个选项。)

嗨,@Grastveit,我不确定我是否理解了您的问题。如果您精选了 C 而不是 B,那么是不是意味着从进一步的工作中可以得出 B?如果不是,那么在您的示例中,B 是否也应该被选择或者仅仅继续在 C 上进行? - Florian Neumann
@florianb:团队中的其他人已经执行了“合并所选范围”,只将C合并到f分支并进行了检入。然后我使用git-tfs获取了最新版本,他们的检入在我的git存储库中显示为合并。在git中,合并意味着合并所有更改,因此假定C'包括来自B和C的更改。清楚吗? - Grastveit
3个回答

7
如何在Git合并中指定合并基?使用嫁接(grafts):
echo $(git rev-parse tip1 mybase) >>.git/info/grafts
echo $(git rev-parse tip2 mybase) >>.git/info/grafts

git checkout tip1
git merge tip2

rm .git/info/grafts

编辑来自评论:使用带注释的标签,在您的引用末尾指定^{},例如tip1^{}等,以便rev-parse追踪并打印提交的ID,而不仅仅是标签。


就此而言,echo $(foo) >> filefoo >> file 是相同的。 - amalloy
@amalloy 我认为你可能忘记了 shell 的单词分割……echo 命令将两行 rev-parse 输出转换为一行 echo 输出。 - jthill
@amalloy,错别字已经修正,谢谢。这确实是关于单词拆分的,shell将每个单词作为单独的参数传递给echo,并根据IFS变量指定的方式标识单词边界,通常是空格/制表符/换行符。尝试一下(IFS=: ; printf '%s\n' $PATH ) - jthill
啊哈哈哈,太有劲了!我之前一直在用普通的cmd,但现在换成了git bash。另外我犯了一个小错误,指定了基础标签。合并失败了,因为显然rev-parse返回的是标签对象的SHA,而不是提交的SHA。 - Grastveit

1
我认为问题在于,“樱桃拣选”(Git中的一种操作方式)似乎不是Team Foundation Server版本控制的功能或计划工作流程
git的“cherry-pick”命令会应用“给定提交引入的更改,位于[...]分支的顶部,并创建具有这些更改的新提交。”(http://git-scm.com/docs/git-cherry-pick
TFSVSC没有“cherry-picking”命令,但有可能进行“合并所选范围”或“部分合并”,将指定(连续的)变更集合并到不同分支上的新变更集中(http://blogs.msdn.com/b/dstfs/archive/2009/05/04/partial-merges-in-tfs-a-guide.aspx)。

在编写本文时,git-tfs 似乎已经达到了其极限 - 无效的选择性合并而不是樱桃拣选。由于 Git 基于快照(因此需要依赖树),而 TFS 基于变更集,因此在 git-merge 产生错误结果的情况下,目前似乎没有一种可靠的方法将部分合并转换为相应的 git-cherry-picks。


我认为你需要等待git-tfs的问题得到解决,或者在git仓库中进行cherry-picking。另一种方法是检出tfs仓库并将其提交到git仓库,但这会在传输过程中丢失您的提交历史记录。

谢谢你的好答案,这绝对排除了“计划B”作为解决方案的可能性。这样只剩下指定合并基准点来使它起作用了。我会稍等一下,看看情况... - Grastveit

1
作为对jthill答案的补充。
我曾经遇到类似的问题,由于/info/grafts已经被弃用,这里是我如何通过git replace解决了相同的问题:
git replace --graft tip1 mybase
git replace --graft tip2 mybase

git checkout tip1
git merge tip2

git replace -d tip2
git replace -d tip1~1

非常流畅,谢谢! - Torben Nehmer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接