git - 合并时跳过特定提交
我已经使用 Git 大约一年了,觉得它太棒了,但我刚刚开始该项目的第二个版本,并为其启动了一个新分支。 我正在为处理未来事情的最佳方式而苦苦挣扎。
我有两个分支,称为 master10 (对于 v1)和 master20 (对于 v2)。 我一直在 master10 分支上的 v1 中进行错误修复,并开发 master20 的新内容。 每当我修复错误时,我都会通过检查 master20 并执行 git merge master10 来将其合并到 v2 中。 到目前为止,一切都很好。
然而现在,我在 v1 中进行了我不希望在 v2 中进行的更改,但我想继续合并其他错误修复。 我如何告诉 Git 跳过该特定提交(或一系列提交),但今后我仍然想合并其他错误修复。
我认为 git rebase 可能就是我所需要的,但读完文档后我的头几乎爆炸了。
我认为我想要的是类似于“gitsync”命令的东西,它告诉git两个分支现在是同步的,并且将来只合并从此同步点开始的提交。
任何帮助表示赞赏。
I've been using Git for about a year now and think it's fantastic, but I've just started on a second version of the project and started a new branch for it. I'm struggling a little with the best way to handle things going forward.
I have two branches called say master10 (for v1) and master20 (for v2). I've been making bug fixes in v1 on branch master10, and developing new stuff of master20. Whenever I make a bug fix I merge it into v2 by checking out master20 and doing git merge master10
. So far so good.
Now however, I've made a change in v1 that I don't want in v2, but I want to continue merging other bug fixes. How do I tell Git to skip that particular commit (or a range of commits), but that going forward I still want to merge other bug fixes.
I thought git rebase
might be what I need but read the doc and my head nearly exploded.
I think what I want is something like a "git sync" command that tells git that two branches are now in-sync and in future only merge the commits from this sync-point on.
Any help appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
例如,如果您想将分支“maint”上的大多数但不是全部提交合并到“master”,您可以这样做。 它需要一些工作——如上所述,通常的用例是合并分支中的所有内容——但有时您会对不应该集成回来的发布版本进行更改(也许该代码是已经在 master 中被取代了),那么你如何表示呢? 这里...
因此,让我们假设 maint 已应用了 5 个更改,其中之一 (maint~3) 不会合并回 master,尽管所有其他都应该合并。 您分三个阶段执行此操作:实际上合并该阶段之前的所有内容,告诉 git 将 maint~3 标记为已合并,即使它尚未合并,然后合并其余部分。 神奇的是:
第一个命令将在麻烦的维护提交到 master 之前的所有内容合并。 默认合并日志消息将解释您正在合并“分支'maint'(早期部分)”。
第二个命令合并了麻烦的 maint~3 提交,但是“-s ours”选项告诉 git 使用特殊的“合并策略”,事实上,该策略的工作原理是简单地保留要合并到的树并忽略提交(s )你们正在完全融合。 但它仍然以 HEAD 和 maint~3 作为父级进行新的合并提交,因此修订图现在显示 maint~3 已合并。 因此,实际上您可能还想对 git merge 使用 -m 选项,以解释 maint~3 提交实际上被忽略了!
最后的命令只是将 maint 的其余部分(maint~2..maint)合并到 master 中,以便您再次同步。
If you want to merge most but not all of the commits on branch "maint" to "master", for instance, you can do this. It requires some work---- as mentioned above, the usual use case is to merge everything from a branch--- but sometimes it happens that you made a change to a release version that shouldn't be integrated back (maybe that code's been superceded in master already), so how do you represent that? Here goes...
So let's suppose maint has had 5 changes applied, and one of those (maint~3) is not to be merged back into master, although all the others should be. You do this in three stages: actually merge everything before that one, tell git to mark maint~3 as merged even when it isn't, and then merge the rest. The magic is:
The first command merges everything before your troublesome maint commit onto master. The default merge log message will explain you're merging "branch 'maint' (early part)".
The second command merges the troublesome maint~3 commit, but the "-s ours" option tells git to use a special "merge strategy" which, in fact, works by simply keeping the tree you are merging into and ignoring the commit(s) you are merging completely. But it does still make a new merge commit with HEAD and maint~3 as the parents, so the revision graph now says that maint~3 is merged. So in fact you probably want to use the -m option to
git merge
as well, to explain that that maint~3 commit is actually being ignored!The final command simply merges the rest of maint (maint~2..maint) into master so that you're all synced up again.
恕我直言,最合乎逻辑的做法是合并所有内容,然后使用 git revert (commit_you_dont_want) 删除它。
示例:
如果您有多个“要忽略”提交,或者想要编辑恢复消息:
那么您的历史记录可能如下所示:
如果您的冲突仅涉及这些“要忽略”提交,您可以使用:
所以您的版本将坚持另一个。 即使没有错误消息,您仍然可以“还原”那些不需要的提交,因为它们可能有其他不冲突的更改,而您仍然不想要它们。
如果您遇到的冲突不仅涉及“要忽略”的提交,您应该手动解决它们,并且您可能必须在恢复期间再次解决它们。
IMHO, the most logical thing to do, is to merge everything, and then use git revert (commit_you_dont_want) to remove it.
Example:
If you have multiple "to-ignore" commits, or would like to edit revert message:
Then your history may look like:
If you have conflicts involving ONLY these "to-ignore" commits, you may use:
So your version will persist over the other one. Even without error messages, you may still "revert" those unwanted commits, because they may have other changes that did not conflict, and you still don't want them.
If you have conflicts envolving NOT ONLY the "to-ignore" commits, you should resolve them manually, and you'll probably have to resolve them again during reverting.
承诺包括血统。 如果不合并先前的提交,则无法合并提交。
当然,你可以挑选它们。 当您有一个处于维护模式的分支时,这是一个很好的流程。
Commits include ancestry. You can't merge a commit without merging prior commits.
You can cherry-pick them, of course. That's a fine flow when you have a branch that's in maintenance mode.
听起来像是“gitcherry-pick”的经典案例
https://git-scm.com/docs/git-cherry-pick
它的作用正如其听起来的那样
Sounds like a classic case for 'git cherry-pick'
https://git-scm.com/docs/git-cherry-pick
it does exactly what it sounds like
一种对我的项目的广告,它基本上包含了@araqnid描述的过程。
它是一种引入以下 GIT 流程的帮助程序:
项目页面的引用:
A kind of an advertisement to my project which basically wraps the process described by @araqnid.
It's kind of helper that introduces following GIT flow:
A quote from the project page:
您可以使用 git-cherry pick 来实现此目的:
此选择从当前
HEAD
和origin/branch
的最后一次公共提交中挑选所有提交,直到提交被忽略(注意>^
告诉cherry-pick 在该提交的父级停止)。第二个命令从
中挑选所有内容以及origin/branch
的其余部分。请注意,如果需要跳过提交来合并其他补丁,则可能仍然需要一些修补(git 将停止cherry-pick 并告诉您解决冲突)。
You can use git-cherry pick for this:
This cherry-picks all commits from last common commit of current
HEAD
andorigin/branch
until commit to be ignored (note^
telling cherry-pick to stop at parent of that commit).Second command cherry-picks everything from
<offending-commit-hash>
with rest oforigin/branch
.Note that some tinkering might be still needed if skipped over commit is needed to merge other patches (git will stop cherry-pick and tell you to resolve conflicts).
为您想要在 master10 中但不在 master20 中进行的更改创建第三个分支。 始终将 master10 视为您的“master”,这是所有分支中最稳定的分支。 所有其他分支都希望始终保持同步的分支。
Create a third branch for the changes you want in master10 but not in master20. Always consider master10 as your "master", the most stable branch of all. The branch all other branches want to keep in sync with at all times.
在这种情况下,您需要让 git 考虑您要跳过的更改比您所做的更改旧,而不是使用
revert
或cherry-pick
。因此:
git merge ccc
git merge --continue
git merge source-branch-head
在第 4 步之后,git 会认为您的分支比该提交更新,因为您已经处理过它(通过选择保留您的版本)。
Rather than
revert
orcherry-pick
for this case, you need to get git to consider the changes you're skipping to be older than the ones you made.So:
git merge ccc
git merge fff --no-commit
git merge --continue
git merge source-branch-head
After Step 4, git will consider your branch more recent than that commit, since you dealt with it already (by choosing to keep YOUR versions of things).