如何实现不允许的`git --no-ff --ff-only`

时间:2013-03-26 07:49:05

标签: git merge rebase

作为我们重量级工作流程的一部分,我希望在主分支上使用合并。特别是我想只在主题分支被重新定位到最近的主提交时合并,从而使任何合并成为快进合并。我可以通过使用:

实现这一目标

git merge --ff-only

此外,我想记录主题分支与空提交的集成,这就是为什么我想使用--no-ff来强制这种行为:

git merge --no-ff

然而,我真正想要的是两者的结合:只有当它微不足道时才合并但是让我记录它。 Git认为

fatal: You cannot combine --no-ff with --ff-only.

对某些人来说,这似乎是不言而喻的。

git merge --edit --no-ff topicbranch

无法实现我想要的行为。那么,如果有问题的主题分支被重新定位到最新的主提交,我如何与--no-ff选项合并?


更新:好像Charles Bailey的回答似乎可以解决问题。如果你想把它变成一个git别名你可以在这里发出:

git config --global alias.integrate '!test "$(git merge-base HEAD "$1")" = "$(git rev-parse HEAD)" && git merge --no-ff --edit $1 || echo >&2 "Not up-to-date; refusing to merge, rebase first!"'

有点满口但是有效。请注意使用选项--edit编辑提交消息的强制。

3 个答案:

答案 0 :(得分:10)

您不希望--ff-only,因为您确实希望进行--ff-only禁止的合并提交。

在运行merge命令之前,可以将所需的检查作为单独的检查。你可以将它打包成一个简单的shell函数。

E.g。

merge_if_ahead () {
  if test "$(git merge-base HEAD "$1")" = "$(git rev-parse HEAD)"; then
      git merge --no-ff "$1"
  else
      echo >&2 "Not up to date; refusing to merge"
      return 1
  fi
}

答案 1 :(得分:2)

我创建了一个适用于我的简单测试的别名

git config --global alias.ffmerge '!sh -c "git merge --ff-only $1 && git reset --hard HEAD@{1} && git merge --no-ff $1" -'

它由3个命令组成,一个接一个,一旦第一个失败就会失败。解释每个:

git merge --ff-only $1

如果合并无法继续作为快进合并,则会失败。 ($ 1是作为参数传入的分支名称)

git reset --hard HEAD@{1}

如果第一个命令成功,则意味着我们可以进行快进合并,但是当我们想要进行合并提交时,我们将在我们(成功)合并之前返回到HEAD状态。 HEAD @ {1}是一个reflog指针。

git merge --no-ff $1

现在我们将使用合并提交进行真正的合并,即使合并可以作为快进进行。

git ffmerge的简单调用将为我们完成整个事情,唯一可能失败的步骤是第一步,这将使我们像以前一样处于未更改的工作副本中。

git reset --hard一样,工作副本应该是干净的。

答案 2 :(得分:1)

git config alias.mff '!mff() { git merge --ff-only "$1" && git reset --hard HEAD@{1} && git merge --no-ff "$1"; }; mff'

从此开始

git mff other-branch