Git中与Hg mq相对应的是什么?

57

我刚刚开始使用Git来熟悉它,同时也在使用Mercurial。

我经常使用Mercurial的mq扩展来管理本地补丁,现在想知道Git中有没有类似的功能?

是应该直接使用Git分支吗?或者有更好的方法来管理本地补丁方便地应用和删除补丁?

谢谢。

4个回答

32
请��看Git Wiki的Interfaces, Frontends And Tools页面中的"Patch-management Interface layers"部分。列出了两个补丁管理接口,大致相当于Mercurials 'mq' 扩展
  • StGIT(Stacked Git)是两者中较旧的一个,用Python编写,使用两个快照来表示补丁
  • Guilt(以前称为'gq')是一系列bash脚本,系列文件和补丁(每个文件一个)存储为纯文本文件。
  • pg(Patchy Git)已被弃用,不再维护。
但是,如果您不需要更高级的用法,则可以使用"git rebase --interactive"代替,以重新排序、压缩和拆分补丁。对于管理您的分支与上游当前版本的关系,通常使用"git rebase"就足够了。

1
你能说出一些“高级用法”中的其中一个吗?我认为 git rebase --interactive 已经基本上消除了像 Mq 这样的需求。 - kizzx2
7
git rebase --interactive 命令强制你按顺序处理整个提交系列。使用补丁管理界面,你可以轻松地在不同的补丁之间来回切换以编辑它们。你还可以查看补丁的变更历史记录,在系列中间添加新的提交,挑选其他提交等。 - Jakub Narębski
1
@jakub,git checkout 不是可以让你在不同的提交之间来回切换吗?管理补丁有什么难的呢?Git 的整个意义就在于轻松地遍历提交。 - Elazar Leibovich
5
如果你检出早期的提交,比如HEAD2,第一步你会进入“分离头指针”(未命名分支);第二步,如果你修改该提交,例如通过修订它,原先的后续提交(HEAD1、HEAD~0)将不再与之相邻(这是因为在Git中,对于“父节点”等引用提交链接的方式是基于其内容的SHA-1哈希值,如果提交更改,则其SHA-1也会改变)。 - Jakub Narębski
2
@Elazar:通过补丁管理界面(例如git的StGit或Mercurial的mq),很容易跳转到第4个补丁,然后是第2个补丁,然后应用所有补丁,然后跳转到第3个并添加新的补丁。交互式变基意味着跳转到第4个补丁,然后应用所有补丁,跳转到第2个补丁,然后再次应用所有补丁...或者使用checkout + rebase + reset,这在我看来稍微难用一些。 - Jakub Narębski
显示剩余4条评论

32

声明:我不是 hg 用户,所以我了解 hg,但没有太多的实际使用经验。

git 提供了几个非常强大和灵活的工具来管理分支,采用“补丁队列”样式,因此对于许多基本(甚至一些相当复杂)的用例来说,原生 git 已足够强大。

通常,大多数项目都会保留一个中央稳定的主分支,它只获得新提交,从不“倒回”,因此主分支中的提交是固定的。

在此基础上,维护人员(或开发人员)可能会维护一个或多个流动的工作进展分支(即提交),这些分支基于稳定分支。

典型的补丁管理活动包括:

将补丁队列变基到最新的稳定分支 - 使用 git rebase

将补丁队列复制到旧的维护分支 - 使用 git branchgit rebase

重新排序队列中的补丁 - 使用 git rebase --interactive(又名 git rebase -i),使用文本编辑器重新排序队列。

压缩补丁 - 使用带有 squash 指令的 git rebase -i

更改补丁或补丁提交消息 - 使用带有 edit 指令的 git rebase -i(发现一个主题了吗?)。

任何改变补丁的方式(即其内容、描述或父级)的活动都会为该补丁创建一个新的提交,带有新的提交 ID。在它们被推广到稳定主分支之前,旧的提交可能被抛弃并被替换是使它们成为“补丁队列”而不是分支的唯一因素,但这是一个项目约定,而不是组成提交的数据中的任何物理差异。对于 git 来说,它们是相同的对象。

将一个补丁推到“真正的”提交,只是将补丁移到队列前面,并将其合并到主分支中。将补丁移到队列前面后,它就像基于主分支的普通提交一样,因此将其合并只是快进主分支指针以指向补丁提交。
将此提交发布为“稳定”的主要补丁是表明:这是一个不会更改并且是项目不可变历史的一部分的提交。

1
我通常使用Mercurial,但这可能是我见过的关于Git分支背后理性的最好描述。谢谢! :) - rpjohnst
2
Mercurial Queues的一个功能在我的一个项目中被广泛使用,就是通过复制.hg/patches目录来“导出”它们。能够将补丁外部存储和管理对于仓库来说至关重要。不可否认,这种用法非常不寻常,但是Git是否有类似的功能呢? - Paul Moore
1
@PaulMoore 只需在要导出的补丁上执行 git format-patch,甚至可以将它们保存到 mbox 文件中,这样您就可以使用 git am 一次性应用所有补丁。 - remmy
@kyrias 谢谢。我之前没见过 format-patcham。我会去了解一下它们的。 - Paul Moore

9

只需定期使用分支并将其与上游分支进行rebase。这比使用mq更容易管理和更安全(我曾经在mq中丢失过数据)。


7

Git本身并没有提供这个功能。根据您的使用情况,您可能可以通过“git stash”和/或分支来完成,但这将是相当基本的。如果人们在使用git时需要更高级的补丁管理需求,他们似乎会转向Quilt或StGit:请参见http://git.or.cz/gitwiki/PatchManagement


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接