简体   繁体   English

Mercurial的工作流程:在重新建立补丁分支时,删除旧提交

[英]Workflow with Mercurial: remove old commits when rebasing a patch branch

I would like to understand which is the better way to realize the workflow I'm going to present with Mercurial. 我想了解哪种方法是实现与Mercurial一起呈现的工作流程的更好方法。 I know how I would do it in Git, which I'm much more confident with, but couldn't find a satisfying way with Mercurial. 我知道我将如何在Git中做到这一点,我对此很有信心,但是在Mercurial中找不到令人满意的方法。

The workflow is the following: I want to track an upstream branch, where development work is done by somebody else, and maintain a reasonably small patch branch on top of it. 工作流如下:我想跟踪上游分支,其他人在上面进行开发工作,并在其上面维护一个相当小的补丁分支。 What I would do with Git is the following: every time I want to include some new upstream commit, I rebase my patch branch over the upstream branch (or the relevant commit, BTW), perhaps modify some commit and forcibly push the patch branch to a repository that is shared with my collaborators (I'm aware of the issues with non fast-forward pushes and so are my collaborators; we know how to avoid problems). 我对Git所做的工作如下:每次我想包括一些新的上游提交时,我都会在上游分支(或相关的提交,BTW)上重新建立我的补丁分支,也许修改一些提交并将其强制推送到与我的协作者共享的存储库(我知道非快进推送的问题,我的协作者也知道;我们知道如何避免问题)。

I would like to do the same with Mercurial. 我想对Mercurial也这样做。 The main problem is that every time that I push a new head, the previous one doesn't get deleted like it happens with Git (ok, commits are not really deleted, but they practically disappear, since they are not ancestors of any branch anymore; they will be eventually really deleted by git gc and that's ok for me). 主要问题是每次我推一个新的头时,上一个头都不会像Git那样被删除(好吧,提交并没有真正删除,但实际上却消失了,因为它们不再是任何分支的祖先;最终它们会被git gc真正删除,这对我来说是可以的)。 So my repository remains polluted with a lot of old commits that I don't want anymore. 因此,我的存储库仍然被许多我不再想要的旧提交污染。 I couldn't find any way to delete them (except perhaps deleting them one by one, but that's not really a solution). 我找不到删除它们的任何方法(除了可能一个一个地删除它们,但这并不是真正的解决方案)。

Is there any better way to do this with Mercurial? 使用Mercurial有更好的方法吗?

In other words, what I would like to do is to automatically delete all commits that are not ancestors of some commit in a predetermined set. 换句话说,我想做的是自动删除不是预定集合中某些提交祖先的所有提交。

EDIT : since someone is asking for more details, I try to be more precise. 编辑 :由于有人要求提供更多详细信息,我尝试更加精确。 I start with this repository: 我从这个存储库开始:

C <upstream>
|
B
|
A
|

Then I develop some patches on it: 然后我在上面开发一些补丁:

F <patch>
|
E
|
D
|
C <upstream>
|
B
|
A
|

At some point upstream adds some more commits: 在上游的某个时候,添加了更多的提交:

F <patch>  I <upstream>
|          |
E          H
|          |
D          G
|          |
C ---------+
|
B
|
A
|

I rebase my patch branch on it, perhaps modify something in the patches and arrive here: 我在此基础上重新建立了补丁分支,也许修改了补丁中的内容并到达此处:

F' <patch>
|
E'
|
D'
|
I <upstream>
|
H
|
G
|
C
|
B
|
A
|

Then I push everything on the remote Mercurial repository: 然后,将所有内容推送到远程Mercurial存储库中:

F' <patch>  F
|           |
E'          E
|           |
D'          D
|           |
I ----------+ <upstream>
|
H
|
G
|
C
|
B
|
A
|

Mercurial doesn't automatically delete the D,E,F head, but I would like it to disappear. Mercurial不会自动删除D,E,F头,但我希望它消失。 I do this pull/rebase/modify/push cycle often and would like to erase old leftover commts that are not relevant anymore. 我经常执行此拉/重新设置/修改/推循环,并希望删除不再相关的旧剩余commt。 How do I do that? 我怎么做?

Thanks. 谢谢。

I know the pain and don't have an automatic solution handy. 我知道很痛苦,并且没有自动解决方案。 I try not to let too much cruft accumulate (checked regularly with hg heads -t ) and use hg strip to remove unwanted changesets from the repository. 我尽量不要堆积过多的碎片(使用hg heads -t定期检查),并使用hg strip从存储库中删除不需要的变更集。 Stripping is not done one by one (changeset), instead, if you choose the right changeset, then it's usually just one strip for every rebase cycle, because all of the stripped changeset's descendants get stripped as well – the repository cannot have orphans. 剥离不是一个接一个地进行(变更集),而是,如果选择正确的变更集,则每个重新基准周期通常只剥离一条,因为所有剥离的变更集的后代也会被剥离-存储库不能有孤儿。 Finding the right changeset is a bit tedious, but since usually only a handful of patches is involved, it is not too difficult using hg glog . 找到正确的变更集有点乏味,但是由于通常只涉及少数补丁程序,因此使用hg glog并不是很难。

If your business-task is 如果您的业​​务任务是

  • Get changes from RepoOne 从RepoOne获取更改
  • Merge these changes with your mainline 合并这些变化主线
  • Publish merge-results into RepoTwo 将合并结果发布到RepoTwo

you have at least two (dirty thinking without deep testing) ways to do it in more Mercurial-way 您至少有两种(经过深思熟虑的肮脏思维)以更Mercurial的方式进行操作

Branch-way 科路

  • Maintain your mainline in separate named branch ANYNAME != default (default most probably used by upstream) 将您的主线维护在单独的命名分支ANYNAME !=默认值中(默认值很可能由上游使用)
  • Have upsteam-repo in paths section of .hgrc in order to be able to pull from it 在.hgrc的paths部分中有upsteam-repo,以便能够从中提取
  • Pull, when needed, from upsteam 必要时从上拉
  • Merge to ANYNAME , resolve conflicts, if any 合并到ANYNAME ,解决冲突(如果有)
  • Commit and push in your repo only ANYNAME branch hg push -b ANYNAME (side-effect: parents of mergeset from upstream will be pushed also) 仅提交并推送您的ANYNAME分支hg push -b ANYNAME (副作用:来自上游的mergeset的父级也会被推送)

MQ-way MQ-方式

  • Have MQ extension enabled in your repo 在您的仓库中启用了MQ扩展
  • Convert your local patches into MQ's patchset (on top of upstream code) in common branch 在公共分支中将本地补丁转换为MQ的补丁集(在上游代码之上)
  • Have upsteam-repo in paths section of .hgrc in order to be able to pull from it 在.hgrc的paths部分中有upsteam-repo,以便能够从中提取
  • Pull, when needed, from upstream 需要时从上游拉动
  • Merge patches with upstream 与上游合并补丁
  • For patch-exchange you have two ways 对于补丁交换,您有两种方法
    • if patch-queue was created as repository ( hg qinit -c ) you can push this repository in addition to "base" 如果补丁程序队列是作为存储库( hg qinit -c )创建的,则除了“ base”之外,还可以推送该存储库
    • Using MQCollab extension on top of MQ will allow you to exchange and synchronize patches with collaborators directly (which have to have also MQ and MQCollab) 在MQ之上使用MQCollab扩展将允许您直接与协作者交换补丁和同步补丁(协作者也必须具有MQ和MQCollab)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM