我有两个分支dev
和a
。我需要将功能a
合并到dev
,但我的队友已在一个文件中创建了某些尚未准备好合并的功能。如果我只是使用我的合并和解析,git会将此文件中的更改标记为无效,而不是允许这些更改在以后合并,如果我尝试重新合并分支,则只需快进。如果我没有解决冲突,git拒绝执行合并。
我解决这个问题的策略是创建一个分支并抑制破坏的特征,然后合并到这个分支中。问题是这个git命令有点复杂,所以我需要专家的帮助。
如果可能的话,我希望将这种类型的操作概括为一个git扩展,我会称之为git-cherrymerge
的效果。
步骤如下:
我不是filter-branch
或rebase
的专家,看起来我非常认真地通过滥用来破坏历史。
我想我的问题是
答案 0 :(得分:4)
You've basically got the right idea, you want to turn one branch into two: a branch with the stuff that's ready to go, and a branch on top of that which is the incomplete changes. For example, a branch might contain a bunch of refactoring and bug fixes interleaved with incomplete features.
A - B - C - D [master]
\
R1 - B1 - F1 - R2 - B2 - F2 [feature]
R1 and R2 are refactoring changes. B1 and B2 are bugfix changes. F1 and F2 are incomplete features. What you want is this:
A - B - C - D [master]
\
R1 - B1 - R2 - B2 [fixes]
\
F1 - F2 [feature]
There's two steps there, reordering the commits and declaring the new branch. Reorder the commits with git rebase -i
. This will present something like:
pick f37beee Refactor 1
pick 7f238ea Bugfix 1
pick d100dd2 Feature 1
pick aa1124b Refactor 2
pick beadbee Bugfix 2
pick 0123abc Feature 2
Then you literally reorder them in the editor.
pick f37beee Refactor 1
pick 7f238ea Bugfix 1
pick aa1124b Refactor 2
pick beadbee Bugfix 2
pick d100dd2 Feature 1
pick 0123abc Feature 2
Git will rebuild the branch by applying those patches in the new order. You might have to resolve conflicts. For more info, see Rewriting History in Pro Git.
Then you need to declare a new branch. That's just git branch fixes beadbee
to declare the fixes branch starting at the last commit you want.
Merge fixes into master normally, and rebase feature on top of master.
But often the commits are not so neatly split out. If you had a commit which contains multiple changes and you only want some of them, you can turn it into multiple commits.
Use git rebase -i
as before, but set the commit you want to split up as edit
instead of pick
.
pick f37beee Refactor 1
pick 7f238ea Bugfix 1
pick aa1124b Refactor 2
pick beadbee Bugfix 2
edit beacd4a Messy commit
pick d100dd2 Feature 1
pick 0123abc Feature 2
Then Git will stop on that commit and allow you to edit it how you like. Use git add -p
to add only pieces of the change to the staging area (where you build a commit) and git commit
only the partial changes. Do this until each change has its own commit. For example, maybe it changes the name of a method, fixes a bug, but also changes an unrelated method. You'd split those into three commits: one to change the name, one to fix the bug, and one to change the unrelated method.
You can read more about that in Interactive Staging.
I'm not quite an expert in filter-branch or rebase and it looks like I can quite seriously damage the history be misusing them.
Yes, but you can reverse those mistakes, and nothing will affect anyone else unless you git push
it. Git doesn't rewrite history, it writes new history and pretends it was that way all along. The old history is still there, for a while, and you can go back to it using things like ORIG_HEAD
and git reflog
.
Worst case scenario, delete your local repository and clone a new one.
答案 1 :(得分:0)
我已将 Schwern的答案标记为正确答案,因为它是最常见的案例 - 但值得注意的是,就我的情况而言有一个非常简单的策略如下。因为无论如何我打算压缩更改,这意味着该过程可以在一次提交中完成。仍然需要创建一个新分支,但可以使用软重置快速完成。如果您只想推迟易于管理的小数量的更改,我会推荐此策略
A
A
develop