git-合并时跳过特定的提交


200

我已经使用Git大约一年了,认为它很棒,但是我刚刚开始开发该项目的第二个版本,并为此创建了一个新分支。我正在努力处理未来的最佳方法。

我有两个分支,分别说master10(对于v1)和master20(对于v2)。我一直在分支master10的v1中进行错误修复,并开发了master20的新东西。每当我进行错误修复时,我都会通过检出master20并将其合并到v2中git merge master10。到目前为止,一切都很好。

但是,现在我在v1中做了我不希望在v2中进行的更改,但是我想继续合并其他错误修复程序。我如何告诉Git跳过那个特定的提交(或一系列提交),但是在未来,我仍然想合并其他错误修复。

我以为git rebase可能是我所需要的,但是读了文档之后,我的脑袋几乎爆炸了。

我认为我想要的是类似“ git sync”的命令,该命令告诉git现在两个分支处于同步状态,将来仅合并从此同步点开始的提交。

任何帮助表示赞赏。

Answers:


289

例如,如果您想将分支“ maint”上的大多数提交但不是全部提交合并到“ master”,则可以这样做。它需要做一些工作-如上所述,通常的用例是合并分支中的所有内容-但有时会发生您更改了不应集成回发行版的情况(也许代码是已经被主人取代了),那么您如何表示呢?开始...

因此,我们假设maint应用了5个更改,并且其中一个(maint〜3)不会合并回master,尽管所有其他更改都应该合并。您分三个阶段进行操作:实际上合并之前的所有内容,告诉git将maint〜3标记为已合并(即使未合并),然后合并其余部分。魔术是:

bash <master>$ git merge maint~4
bash <master>$ git merge -s ours maint~3
bash <master>$ git merge maint

麻烦的维护提交到master 之前,第一个命令会合并所有内容。默认的合并日志消息将说明您正在合并“分支'maint'(早期)”。

第二条命令合并了麻烦的maint〜3提交,但是“ -s ours”选项告诉git使用特殊的“合并策略”,实际上,它只是通过保留要合并的树并忽略提交来工作。 ),您正在完全合并。但是它仍然使用HEAD和maint〜3作为父级进行新的合并提交,因此修订图现在显示maint〜3已合并。因此,实际上,您可能也想使用-m选项进行'git merge'来解释maint〜3提交实际上被忽略了!

最后一个命令只是将其余的maint(maint〜2..maint)合并到master中,这样您就可以再次同步了。


5
我认为,如果您需要推迟合并该提交,则别无选择,只能跳过它(合并-s我们的),然后再使用cherry-pick命令应用它。一旦可以从master获得提交,就不能再次合并-避免将同一更改两次合并是主要的git目标之一。
araqnid

3
关于您的分支机构示例:我怀疑一旦合并了分支机构,您的处境与我发布第二步后的情况完全相同。创建其他分支对提交关系没有影响。
araqnid

5
只是出于兴趣,如果您只想忽略一个更改,为什么不只做一个合并,然后还原一个更改集,而不是执行三个合并呢?这将导致更少的变更集提交到存储库,以及更明确的历史记录。
Mark Booth

3
显式命名提交通常更容易。因此,您只需要查看待合并分支的git日志,并注意不应该合并的提交的哈希值和之前的哈希值-而不是计算提交次数……
zwirbeltier

14
@MarkBooth:您要跳过的提交可能与您要合并的分支存在巨大冲突。跳过它而不是解决冲突,然后还原更改并再次解决冲突,就更容易跳过它
SztupY

39

恕我直言,最合乎逻辑的做法是将所有内容合并,然后使用git revert(commit_you_dont_want)删除它

例:

git merge master
git revert 12345678

如果您有多个“忽略”提交,或想编辑还原消息:

git merge master
git revert -n 123456
git revert -n abcdef
git commit -m "... Except commits 123456 and abcdef"

那么您的历史记录可能如下所示:

| ... Except 123456 and abcdef
|\ Merge branch 'master' into 'your_branch'

如果您仅涉及这些“忽略”提交的冲突,则可以使用:

git merge master -X ours

因此,您的版本将比其他版本持久。即使没有错误消息,您仍然可以“还原”那些不需要的提交,因为它们可能具有不冲突的其他更改,并且您仍然不希望它们。

如果您的冲突不仅仅涉及“忽略”提交,则应手动解决它们,并且在还原期间可能必须再次解决它们。


2
如果您以后想将这些还原的提交合并到分支中,则Git仍然会忽略它们吗?
Anriëtte迈伯勒

@AnriëtteMyburgh您可以还原还原提交,以便以后将它们合并到一起-使用“合并-s我们的”策略实际上是不容易做到的。
莉莉·钟

谢谢,这正是我需要的功能,而我在master中不需要的功能分支中有一些较旧的提交,而我确实希望在master中获得了一些。干净整洁。
Vale Trujillo

17

承诺包括血统。您不能不合并先前的提交就合并一个提交。

您当然可以挑选它们。当您的分支处于维护模式时,这是很好的流程。


1
谢谢,樱桃挑选会做的。不如我希望的那样好,但它会做到的。
布拉德·罗宾逊


3

一种对我的项目的广告它基本上包装了@araqnid描述的过程。

这类帮助程序介绍了以下GIT流程:

  • 从维护分支到开发/主分支的合并有每日/每周通知
  • 分支维护者检查状态,并自行决定是否需要所有提交,然后阻止其中一些,或要求开发人员阻止自己。最终,维护分支合并到upsteam中。

项目页面的报价:

根据工作流程,可以将维护分支或客户特定分支与主分支一起使用。这些分支也称为LTS分支。

通常,修补程序会进入报告错误的分支,然后将提交合并回master分支。

通常的做法是使所有分支与master完全同步,即,您想查看特定分支与master之间的明确差异,以了解master是否包含所有功能和错误修正。

但是,有时您不希望特定的提交,因为它们是特定于客户的,并且其他用户将看不到它们。或者您的主分支差异很大,以至于需要使用完全不同的方法来解决此问题,甚至更好的是,该问题不再存在。

同样,在从master到维护分支的选择过程中,最终的提交也将在master中被阻止。


0

在master10中而不是master20中为所需的更改创建第三个分支。始终将master10视为您的“ master”,这是最稳定的分支。所有其他分支都希望一直与之保持同步的分支。


我想这可能行得通,但是我已经进入了这种状态,而第三个分支可能会使我更加困惑。:)
布拉德·罗宾逊

0

而不是revertcherry-pick在这种情况下,在这种情况下,您需要使用git来考虑要跳过的更改要早于所做的更改。

所以:

  1. 在您要跳过的提交之前合并最后的提交。当然,这将合并所有提交。 git merge ccc
  2. 合并您要跳过的提交。 git merge fff --no-commit
  3. 暂存所有合并,取消暂存所有更改,撤消所有更改。(也许对此有一些简单的命令,但是我只是在UI中执行此部分,但是您知道如何做)
  4. 完成空合并 git merge --continue
  5. 在您要跳过的提交之后合并提交。 git merge source-branch-head

在第4步之后,git将考虑您的分支比该提交更新,因为您已经处理了该分支(通过选择保留您的事物版本)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.