Git增量合并
项目描述
git-imerge -- Git的增量合并和变基工具
在两个分支之间进行增量合并。如果遇到冲突,确定确切的冲突提交对,并一次呈现一个提交对给用户进行解决。
git-imerge
有两个主要设计目标
-
通过找到并呈现最小的冲突(即每个分支引入的一个提交之间的变化)来将解决合并冲突的痛苦减少到不可避免的最小。
-
允许在合并过程中保存、测试、中断、发布和协作。
我认为通过视觉方式理解增量合并的概念更容易,因此我推荐观看我在GitMerge 2013会议上的git-imerge演示视频(20分钟),这是一个很好的起点。该演讲的全部幻灯片可在本存储库中的doc/presentations/GitMerge-2013
部分找到。在同一个会议上,我被Thomas Ferris Nicolaisen采访,讨论了git-imerge
,该采访可在他的GitMinutes播客#12中找到。
要了解如何使用 git-imerge
工具本身,我建议阅读博客文章 git-imerge:实用入门,也可以通过输入 git-imerge --help
和 git-imerge SUBCOMMAND --help
来获取更多信息。如果你想了解更多信息,增量合并的理论和好处可以在一系列博客文章中详细描述[1],同样还有在rebase时保留历史的好处[2]。
可以同时进行多个增量合并。每个增量合并都有一个名称,其进度会记录在Git仓库中,作为 refs/imerge/NAME
下的引用。可以使用 diagram
命令来可视化增量合并的当前状态。
增量合并可以被任意中断和恢复,甚至可以推送到服务器,让其他人继续工作。
git-imerge
包含一个Bash完成脚本 completions/git-imerge
,在安装 git-imerge
时会自动安装。
要求
git-imerge
需要:
-
一个Python解释器;可以是:
-
Python 3.x,版本 3.3 或更高。
-
Python 2.x,版本 2.6 或更高。如果你使用的是Python 2.6.x,那么你必须自己安装
argparse
模块,因为它是在Python 2.7中添加到标准库的。
-
-
Git的较新版本。
Bash完成需要Git的完成功能可用。
安装
git-imerge
在PyPI_上可用,因此你可以使用 pip
来安装它
$ pip install git-imerge
或者如果你已经下载了源代码包,可以使用 setup.py
进行安装
$ python setup.py install
说明
要使用 git-imerge
开始合并或rebase操作,你可以使用与相应 git
命令相似的命令
git-imerge 命令 |
git 类似命令 |
效果 |
---|---|---|
git-imerge merge BRANCH |
git merge BRANCH |
将 BRANCH 合并到当前分支 |
git-imerge rebase BRANCH |
git rebase BRANCH |
将当前分支基于 BRANCH 进行rebase |
git-imerge revert COMMIT |
git revert COMMIT |
添加一个新的提交,该提交取消 COMMIT 的影响 |
git-imerge revert COMMIT1..COMMIT2 |
git revert COMMIT1..COMMIT2 |
添加新的提交,取消 COMMIT1..COMMIT2 的影响 |
git-imerge drop COMMIT |
git rebase --onto COMMIT^ COMMIT |
完全从当前分支的历史中删除提交 COMMIT |
git-imerge drop COMMIT1..COMMIT2 |
git rebase --onto COMMIT1 COMMIT2 |
完全从当前分支的历史中删除提交 COMMIT1..COMMIT2 |
git-imerge drop
也类似于运行 git rebase --interactive
,然后从历史中删除指定的提交。这两个子命令都被包含在git-imerge中,因为等效的git操作可能会冲突,所以它们都可以从增量合并方法中受益。)
如果你使用 git imerge start
开始增量合并,还有更多选项可用
$ git-imerge start --name=NAME --goal=GOAL [--first-parent] BRANCH
其中:
-
NAME
是这个合并的名称(也是结果将保存到的分支的默认名称)。 -
GOAL
描述了你想要如何简化结果(参见下一节)。
增量合并开始后,你将需要解决任何必须解决的冲突。基本步骤与使用 git
进行增量合并相似
while not done:
<fix the conflict that is presented to you>
<"git add" the files that you changed>
git-imerge continue
当你解决所有冲突后,通过输入以下命令完成增量合并:
git-imerge finish
这应该就足够了。所有这些子命令都有额外的选项;要了解它们,请输入
git-imerge --help
git-imerge SUBCMD --help
简化结果
当增量合并完成后,您可以使用finish
或simplify
命令以各种方式简化其结果,然后再将其记录到项目的历史记录中。增量合并的“目标”可以是以下之一:
-
merge
— 只保留第二个分支合并到第一个分支的简单合并,丢弃所有中间合并。最终结果类似于使用git checkout BRANCH1 git merge BRANCH2
-
rebase
— 保留将第二个分支的提交版本重新应用到第一个分支。最终结果类似于使用git checkout BRANCH2 git rebase BRANCH1
-
rebase-with-history
— 类似于rebase
,但保留重新应用提交的历史旧版本。它等同于将BRANCH2
的提交合并到BRANCH1
中,每次一个提交。换句话说,它将这个o---o---o---o BRANCH1 \ A---B---C---D BRANCH2
转换为这个
o---o---o---o---A'--B'--C'--D' NEW_BRANCH \ / / / / --------A---B---C---D
使用这种方法重新应用已发布的分支是安全的。有关更多信息,请参阅[2]。
-
full
— 完全不简化增量合并:执行所有中间合并,并将它们全部保留在永久历史中。换句话说,它将这个o---o---1---2---3 BRANCH1 \ A---B---C---D BRANCH2
转换为这个
o---o---1---2---3 \ \ \ \ A---A1--A2--A3 \ \ \ \ B---B1--B2--B3 \ \ \ \ C---C1--C2--C3 \ \ \ \ D---D1--D2--D3 NEW_BRANCH
这种方法保留了完整的历史和祖先信息,这为将来进行合并提供了最大的灵活性。另一方面,它在Git的永久历史中造成了相当大的混乱。
-
border
— 这个实验性目标保留BRANCH2
到BRANCH1
的重新应用,以及BRANCH1
到BRANCH2
的重新应用,加上包含两个分支的合并提交。换句话说,它将这个o---o---1---2---3 BRANCH1 \ A---B---C---D BRANCH2
转换为这个
o---o---1---2---3 \ \ A A2 \ \ B B2 \ \ C C2 \ \ D---D1--D2--D3 NEW_BRANCH
这种方法比简单合并或重新应用留下了更多的历史记录,可能会使未来的合并更容易。
-
border-with-history
— 这个实验性目标保留BRANCH2
到BRANCH1
的rebase-with-history
,以及(不带历史记录的)BRANCH1
到BRANCH2
的重新应用,加上包含两个分支的合并提交。换句话说,它将这个o---o---1---2---3 BRANCH1 \ A---B---C---D BRANCH2
转换为这个
o---o---1---2---3 \ \ A-----------A3 \ \ B-----------B3 \ \ C-----------C3 \ \ D---D1--D2--D3 NEW_BRANCH
这种方法比简单合并或重新应用留下了更多历史和祖先信息,可能会使未来的合并更容易。
-
border-with-history2
— 这个实验性目标保留BRANCH1
到BRANCH2
的rebase-with-history
,以及BRANCH2
到BRANCH1
的rebase-with-history
,加上包含两个分支的合并提交。换句话说,它将这个o---o---1---2---3 BRANCH1 \ A---B---C---D BRANCH2
转换为这个
o---o---1---2---3 \ \ \ \ A--- --- ---A3 \ \ \ \ B--- --- ---B3 \ \ \ \ C--- --- ---C3 \ \ \ \ D---D1--D2--D3 NEW_BRANCH
这种方法比简单合并或重新应用留下了更多历史和祖先信息,可能会使未来的合并更容易。
技术说明
挂起/恢复
当git-imerge
需要用户手动进行合并时,它会创建一个临时分支refs/heads/imerge/NAME
来保存结果。如果您想挂起增量合并去做其他事情然后再继续,您只需使用git merge --abort
中止任何挂起的合并并切换到其他分支。当您准备好恢复增量合并时,只需输入git imerge continue
。
如果您需要完全中止正在进行的增量合并,首先使用git-imerge remove
删除git-imerge
创建的临时分支,然后使用git checkout ORIGINAL_BRANCH
检查出您开始增量合并之前所在的分支。
存储
git-imerge
将有关增量合并的所有中间状态记录在Git对象数据库中,作为位于refs/imerge/NAME
下的一组引用,其中NAME
是imerge的名称
-
refs/imerge/NAME/state
指向一个blob,以JSON格式描述imerge的当前状态;例如,-
正在合并的两个分支的尖端
-
当前的“阻塞”合并(用户将必须手动完成的合并),如果有的话
-
简化目标
-
将要写入结果的分支名称。
-
-
refs/imerge/NAME/manual/I-J
和refs/imerge/NAME/auto/I-J
分别表示到目前为止作为增量合并的一部分所完成的的手动和自动合并提交。I
和J
是整数,表示合并在增量合并图中的位置(I,J)
。
在仓库间转移正在进行的imerge
有时可能方便将一个正在进行的增量合并从一个Git仓库转移到另一个仓库。例如,您可能想要备份当前状态,或者在家里继续您在工作中开始的一个imerge,或者请同事为您执行特定的成对合并。由于所有imerge状态都存储在Git对象数据库中,因此可以通过推送/获取上一节中命名的引用来完成。例如,
$ git push --prune origin +refs/imerge/NAME/*:refs/imerge/NAME/*
或者
$ git fetch --prune origin +refs/imerge/NAME/*:refs/imerge/NAME/*
请注意,这些命令会覆盖目标仓库中已经存在的任何状态。目前尚不支持合并两个人在增量合并上并行工作的成果,因此现在您只能轮流进行。
与 git rerere
的交互
git rerere
是一个很好的工具,它可以记录您如何解决合并冲突,如果在再次遇到相同的冲突时,它会尝试自动重用相同的解决方案。
由于 git-imerge
尝试了如此多的类似测试合并,因此可以想象 rerere
会感到困惑。此外,git-imerge
依赖于合并解决(或不解决)的一致性,如果它执行多次。因此,rerere
在后台存储额外信息可能会使 git-imerge
感到困惑。
实际上,在测试中,似乎在增量合并期间,git-imerge
与 rerere
的交互有时会导致合并冲突被错误地解决。因此,git-imerge
在运行任何 git
命令时都会明确暂时关闭 rerere。
成对合并提交的日志消息
当 git imerge continue
或 git imerge record
在工作树中找到一个已解决的合并时,它会提交该合并并将其合并到增量合并中。通常它只是使用Git自动生成的提交消息。如果您希望被提示编辑此类提交消息,您可以在命令行上指定 --edit
或更改您配置中的默认设置。
$ git config --global imerge.editmergemessages true
测试
git-imerge
使用 tox
来运行测试。要使用系统的默认Python运行测试套件
$ tox
要使用特定的Python版本,例如3.7,向 tox
传递 -e
参数
$ tox -e py37
许可证
git-imerge
在GNU通用公共许可证(GPL)下以2或更高版本发布为开源软件。有关更多信息,请参阅文件 COPYING
。
参考文献
- http://softwareswirl.blogspot.com/2012/12/the-conflict-frontier-of-nightmare-merge.html
- http://softwareswirl.blogspot.com/2012/12/mapping-merge-conflict-frontier.html
- http://softwareswirl.blogspot.com/2012/12/real-world-conflict-diagrams.html
- http://softwareswirl.blogspot.com/2013/05/git-incremental-merge.html
- http://softwareswirl.blogspot.com/2013/05/one-merge-to-rule-them-all.html
- http://softwareswirl.blogspot.com/2013/05/incremental-merge-vs-direct-merge-vs.html
- http://softwareswirl.blogspot.com/2013/05/git-imerge-practical-introduction.html
项目详情
下载文件
下载适合您平台文件。如果您不确定选择哪个,请了解有关 安装包 的更多信息。
源分发
构建分发
git-imerge-1.2.0.tar.gz 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | df5818f40164b916eb089a004a47e5b8febae2b4471a827e3aaa4ebec3831a3f |
|
MD5 | 59747229598f2b412eb91b6f734dae4c |
|
BLAKE2b-256 | bef6ea97fb920d7c3469e4817cfbf9202db98b4a4cdf71d8740e274af57d728c |
git_imerge-1.2.0-py3-none-any.whl 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 350c64707ee8cb4ccf248b2d6d4dc314d4843b6a99900386601e801e10977acf |
|
MD5 | 6191ee6b272ffb6ee04ea5bfef7e78af |
|
BLAKE2b-256 | 4272dc19db2a8f543da167fa39a865a3e335fe1af682fd5a2dbe2ba3232a41c4 |