【问题标题】:Can you close a Mercurial branch without updating to it first?你可以关闭 Mercurial 分支而不先更新它吗?
【发布时间】:2014-04-16 23:46:29
【问题描述】:

我知道您可以通过以下方式关闭 Mercurial 分支:

hg update rev-number
hg commit --close-branch -m "Closing branch."

但是,我使用的一些存储库相当大,并且在发现多年前我想关闭的松散分支后,首先更新到它可能需要几分钟(如果不是几小时),只能进行一次提交然后更新回我正在使用的原始版本(如果不是几小时,则需要更多分钟)。

所以我的问题是,有什么方法可以在不先将工作目录更新到分支修订版的情况下关闭 Mercurial 分支?

【问题讨论】:

    标签: mercurial branch


    【解决方案1】:

    是的,您可以,但这在任何地方都没有记录。这个技术我用了很久了,不用担心,很安全。

    您可以发出以下命令,而不是更新

    hg debugsetparent <revision>
    hg branch <branchOfRevision>
    

    请注意,顺序很重要。这将使您的 repo 认为它在新版本上,而您的所有文件都来自最初的版本。之后,您可以使用--close-branch 提交,但使用-X * 选项进行空提交。

    hg commit --close-branch -X * -m "Closing branch."
    

    现在,只要回到你之前的头脑,就像什么都没发生一样。

    hg debugsetparent <InitialRevision>
    hg branch <branchOfInitialRevision>
    

    最后,如果您有子存储库,您可能希望在提交 --close-branch 之前暂时重命名 .hgsub 文件,然后再重命名。

    【讨论】:

    • 聪明!作为一名 Mercurial 开发人员,我认为这种技术是正确的。
    • @MartinGeisler 谢谢!当然,这是在脚本中使用的,如果它在任何步骤中失败,它会自动恢复到初始状态。我问你,你觉得写完之前应该发debugrebuildstate吗?
    • 看起来没有必要。 debugrebuilddirstate 清除强制 Mercurial 将磁盘上的文件与其内部表示进行比较的目录状态。由于您更新回开始的位置,因此 dirstate 将是正确的。
    • @Vince,谢谢!事实证明这比我想象的要复杂(我希望有一个单行,或现有的常用 Mercurial 命令的附加选项),所以非常感谢你弄清楚......这肯定会节省时间.
    • -X * 不能正常处理子存储库。我将它与this method of creating an empty commit 结合在一个脚本中以自动化该过程。
    【解决方案2】:

    Mercurial 4.8 及更高版本附带提供此功能的核心扩展 closehead

    hg close-head <revision>
    

    来自帮助:

    这相当于检查干净树中的每个修订并运行“hg commit --close-branch”,只是它不会更改工作目录。

    目前您需要在 hgrc 中明确启用此扩展:

    [extensions]
    closehead =
    

    【讨论】:

    • 太棒了!这看起来比公认的答案更容易,如果您拥有 Mercurial 4.8+,这可能应该是这样做的方法。
    【解决方案3】:

    感谢文斯的方法。我已经将它实现为 Python 脚本 - 它比我最初预期的要多一些工作,所以希望这会节省其他人一些时间。在 Windows 8.1 上使用 TortoiseHg 3.3 和 Python 2.7.9 进行测试。

    欢迎提供反馈,它可能需要一些技巧,尤其是在错误处理方面。

    #!/usr/bin/python
    
    from subprocess import check_output
    
    def close_branch( branch, message ):
        if not message:
            message = 'Closing branch "{}"'.format( branch )
        print( 'Closing branch "{}"'.format( branch ) )
        try:
            check_output( 'hg debugsetparent ' + branch )
            check_output( 'hg branch ' + branch )
            check_output( 'hg commit --close-branch -X * -m "' + message + '"' )
        except:
            print( 'Failed to close branch.' )
    
    def main():
        import argparse
        parser = argparse.ArgumentParser()
        parser.add_argument('branch', help='branch name(s)', nargs = '+' )
        parser.add_argument('-m', '--message', help='message (defaults to "Closing branch <branch name>")' )
        args = parser.parse_args()
    
        status = check_output( 'hg status' )
        if len(status) > 0:
            print( 'Do not use this script with local changes. Commit/revert changes and try again' )
            exit(1)
    
        # Cache initial revision and branch.
        initial_revision = check_output( 'hg id -i -b' ).split()
        # print( 'Using: ' + initial_revision[0].decode("utf-8") )
    
        for branch in args.branch:
            close_branch( branch, args.message )
    
        # Return to original changeset
        check_output( 'hg debugsetparent ' + initial_revision[0].decode("utf-8") )
        check_output( 'hg branch ' + initial_revision[1].decode("utf-8") )
    
    if __name__ == '__main__':
        main()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-10
      • 2013-02-23
      相关资源
      最近更新 更多