防止“hg push”(没有分支名称或修订版)推送所有更改

use*_*740 1 version-control mercurial push

我发现(与其他一些实现不同),Mercurial 对它推送的内容过于热情 - 推送提交是不可编辑的提交。

我已经训练自己使用hg push -b branchawesomehg push -r awesomer。然而,有时我的手指会发出“哎呀”的声音,所有东西——包括临时的草稿工作——都会被推送到上游存储库。

是否有一种 Mercurial 方式可以hg push直接阻止或需要“强制”标志,如hg push --draft


我不想使用Secret Phases。不管我如何措辞这个问题,目标是帮助/鼓励其他人具体说明所推动的变化 -不会产生全新的概念。

Rei*_*nds 5

首先,请注意:默认情况下,Mercurial 不会让您在没有明确说明的情况下推送新的头/分支(您将收到一条错误消息,告诉您需要--new-branch-f实际推送您的更改)。只有当您在多个现有分支上提交时,才会发生意外推送超出预期的情况。

其次,简单(但有问题)的解决方案是使用别名进行推送,例如push = push -r .会更具限制性。但是,这会覆盖 push 命令,因此很难获得原始版本(例如,您可以通过 来rawpush = !$HG --config alias.push=push "$@"实现)。

最干净的方法是使用一个扩展来包装 push 命令并提供不同的默认值。例如:

from mercurial import extensions, commands

testedwith = "3.5"

default_push_rev = "."

# alternative choices

# Push the current revision, but only if it is a head
# default_push_rev = ". and head()"

# Push the current revisions and all revisions depending on it
# default_push_rev = "descendants(.)"

# Push the most recent head that follows the current revision
# default_push_rev = "last(descendants(.))"

# Push the tip revision (i.e. the chronologically most recent commit).
# default_push_rev = "tip"

# Push only public change sets
# default_push_rev = "public()"

def override_push(original_cmd, ui, repo, *pats, **opts):
  have_rev = False
  for opt in ["rev", "branch"]:
    if opts.has_key(opt) and opts[opt]:
      have_rev = True
  if not have_rev:
    opts["rev"] = [default_push_rev]
  return original_cmd(ui, repo, *pats, **opts)

def uisetup(ui):
  extensions.wrapcommand(commands.table, "push", override_push)
Run Code Online (Sandbox Code Playgroud)

与别名不同,如果没有明确提供,这只会更改要推送的默认修订。请注意,有多种选择可能有意义。上面的代码.默认设置为推送,但也有您可能更喜欢的替代方法。

还要注意的是,扩展不会覆盖hg outgoing命令,但是如果你愿意的话,可以很容易地通过复制完成的wrapcommand线,而代以"outgoing"用于"push"在重复的行。

要获得原始行为,只需使用hg push -r 'all()', 可能作为别名:

[alias]
push-all = push -r 'all()'
Run Code Online (Sandbox Code Playgroud)

编辑:修复了原始代码中忽略分支选项的错误。