Mercurial补丁的创建和使用

Mercurial补丁的创建和使用,mercurial,patch,Mercurial,Patch,我遇到了一个问题,我“认为”只有使用补丁才能解决 我从我们的主存储库克隆了一个项目,对它做了很多更改(更新、删除文件和目录以及添加)。这些更改甚至没有提交。问题是,主存储库中的项目已被删除/删除,并重新创建为新项目(名称相同,所有目录结构都与以前相同)。我再次从主存储库克隆了该项目,并希望将所有未提交的更改转移到该项目 我仍在探索hg补丁来解决这个问题。如果有人能确认创建和添加补丁是正确的方法,这将非常有帮助,任何解释该过程的资源都会非常有帮助。如果布局相同,您可以复制所有文件(不包括.hg),

我遇到了一个问题,我“认为”只有使用补丁才能解决

我从我们的主存储库克隆了一个项目,对它做了很多更改(更新、删除文件和目录以及添加)。这些更改甚至没有提交。问题是,主存储库中的项目已被删除/删除,并重新创建为新项目(名称相同,所有目录结构都与以前相同)。我再次从主存储库克隆了该项目,并希望将所有未提交的更改转移到该项目


我仍在探索
hg补丁来解决这个问题。如果有人能确认创建和添加补丁是正确的方法,这将非常有帮助,任何解释该过程的资源都会非常有帮助。

如果布局相同,您可以复制所有文件(不包括.hg),然后使用
hg addrem
尝试查看MQ插件,如果我记得的话,它就是这样做的。但是我从来没有使用过它,所以我不能说。

如果只是将旧存储库移动/克隆到一个新的URL,那么您可以简单地将远程存储库更改为新的存储库

但是,如果它是从头开始重新创建的(即使使用相同的结构),那么我认为Mercurial没有任何内置功能来帮助您。Mercurial补丁引用新存储库中不存在的特定变更集

您可以使用合并工具来执行差异,并将您所做的任何更改都合并到一起

编辑以回答评论中的问题: 克隆存储库时,您正在拍摄整个更改历史的完整快照,以及相关的更改集ID等

Mercurial通过更改集跟踪存储库中的更改,而不是像Subversion那样在文件级别

如果进行克隆,则可以轻松地推送/合并到另一个也从同一源克隆的存储库中

如果重新创建了存储库,那么更改ID将不匹配,并且无法合并到Hg中。 在这种情况下,唯一的选择是使用合并工具,它可以让您看到文件/文件夹结构中的不匹配


另外:值得指出的是,它(间接地)解释了其中的一些原因

我会先复制所有东西,这样你就有了回溯的方法

然后,在带有更改的工作副本中,我将首先删除
.hg
目录,然后从新repo中复制
.hg
目录。这基本上将所有更改的文件传输到新的repo中,而无需删除任何文件和目录

您仍然需要告诉repo是否删除任何标记为丢失的文件。您还必须手动处理重命名。如果这是一个小数目的操作,它比尝试使用补丁方法更容易


完成后,提交您的更改并在必要时推送。

似乎您需要的是修补程序队列。因为您有未提交的更改,并且您希望在提交更改之前从新回购中提取

$ hg qinit -c # initialize mq for your repo containing the uncommitted changes 
$ hg qnew name_of_patch # create patch that contains your uncommitted changes
$ hg qpop # resets your working dir back to the parent changeset
不过不用担心,您的更改在.hg/patches/name_of_patch中是安全可靠的,您可以自己查看

$ cat .hg/patches/name_of_patch
现在加入新的回购协议

$ hg pull -u http://location.of.new/repo # pull in changes from new repo update working dir

$ hg qpush # apply your uncommitted changes to new repo
$ hg clone http://location.of.new/repo ./new_repo
如果幸运的话,您将不会有合并冲突,您可以继续并通过提交补丁

$ hg qfinish -a # change all applied patches to changeset
如果你想

$ hg push http://location.of.new/repo
如果回购协议不相关,只需在新回购协议上初始化补丁回购协议即可。然后手动复制补丁并将其添加到.hg/patches/series文件中

假设已创建修补程序。克隆新回购协议

$ hg pull -u http://location.of.new/repo # pull in changes from new repo update working dir

$ hg qpush # apply your uncommitted changes to new repo
$ hg clone http://location.of.new/repo ./new_repo
初始补丁回购

$ cd ./new_repo && hg qinit -c
复制补丁

$ cp ../old_repo/.hg/patches/name_of_patch .hg/patches/
使用某种编辑器编辑序列文件

$ your_favorite_editor .hg/patches/series

name_of_patch   # <---put this in the series file
如果没有合并冲突,并且您确信它是有效的

$ hg qfinish -a

标准Mercurial安装可执行以下步骤:

  • 在本地存储库中提交更改。注意修订号
  • 使用“hg export-r REV>patch.diff”创建补丁
  • 克隆新存储库
  • 使用“hg import patch.diff”将修补程序应用于新存储库
  • 例子 此时,
    example
    example2
    具有相同的内容,但由于删除并重新初始化.hg文件夹,存储库彼此无关

    现在进行一些更改并在其中一个存储库中提交,然后将其导出为修补程序:

    C:\example>echo >>file1
    C:\example>echo >file2
    C:\example>hg ci -Am changes
    adding file2
    
    C:\example>hg export -r 1 >patch.diff
    
    下面显示了由于重新初始化,其他存储库无法提取更改。但是,它可以成功应用修补程序:

    C:\example>cd ..\example2
    C:\example2>hg pull
    pulling from c:\example
    searching for changes
    abort: repository is unrelated
    
    C:\example2>hg import ..\example\patch.diff
    applying ..\example\patch.diff
    

    您是对的-修补程序是将信息从一个存储库传输到另一个(不相关)存储库所需的。正如您所注意到的,这将起作用,因为文件是相同的

    因此,要将未提交的更改从
    旧的
    克隆中转移,您需要

    $ hg diff -g > uncommited.patch
    $ cd ../new
    $ hg patch --no-commit ../old/uncomitted.patch
    

    这将恢复修补程序中保存的信息。这包括有关在旧克隆中添加或重命名的文件的信息。

    我认为这是一个手动且不完整的解决方案,首先我必须确保复制所有文件,然后从新文件中删除文件和目录。嗯,听起来很有趣,我只是想知道为什么我必须手动处理重命名,是因为new.hg目录不知道这些更改吗?如果是这样的话,那么new.hg就不会知道任何文件了?每当我重命名一个文件,Mercurial状态就会显示出来!然后呢?针对旧文件和新文件,这是意料之中的。重命名文件时应使用“hg rename”,以便在文件重命名过程中跟踪历史记录。因为重命名必须通过hg中的显式命令来完成,以便维护文件历史记录,我们通过在文件系统级别有效重命名任何更改的文件名来避免这种情况。TortoiseHg有一个Guess重命名功能,可以自动执行此操作,但是如果只是几个文件,您可以将它们命名为旧名称,然后使用hg的重命名功能返回新名称。Guess重命名来自