Mercurial 补丁的创建和使用

发布于 2024-10-09 03:38:51 字数 276 浏览 7 评论 0原文

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

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

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

I have come across a problem that I "think" can only be resolved using patches.

I cloned a project from our main repository, made quite a few changes (updates, deletion of files & directory and additions) to it. These changes are not even committed. The problem is, project from the main repository has been deleted/removed and recreated as a new project (name is same, all the directory structures everything is same as before). I cloned that project again from the main repository and would like to transfer all my uncommitted changes to it.

I am still exploring the hg patch to resolve that. It would be helpful if someone could confirm that creating and adding a patch IS the right approach to this, any resources explaining the process would be of great help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

沩ん囻菔务 2024-10-16 03:38:52

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

  1. 在本地存储库中提交更改。请注意修订号。
  2. 使用“hg export -r REV > patch.diff”创建补丁。
  3. 克隆新存储库。
  4. 使用“hg import patch.diff”将补丁应用到新存储库。

示例

C:\>hg init example
C:\>cd example
C:\example>echo >file1
C:\example>hg ci -Am file1
adding file1

C:\example>hg clone . ..\example2
updating to branch default
1 files updated, 0 files merged, 0 files removed, 0 files unresolved

C:\example>rd /s/q .hg
C:\example>hg init
C:\example>hg ci -Am same-but-different
adding file1

此时,exampleexample2 具有相同的内容,但由于删除并重新初始化 .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

The following steps can be performed with a standard Mercurial install:

  1. Commit the changes in your local repository. Note the revision number.
  2. Use "hg export -r REV >patch.diff" to create a patch.
  3. Clone the new repository.
  4. Use "hg import patch.diff" to apply the patch to the new repository.

Example

C:\>hg init example
C:\>cd example
C:\example>echo >file1
C:\example>hg ci -Am file1
adding file1

C:\example>hg clone . ..\example2
updating to branch default
1 files updated, 0 files merged, 0 files removed, 0 files unresolved

C:\example>rd /s/q .hg
C:\example>hg init
C:\example>hg ci -Am same-but-different
adding file1

At this point example and example2 have identical contents, but the repositories are unrelated to each other due to deleting and reinitializing the .hg folder.

Now make some changes and commit them in one of the repositories, then export them as a patch:

C:\example>echo >>file1
C:\example>echo >file2
C:\example>hg ci -Am changes
adding file2

C:\example>hg export -r 1 >patch.diff

Below shows that the other repository can't pull the changes, because of the reinitialization. It can, however, apply the patch successfully:

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
醉生梦死 2024-10-16 03:38:52

我会首先复制所有内容,以便您可以回溯。

然后,在进行更改的工作副本中,我将首先删除 .hg 目录,然后从新存储库复制到 .hg 目录。这基本上会将所有更改的文件传输到新的存储库中,而不需要删除任何文件和目录。

您仍然需要告诉存储库是否删除任何标记为丢失的文件。您还必须手动处理重命名。如果这是少量操作,则比尝试使用修补方法更容易。

完成此操作后,提交更改并推送(如有必要)。

I would first make copies of everything so you have a way of backtracking.

Then, in the working copy with the changes, I would first delete the .hg directory, then copy in the .hg directory from the new repo. This basically transfers all of the changed files into the new repo without the need to delete any files and directories.

You will still need to tell the repo about whether to remove any files marked as missing. You will also have to handle renames manually. If this is a small number of operations, it's easier than trying to use the patch method.

Once this is done, commit your changes and push, if necessary.

悲念泪 2024-10-16 03:38:52

看起来你想要的是补丁队列。因为您有未提交的更改,并且您想在提交之前从新的存储库中提取...

$ 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 qfinish -a # change all applied patches to changeset

,然后如果您愿意....

$ hg push http://location.of.new/repo

如果存储库不相关,只需在你的新仓库。并手动复制补丁并将其添加到 .hg/patches/series 文件中。

假设补丁已创建。克隆新存储库

$ 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 qpush

编辑系列文件,如果没有合并冲突并且您确信它有效,

$ hg qfinish -a

seems like what you want is patch queues. In that you have uncommitted changes, and you want to pull from the new repo before committing them....

$ 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

no worries though, your changes are safe and sound in .hg/patches/name_of_patch to see for yourself.....

$ cat .hg/patches/name_of_patch

now pull in the new repo

$ 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

If you are lucky you will have no merge conflicts and you can go ahead and commit the patch by....

$ hg qfinish -a # change all applied patches to changeset

And then if you want....

$ hg push http://location.of.new/repo

If the repos are unrelated, just init a patch repo on your new repo. and manually copy the patch in and add it to .hg/patches/series file.

assuming patch was created. clone new repo

$ hg clone http://location.of.new/repo ./new_repo

init patch repo

$ cd ./new_repo && hg qinit -c

copy patch

$ cp ../old_repo/.hg/patches/name_of_patch .hg/patches/

edit series file using an editor of some sort

$ your_favorite_editor .hg/patches/series

name_of_patch   # <---put this in the series file

apply your patch to new repo

$ hg qpush

if no merge conflicts and you are convinced it works

$ hg qfinish -a
若水般的淡然安静女子 2024-10-16 03:38:52

如果布局相同,您可以复制所有文件(不包括.hg),然后使用hg addrem

If the layout is the same, you can just copy all the files over (excluding .hg) and then use hg addrem.

别靠近我心 2024-10-16 03:38:52

尝试查看 MQ 插件,如果我没记错的话,它正是这样做的。不过我从来没有用过它,所以我不能说。

Try to look into the MQ plugin, it does exactly this if I recall. I've never had a use for that though, so I can't say.

离笑几人歌 2024-10-16 03:38:52

如果旧存储库只是移动/克隆到新 URL,那么您只需更改与新存储库通信的远程存储库即可。

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

您可以使用合并工具来执行差异并带来您所做的任何更改。

已编辑回答评论中的问题:
当您克隆存储库时,您将获取整个更改历史记录的完整快照 - 以及关联的更改集 ID 等。Mercurial

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

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

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

另外:值得指出 http://hginit.com/ 因为它(间接)解释了其中的一些内容。

If the old repository was simply moved/cloned to a new URL then you could simply change the remote repository you talk to the new one.

If, however, it was recreated from the ground up (even with the same structure) then I don't believe Mercurial has any built-in functionality to help you here. Mercurial patches reference specific changesets which won't exist in your new repository.

You could use a merge tool to perform the diff and bring across any changes you made.

Edited To answer the question in the comment:
When you clone the repository you are taking a complete snapshot of the entire change history - along with the associated change-set IDs, etc.

Mercurial tracks changes by change-sets to the repository, rather than at the file level like Subversion.

If you clone, then you can easily push/merge into another repository that was also cloned from the same source.

If you recreated the repository then the change IDs won't match, and can't be merged in Hg.
The only option in this scenario would be to use a Merge tool which will let you see mismatches in files/folder structure.

Also: Worth pointing out http://hginit.com/ because it explains (indirectly) some of this.

若沐 2024-10-16 03:38:51

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

因此,要从旧克隆中传输未提交的更改,您需要执行此操作,

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

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

You're correct — a patch is what you need to transfer the information from one repository to another (unrelated) repository. This will work since the files are the same, as you note.

So, to transfer your uncommitted changes from your old clone, you do

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

That will restore the information saved in the patch. This includes information about files that are added or renamed in the old clone.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文