【问题标题】:Mercurial: Merging one file between branches in one repoMercurial:在一个仓库中的分支之间合并一个文件
【发布时间】:2010-11-07 21:51:41
【问题描述】:

当我在 Hg repo 中有两个分支时,如何只将一个文件与另一个分支合并,而不合并变更集中的所有其他文件?

是否可以只合并某些文件,而不是整个变更集?

【问题讨论】:

    标签: version-control mercurial dvcs branching-and-merging


    【解决方案1】:

    警告:这样的“虚拟合并”,就像recommended by @Martin_Geisler 一样,真的会搞砸你,如果以后你想对两个分支进行真正的合并。将记录虚拟合并,并说您合并到您进行虚拟合并的分支 - 您将看不到更改。或者,如果您合并到另一个分支,则该另一个分支上的更改将被撤消。

    如果您只想将整个文件从一个分支复制到另一个分支,您可以这样做:

       hg update -r to-branch
       hg revert -r from-branch file
       hg ci -m 'copied single file from from-branch to to-branch
    

    如果您想选择该文件的不同部分,那么"hg record" 很有用。

    我刚刚在我的主目录 .hgignore 上做了这个。

    如果两个分支都对您要保留的文件进行了更改,一个肮脏的技巧是使用 hg merge 创建两个分支的合并,可能/可能在另一个分支上,签入,然后复制合并和目标分支之间的单个文件:

       hg update -r to-branch
       branch merge-branch
       hg merge -r from-branch
       hg ci -m 'temp merge to be discarded"
       hg update -r to-branch
       hg revert -r merge-branch single-file
       hg ci -m 'merged single-file from from-branch to to-branch"
       hg strip merge-branch
    

    值得一提的是:“在分支之间复制单个文件”(或修订,或从修订到合并,或....)的方式是“hg revert”。即

       hg update -r Where-you-want-to-copy-to
       hg revert -r Where-you-want-to-copy-from file-you-want-to-copy
       ...
       hg ci
    

    出于某种原因,我和我的一些同事觉得这非常令人困惑。 "revert"=="copy" ... 对某些使用模式有意义,但不是全部。

    【讨论】:

    • 这应该是公认的答案,而不是 Martin Geisler 给出的答案。虽然它实际上不会合并文件,但复制它是大多数时间想要做的事情,它不会弄乱分支。
    • 这非常适合将单个文件从分支带到主干。然而,我注意到的一件事是,对主干的签入似乎没有出现在文件的历史记录中,这很不幸。
    • 您好,感谢您的回答。但是我遇到了麻烦,在我的情况下,我的源分支包含一个在我的默认分支中不存在的文件,但我想将其复制回来而不合并分支的其余部分。当我尝试按照您的描述进行操作时,我得到“rev 中没有这样的文件”有什么建议吗?
    • 所以我的问题的解决方法是手动复制文件然后运行复制命令,但我想知道是否有针对目标分支中不存在的新文件的解决方案?
    • @Brad_Oestreicher:是的,很遗憾,除了您提供的任何评论之外,Mercurial 历史中没有任何迹象表明发生了什么。例如。我依靠“hg glog”来获得漂亮的树形图。如果可以在复制文件的修订之间划一条线,那就太好了。 IE。跟踪部分合并和完全合并会很好。太多的 DVCS 具有“仅整个存储库”的观点。
    【解决方案2】:

    不。 Mercurial 在变更集的基础上工作。

    但是您可以执行“dummy merge”忽略来自其中一个分支的传入更改。在您提交之前,您可以将选定的文件恢复为您想要的任何状态:

    % HGMERGE=internal:local hg merge     # keep my files
    % hg revert --rev other-branch a.txt  # update a.txt to other branch
    % hg commit -m 'Dummy merge to pick a.txt from other-branch.'
    

    也许这会对你有所帮助。

    【讨论】:

    • 警告:如果以后你想对两个分支进行真正的合并,这样的“虚拟合并”真的会搞砸你。虚拟合并将被记录,并说您合并到您进行虚拟合并的分支 - 您将看不到更改。或者,如果您合并到另一个分支,则该另一个分支上的更改将被撤消。 // 如果你只想将整个文件从一个分支复制到另一个分支,你可以简单地“hg update -r to-branch; hg revert -r file” // 如果你想选择该文件的不同部分,那么“汞记录”很有用。 // 我刚刚在我的主目录.hgignore 上做了这个。
    • 一个肮脏的技巧是使用 hg merge 创建两个分支的合并,签入,然后使用“hg update -t​​ to”在合并和到分支之间复制一个文件-branch; branch merge-branch; hg merge -r from-branch; hg ci -m '临时合并被丢弃"; hg update -r 到分支; hg revert -r 合并分支单文件-u-want; hg ci -m '将单个文件从分支合并到分支"; hg strip merge-branch.
    • 哦,见鬼,我还不如把我的 cmets 变成一个真正的答案。
    【解决方案3】:

    我会使用像vimdiff 这样的外部工具来区分我想要合并的两个文件,然后合并它们。这样做的好处是您可以对文件的某些部分进行选择性编辑。例如:

    hg update -r branch-merging-to
    hg extdiff -p vimdiff -r branch-merging-from file-I-am-merging
    

    为此,您需要在 .hgrc 中启用外部工具,这意味着添加以下行:

    [extensions]
    hgext.extdiff =  
    

    【讨论】:

      【解决方案4】:

      获得所需结果的一种相当简洁的方法是分两步完成:首先使用graft,然后使用histedit

      说这是起点,你需要选择CD的某些部分在E之后“合并”:

      A---B---C---D
            \
             -E
      

      然后你将CD嫁接在E之上:

      A---B---C---D
            \
             -E--C'--D'
      

      然后使用hg histedit 编辑 C'D'。在编辑过程中,您可以进行任何您想要的更改,但在这种情况下,您只需还原任何不需要的文件(甚至是其中的一部分)。

      (请注意,histedit 编辑通过临时更新您的工作文件夹以匹配给定变更集的内容,就好像它尚未提交一样。因此您可以轻松恢复不需要的文件,然后hg histedit --continue 将有效地替换编辑变更集。)

      所以最终的结果是:

      A---B---C---D
            \
             -E--C''--D''
      

      '' 的修订已根据需要进行了修改。

      我会说,当您有较大的变更集时,这种方法更有益,而这些变更集最初可能应该是多个较小的提交;这种方法允许您仅“解开”您需要的部分。仅将其用于单个文件会很好,但可能会过大。

      【讨论】:

        猜你喜欢
        • 2019-03-10
        • 2023-01-13
        • 1970-01-01
        • 1970-01-01
        • 2017-03-12
        • 2023-02-08
        • 1970-01-01
        • 2018-12-22
        • 1970-01-01
        相关资源
        最近更新 更多