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

我已经使用Git大约一年了,觉得它很棒,但我刚刚开始开发这个项目的第二个版本,并为它创建了一个新的分支。我有点纠结于如何最好地处理未来的事情。

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

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

我以为git rebase可能是我需要的,但看了医生,我的头几乎爆炸了。

我想我想要的是一个类似于“git sync”命令的东西,它告诉git两个分支现在是同步的,将来只合并从这个同步点开始的提交。

感谢任何帮助。

78190 次浏览

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

提交包括祖先。如果不合并先前的提交,就不能合并一次提交。

当然,你可以从中挑选。当你有一个处于维护模式的分支时,这是一个很好的流动。

如果你想合并分支“维护”上的大部分而不是所有提交;例如,要“精通”,你可以这样做。这需要一些工作----如上所述,通常的用例是合并来自分支的所有内容——但有时发生的情况是,您对发布版本进行了更改,而不应该集成回去(也许该代码已经在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

第一个命令合并所有之前你麻烦的维护提交到主。默认的合并日志消息将解释您正在合并“分支‘维护’(早期部分)”。

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

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

恕我直言,最合乎逻辑的做法是合并所有内容,然后使用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'

如果你的冲突只涉及这些“to-ignore”提交,你可以使用:

git merge master -X ours

所以你的版本会比另一个版本持久。即使没有错误消息,您仍然可能“恢复”那些不想要的提交,因为它们可能有其他不冲突的更改,而您仍然不想要它们。

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

项目的一种广告,它基本上包装了@araqnid所描述的进程。

它是一种助手,引入以下GIT流程:

  • 每天/每周都会有一个关于从维护分支到开发/主分支的待处理合并的通知
  • 分支维护者检查状态并自己决定是否所有的提交都是必需的,然后要么阻止一些提交,要么让开发人员阻止他们自己。最后,维护部门合并到上游部门。

项目页面上的一句话:

根据工作流程,有可能进行维护或 特定于客户的分支以及主分支。这些 分支也被称为LTS分支 通常情况下,热修复会进入bug所在的分支 报告,然后提交被合并回主分支 一般的做法是让所有分支完全同步 master,即你想要看到一个特定之间的清晰的delta 分支和主节点要了解主节点是否包含全部

然而,有时你不想要特定的提交,因为它们是 特定于客户,不应被其他用户看到。或者你的 主分支分歧太大,要求完全不同 方法解决问题,甚至更好,问题不再 现在。< / p >

同样在从master进入维护分支的情况下 生成的提交将在master中被阻塞

听起来像是'git cherry-pick'的经典案例 https://git-scm.com/docs/git-cherry-pick 它就像它听起来的那样

在这种情况下,你需要让git考虑你所跳过的更改比你所做的更改更老,而不是revertcherry-pick

所以:

  1. 合并要跳过的提交之前的最后一次提交。当然,这将在之前合并所有提交。git merge ccc
  2. 合并要跳过的提交。git merge fff --no-commit
  3. 执行任何合并,取消执行所有更改,撤销所有更改。(也许对此有万无一失的命令,但我只是在UI中完成这部分-无论你知道怎么做)
  4. 完成空合并git merge --continue
  5. 合并提交后,你想跳过一个。git merge source-branch-head

在步骤4之后,git会认为你的分支比上次提交的要更新,因为你已经处理过它了(通过选择保留你的版本)。

你可以用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的最后一次公共提交中挑选所有提交,直到忽略提交(注意^告诉挑选停止在该提交的父节点)。

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

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