git - 合并时跳过特定提交

时间:2009-04-07 23:32:54

标签: git version-control

我已经使用Git大约一年了,并认为这太棒了,但我刚刚开始了该项目的第二个版本,并开始了一个新的分支。我正在努力解决未来的最佳方法。

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

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

我认为git rebase可能是我需要的,但阅读了文档,我的头几乎爆炸了。

我认为我想要的就像是一个“git sync”命令,告诉git两个分支现在是同步的,将来只会合并来自这个同步点的提交。

任何帮助表示感谢。

8 个答案:

答案 0 :(得分:269)

例如,如果要将分支“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

第一个命令将麻烦的maint提交之前的所有合并到master上。默认的合并日志消息将解释您正在合并“branch'maint'(早期部分)”。

第二个命令合并了麻烦的maint~3 commit,但是“-s ours”选项告诉git使用一个特殊的“合并策略”,实际上,只需保留你要合并的树并忽略它提交你完全合并。但是它仍然使用HEAD和maint~3作为父项进行新的合并提交,因此修订图现在表示maint~3被合并。所以实际上你可能也想使用-m选项'git merge'来解释maint~3 commit实际上被忽略了!

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

答案 1 :(得分:32)

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

示例:

git merge master
git revert 12345678

如果您有多个“to-ignore”提交,或者想要编辑还原消息:

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 :(得分:16)

提交包括祖先。如果不合并先前的提交,则无法合并提交。

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

答案 3 :(得分:6)

听起来像'git cherry-pick'的经典案例 https://git-scm.com/docs/git-cherry-pick 它确实听起来像

答案 4 :(得分:2)

project的一种广告,它基本上包含了@araqnid所描述的过程。

它引入了以下GIT流程的帮助:

  • 有关于从维护分支到dev / master分支的待定合并的每日/每周通知
  • 分支维护者检查状态并决定是否所有提交都是必需的,并阻止它们或要求开发人员阻止自己。最后维护分支合并到上游。

项目页面的引用:

  

根据工作流程,可以进行维护或   客户特定分支以及主分支。这些   分支也称为LTS分支。

     

通常,热修复程序会进入错误所在的分支   报告然后将提交合并回主分支。

     

一般的做法是让所有分支完全同步   主人,即你想看到一个特定的明显的增量   分支和主人,以了解主人是否包含所有   功能和错误修正。

     

但是,有时你不想要特定的提交,因为它们是   客户特定的,其他用户不得看到。或者你的   主分支分歧很大,它需要完全不同   解决问题的方法,甚至更好,问题不再存在   在那里。

     

此外,如果从主人那里挑选樱桃进入维修部门   生成的提交应在master中被阻止。

答案 5 :(得分:1)

您可以为此使用 git-cherry pick:

git cherry-pick $(git merge-base HEAD origin/branch)..$(git rev-parse <offending-commit-hash>^)
git cherry-pick <offending-commit-hash>..$(git rev-parse origin/branch)

从当前 HEADorigin/branch 的最后一次共同提交中挑选所有提交,直到提交被忽略(注意 ^ 告诉cherry-pick 在该提交的父项处停止) .

第二个命令从 <offending-commit-hash> 中挑选所有内容以及 origin/branch 的其余部分。

请注意,如果需要跳过提交来合并其他补丁,则可能仍需要进行一些修补(git 将停止选择并告诉您解决冲突)。

答案 6 :(得分:0)

为master10中的所需更改创建第三个分支,但不在master20中。始终将master10视为您的“主人”,是所有人中最稳定的分支。所有其他分支机构的分支机构都希望始终保持同步。

答案 7 :(得分:0)

在这种情况下,您需要使用git来考虑要跳过的更改,使其比进行的更改更早,而不是revertcherry-pick

所以:

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

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