Git 部分合并的工作流程?
Git workflow for partial merges?
我有两个分支 dev
和 a
。我需要将功能 a
合并到 dev
中,但我的队友在一个尚未准备好合并的文件中创建了某些功能。如果我只是使用我的合并和解析,git 会将此文件中的更改标记为无效,而不是允许这些更改在以后合并,如果我尝试重新合并分支则只是快进。如果我不解决冲突,git 拒绝执行合并。
我解决这个问题的策略是在旁边创建一个分支并抑制损坏的功能,然后合并到这个分支中。问题是 git 命令有点复杂,所以我需要专家的帮助。
如果可能的话,我想将这种类型的动作概括为 git 扩展,我会调用一些东西来达到 git-cherrymerge
.
的效果
步骤如下:
- 重播用户指定的提交(也许这可以通过某种策略自动执行)到临时分支
- Git filter-branch 删除损坏的文件
- 压缩临时分支,添加自动提交消息
- 将临时分支合并到目标分支(这里是dev)
我不是 filter-branch
或 rebase
方面的专家,看起来我可以非常认真地 滥用它们来破坏历史 。
我想我的问题是
- 这行得通吗?有更好的规范方法吗?
- 我应该按什么顺序执行什么 git 命令,以避免意外损坏我的存储库历史记录。
您的想法基本上是正确的,您想要将一个分支变成两个:一个分支包含已准备就绪的内容,另一个分支在其之上是未完成的更改。例如,一个分支可能包含一堆重构和错误修复,与不完整的功能交织在一起。
A - B - C - D [master]
\
R1 - B1 - F1 - R2 - B2 - F2 [feature]
R1 和 R2 是重构更改。 B1 和 B2 是错误修复更改。 F1 和 F2 是不完整的特征。你要的是这个:
A - B - C - D [master]
\
R1 - B1 - R2 - B2 [fixes]
\
F1 - F2 [feature]
那里有两个步骤,重新排序提交并声明新分支。使用 git rebase -i
重新排序提交。这将显示如下内容:
pick f37beee Refactor 1
pick 7f238ea Bugfix 1
pick d100dd2 Feature 1
pick aa1124b Refactor 2
pick beadbee Bugfix 2
pick 0123abc Feature 2
然后您可以在编辑器中对它们重新排序。
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 将通过按新顺序应用这些补丁来重建分支。您可能必须解决冲突。有关详细信息,请参阅 Rewriting History in Pro Git。
然后你需要声明一个新的分支。这只是 git branch fixes beadbee
声明从您想要的最后一次提交开始的修复分支。
将修复程序正常合并到 master 中,并在 master 之上重新设置功能。
但是通常提交并不是那么整齐地分开的。如果您有一个包含多个更改的提交并且您只想要其中的一些更改,则可以将其变成多个提交。
像以前一样使用 git rebase -i
,但将要拆分的提交设置为 edit
而不是 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
然后 Git 将停止该提交并允许您按自己喜欢的方式对其进行编辑。使用 git add -p
仅将部分更改添加到暂存区(您构建提交的位置),使用 git commit
仅添加部分更改。这样做直到每个更改都有自己的提交。例如,它可能更改了一个方法的名称,修复了一个错误,但也更改了一个不相关的方法。您可以将它们分成三个提交:一个更改名称,一个修复错误,一个更改不相关的方法。
您可以在 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.
是的,但是您可以扭转这些错误,除非您 git push
否则不会影响任何其他人。 Git 不会重写历史,它会编写新的历史并假装一直都是这样。旧的历史仍然存在一段时间,您可以使用 ORIG_HEAD
和 git reflog
.
之类的东西返回它。
我已将 Schwern 的回答标记为正确答案,因为这是最普遍的情况 - 但值得注意的是,对于我的情况,有一个非常简单的策略如下。由于无论如何我都打算压缩更改,这意味着该过程可以在一次提交中完成。仍然需要创建一个新分支,但可以使用软重置快速完成。如果只有您想要推迟的少量易于管理的更改,我会推荐此策略
- 检查
A
的 HEAD
- 分支到临时分支
- Git软重置为
A
的"root"
- 提交更改,不包括您不想要的更改
- 合并到
develop
我有两个分支 dev
和 a
。我需要将功能 a
合并到 dev
中,但我的队友在一个尚未准备好合并的文件中创建了某些功能。如果我只是使用我的合并和解析,git 会将此文件中的更改标记为无效,而不是允许这些更改在以后合并,如果我尝试重新合并分支则只是快进。如果我不解决冲突,git 拒绝执行合并。
我解决这个问题的策略是在旁边创建一个分支并抑制损坏的功能,然后合并到这个分支中。问题是 git 命令有点复杂,所以我需要专家的帮助。
如果可能的话,我想将这种类型的动作概括为 git 扩展,我会调用一些东西来达到 git-cherrymerge
.
步骤如下:
- 重播用户指定的提交(也许这可以通过某种策略自动执行)到临时分支
- Git filter-branch 删除损坏的文件
- 压缩临时分支,添加自动提交消息
- 将临时分支合并到目标分支(这里是dev)
我不是 filter-branch
或 rebase
方面的专家,看起来我可以非常认真地 滥用它们来破坏历史 。
我想我的问题是
- 这行得通吗?有更好的规范方法吗?
- 我应该按什么顺序执行什么 git 命令,以避免意外损坏我的存储库历史记录。
您的想法基本上是正确的,您想要将一个分支变成两个:一个分支包含已准备就绪的内容,另一个分支在其之上是未完成的更改。例如,一个分支可能包含一堆重构和错误修复,与不完整的功能交织在一起。
A - B - C - D [master]
\
R1 - B1 - F1 - R2 - B2 - F2 [feature]
R1 和 R2 是重构更改。 B1 和 B2 是错误修复更改。 F1 和 F2 是不完整的特征。你要的是这个:
A - B - C - D [master]
\
R1 - B1 - R2 - B2 [fixes]
\
F1 - F2 [feature]
那里有两个步骤,重新排序提交并声明新分支。使用 git rebase -i
重新排序提交。这将显示如下内容:
pick f37beee Refactor 1
pick 7f238ea Bugfix 1
pick d100dd2 Feature 1
pick aa1124b Refactor 2
pick beadbee Bugfix 2
pick 0123abc Feature 2
然后您可以在编辑器中对它们重新排序。
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 将通过按新顺序应用这些补丁来重建分支。您可能必须解决冲突。有关详细信息,请参阅 Rewriting History in Pro Git。
然后你需要声明一个新的分支。这只是 git branch fixes beadbee
声明从您想要的最后一次提交开始的修复分支。
将修复程序正常合并到 master 中,并在 master 之上重新设置功能。
但是通常提交并不是那么整齐地分开的。如果您有一个包含多个更改的提交并且您只想要其中的一些更改,则可以将其变成多个提交。
像以前一样使用 git rebase -i
,但将要拆分的提交设置为 edit
而不是 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
然后 Git 将停止该提交并允许您按自己喜欢的方式对其进行编辑。使用 git add -p
仅将部分更改添加到暂存区(您构建提交的位置),使用 git commit
仅添加部分更改。这样做直到每个更改都有自己的提交。例如,它可能更改了一个方法的名称,修复了一个错误,但也更改了一个不相关的方法。您可以将它们分成三个提交:一个更改名称,一个修复错误,一个更改不相关的方法。
您可以在 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.
是的,但是您可以扭转这些错误,除非您 git push
否则不会影响任何其他人。 Git 不会重写历史,它会编写新的历史并假装一直都是这样。旧的历史仍然存在一段时间,您可以使用 ORIG_HEAD
和 git reflog
.
我已将 Schwern 的回答标记为正确答案,因为这是最普遍的情况 - 但值得注意的是,对于我的情况,有一个非常简单的策略如下。由于无论如何我都打算压缩更改,这意味着该过程可以在一次提交中完成。仍然需要创建一个新分支,但可以使用软重置快速完成。如果只有您想要推迟的少量易于管理的更改,我会推荐此策略
- 检查
A
的 HEAD
- 分支到临时分支
- Git软重置为
A
的"root"
- 提交更改,不包括您不想要的更改
- 合并到
develop