部分合并的 Git 工作流程?

awi*_*ebe 3 git version-control merge cherry-pick git-filter-branch

我有两个分支deva。我需要将功能合并a到 中dev,但我的队友在一个文件中创建了某些功能,但尚未准备好合并。如果我只是使用我的合并和解析,git 会将此文件中的更改标记为无效,并且不会允许这些更改稍后合并,而是在我尝试重新合并分支时快进。如果我不解决冲突,git 将拒绝执行合并。

我解决此问题的策略是在旁边创建一个分支并抑制损坏的功能,然后合并到该分支中。问题是 git 命令变得有些复杂,所以我需要专家的帮助。

我希望如果可能的话将这种类型的操作概括为 git 扩展,我会调用一些达到git-cherrymerge.

步骤如下:

  1. 将用户指定的提交(也许这可以通过某种策略自动化)重放到临时分支上
  2. Git filter-branch 删除损坏的文件
  3. 压缩临时分支,添加自动提交消息
  4. 将临时分支合并到目标分支(这里是dev)

我不是filter-branchor方面的专家rebase,看起来我可以通过滥用它们来严重破坏历史

我想我的问题是

  1. 这会起作用还是有更好的规范方法来做到这一点?
  2. 我应该按什么顺序执行哪些 git 命令,以避免意外损坏我的存储库历史记录。

Sch*_*ern 5

您基本上已经有了正确的想法,您想要将一个分支变成两个:一个分支包含已准备好的内容,另一个分支位于未完成的更改之上。例如,一个分支可能包含一堆重构和错误修复,其中包含不完整的功能。

A - B - C - D [master]
         \
          R1 - B1 - F1 - R2 - B2 - F2 [feature]
Run Code Online (Sandbox Code Playgroud)

R1和R2是重构变化。B1 和 B2 是错误修复更改。F1和F2是不完全特征。你想要的是这样的:

A - B - C - D [master]
         \
          R1 - B1 - R2 - B2 [fixes]
                           \
                            F1 - F2 [feature]
Run Code Online (Sandbox Code Playgroud)

这里有两个步骤,重新排序提交并声明新分支。使用 重新排序提交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
Run Code Online (Sandbox Code Playgroud)

然后你可以在编辑器中对它们重新排序。

pick f37beee Refactor 1
pick 7f238ea Bugfix 1
pick aa1124b Refactor 2
pick beadbee Bugfix 2
pick d100dd2 Feature 1
pick 0123abc Feature 2
Run Code Online (Sandbox Code Playgroud)

Git 将通过按新顺序应用这些补丁来重建分支。您可能必须解决冲突。有关更多信息,请参阅在 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
Run Code Online (Sandbox Code Playgroud)

然后 Git 将停止该提交并允许您按照自己的喜好进行编辑。用于git add -p仅将部分更改添加到暂存区域(构建提交的位置),并且git commit仅将部分更改添加到暂存区域。这样做直到每个更改都有自己的提交。例如,它可能更改了方法的名称,修复了错误,但也更改了不相关的方法。您将这些提交分为三项提交:一项用于更改名称,一项用于修复错误,一项用于更改不相关的方法。

您可以在Interactive Staging中阅读更多相关内容。


我不是过滤器分支或变基方面的专家,看起来我可能会因为滥用它们而严重损害历史。

是的,但你可以扭转这些错误,除非你这样做,否则任何事情都不会影响其他人git push。Git 不会重写历史,它会编写新的历史并假装一直都是这样。旧的历史仍然存在一段时间,您可以使用ORIG_HEAD和 之类的东西返回到它git reflog

最坏的情况是,删除本地存储库并克隆一个新存储库