【问题标题】:Perform an empty commit with mercurial使用 mercurial 执行空提交
【发布时间】:2022-04-14 20:40:21
【问题描述】:

使用 Mercurial 队列扩展,我可以使用一些提交消息进行空提交,如下所示:

hg qnew patch_name -m "message"

有没有办法在没有 Mercurial 队列的情况下做到这一点?我试过了:

hg commit -m "message"

但是 hg 只是说“没有改变”并且没有进行提交,而且我没有看到任何可以覆盖它的“强制”选项。

如果您想知道我这样做的动机:我们有测试基础架构,您可以在其中推送到一个特殊的存储库,它会触发自动化测试运行。您需要在最尖端提交的提交消息中放入一个特殊字符串,说明要运行哪些测试。显然,当我推送到实际存储库时,我不希望这个字符串在那里。与其修改提交两次(一次添加特殊字符串,第二次删除它),我会发现只添加一个空提交,然后将其回滚更简洁——我可以用 mq 做到这一点,但我想找到一种不用 mq 的方法。

【问题讨论】:

    标签: version-control mercurial commit mercurial-queue


    【解决方案1】:

    您可以使用hg commit --amend 创建空提交。

    只需创建一个任意提交并撤销更改。然后将两个提交折叠在一起。

    示例:

    touch tmp                               # create dummy file
    hg add tmp                              # add file and...
    hg commit -m "tmp"                      # ... commit
    hg rm tmp                               # remove the file again and ...
    hg commit --amend -m "empty commit"     # ... commit
    

    【讨论】:

    • 类似于hg commit --close-branch,这不会创建一个真正的空提交——它仍然会在变更集中留下一个标记并创建一个修改备份包。但是,我认为更好的是,它没有在打算保持打开状态时将分支标记为关闭的潜在混淆效果。
    • 如果您已经推送到远程存储库,这将不起作用
    • @matteo 为什么不呢?只要您不在两个 hg commit 命令之间插入就可以了。
    • @richard 同意!但是,如果您确实需要更频繁地创建别名,可以通过将以下内容放入您的 .hgrc 文件中:[alias] emptycommit = !touch tmp ; $HG add tmp ; $HG commit -m "<enter commit message>" ; $HG rm tmp ; $HG commit --amend "$@"
    • 改进@JosefEisl 别名[alias] emptycommit = !touch tmp ; $HG add tmp ; $HG commit tmp -m "<enter commit message>" ; $HG rm tmp ; $HG commit tmp --amend "$@" 提交应该针对我们的 tmp 文件,这样我们就不会提交更改(因此它始终是一个空提交)。
    【解决方案2】:

    您可以进行关闭分支的提交:

    hg commit --close-branch -m "message"
    

    更新:

    您可以关闭分支一次,但可以通过另一个提交重新打开它。在不更改文件的情况下重新打开分支的最简单方法是标记一些修订。所以你可以使用hg commit --close-branch 进行空提​​交,然后使用hg tag 重新打开。

    更新 v2

    实际上,您可以使用 hg tag 命令创建新的空提交。它具有用于设置提交消息的-m 参数。如果你不是很在意这个标签的正确性,你可以只使用一个标签名,通过调用hg tag-f 参数:

    hg tag t1 -f -m "message"
    

    【讨论】:

    • 这些操作不会因为分支关闭和标签创建事件而污染历史吗?
    • 关闭分支不会污染历史。它只会添加新的变更集。标签创建添加带有特定提交消息的新变更集,但您可以使用 -m 参数覆盖它。
    • 嘿,您实际上可以在不关闭分支的情况下创建新标签。如果您不关心标签而只关心提交消息,您甚至可以只使用一个标签并将其设置为-f 标志。因此,您可以使用 hg tag t1 -f -m "message" 创建空提交。
    • 关闭分支或添加标签不是真正的 empty 提交。
    【解决方案3】:

    您现在可以通过 hg ci -m "empty commit" 来创建空提交

    例如

    hg branch my-next-branch
    hg ci -m "empty commit"
    

    将创建一个my-next-branch,其中包含一个可以推送到远程仓库的空提交。

    【讨论】:

    • 我总是能够有一个“空”的提交,它只做一个分支。假设我已经对分支进行了七次提交,然后只想添加一条新的提交消息而不更改文件。 hg ci -m "empty commit" 应该在这种情况下工作吗?我试过了,但没有用。我不知道我只是有一个旧版本还是因为这个示例首先创建了一个分支,而在我描述的场景中我没有这样做。
    【解决方案4】:

    2015 年a patch to the mercurial-devel mailing list 建议在提交命令中添加一个选项,称为--allow-empty(很像the similar git option)。但是,it was decided 改为使用配置选项。

    这最终在 2015 年 7 月成为 added in Mercurial 3.5,名称为 ui.allowemptycommit。不必在用户或 repo 的配置文件中指定它,但是将--config 开关添加到单个命令就足够了,如下所示:

    hg ci -m "empty commit" --config ui.allowemptycommit=1
    

    此外,in 2020 it was suggestedhg rebase 扩展命令考虑另一个实验性配置选项的值。它被命名为rewrite.empty-successor,可以设置为skip(默认值)或keep。配置选项本身是在 2020 年 8 月用Mercurial 5.5 引入的,虽然我不确定rebase 扩展是什么时候开始考虑的。

    它的工作原理似乎是 rebase reads the new option 然后 locally overrides 较旧的 ui.allowemptycommit 选项取决于 rewrite.empty-successor 是配置为 skip 还是 keep。结果是旧 Mercurial 版本的 rebase 扩展直接观察到 ui.allowemptycommit=1 选项(版本 4.8.2 测试),而新版本的扩展观察 rewrite.empty-successor=keep 代替(版本 6.1 测试)。较新的版本会忽略ui.allowemptycommit 配置的外部状态。

    因此,要让hg rebase 保留一些可移植的空变更集,可以设置两个选项以保留它们,如下例所示:

    hg rebase --config rewrite.empty-successor=keep --config ui.allowemptycommit=1 ...
    

    我所有这一切的用例是在 svn 存储库上使用 hg convert,然后使用空的 hg commit 成为初始提交(本地变更集编号 0)。然后我将首先使用hg rebase 使即将成为变更集 0 成为第一个导入的 svn 修订版的父级(因此它将成为本地变更集编号 1,与 svn 修订版号匹配),然后修复某些问题提交 hg convert 解析不正确。对我而言,hg rebase 命令应保留空提交对我来说至关重要,例如基于 svn 修订版的那些仅更改目录的提交。 (Mercurial 永远不会单独跟踪目录,只跟踪文件。)

    【讨论】:

    【解决方案5】:

    我刚刚发现 hg graft . --force --edit 可以很好地用于此目的。

    这将强制嫁接当前签出的提交,因此它将为空,并且会打开一个编辑器来输入提交消息。

    【讨论】:

      猜你喜欢
      • 2013-04-30
      • 1970-01-01
      • 1970-01-01
      • 2011-03-09
      • 2011-04-03
      • 2011-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多