防止 'hg push'(没有分支名称或修订版)推送所有更改
Prevent 'hg push' (without branch name or revision) from pushing all changes
我发现(与其他一些实现不同),Mercurial 过于热衷于它推送的内容 - 推送的提交是不可编辑的提交。
我已经训练自己使用 hg push -b branchawesome
或 hg push -r awesomer
。然而,有时我的手指会做一个 "oops" 并且所有内容 - 包括临时草稿工作 - 都会被推送到上游存储库。
是否有一种 Mercurial 方法可以完全阻止 hg push
或需要一个 "force" 标志,如 hg push --draft
?
我不想使用 Secret Phases。不管我如何措辞这个问题,目标是 help/encourage 其他人具体说明推动了哪些更改 - 而不会 产生一个全新的概念。
首先,请注意:默认情况下,Mercurial 不会让您在没有明确说明的情况下推送新的 head/branch(您会收到一条错误消息,告诉您需要 --new-branch
或 -f
实际推送您的更改)。仅当您在多个现有分支上提交时,才会意外地推送超出预期的内容。
其次,简单(但有问题)的解决方案是为推送使用别名,例如push = push -r .
会更加严格。但是,这会覆盖推送命令,因此很难获得原始版本(例如,您可以通过 rawpush = !$HG --config alias.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)
与别名不同,如果明确提供 none,这只会更改要推送的默认修订。请注意,有多个可能有意义的选择。上面的代码默认设置为推送 .
,但您可能更喜欢其他选择。
另请注意,扩展不会覆盖 hg outgoing
命令,但如果您愿意,可以通过复制 wrapcommand
行并将 "outgoing"
替换为 "push"
在重复行中。
要获得原始行为,只需使用 hg push -r 'all()'
,可能作为别名:
[alias]
push-all = push -r 'all()'
编辑:修复了原始代码中忽略分支选项的错误。
我发现(与其他一些实现不同),Mercurial 过于热衷于它推送的内容 - 推送的提交是不可编辑的提交。
我已经训练自己使用 hg push -b branchawesome
或 hg push -r awesomer
。然而,有时我的手指会做一个 "oops" 并且所有内容 - 包括临时草稿工作 - 都会被推送到上游存储库。
是否有一种 Mercurial 方法可以完全阻止 hg push
或需要一个 "force" 标志,如 hg push --draft
?
我不想使用 Secret Phases。不管我如何措辞这个问题,目标是 help/encourage 其他人具体说明推动了哪些更改 - 而不会 产生一个全新的概念。
首先,请注意:默认情况下,Mercurial 不会让您在没有明确说明的情况下推送新的 head/branch(您会收到一条错误消息,告诉您需要 --new-branch
或 -f
实际推送您的更改)。仅当您在多个现有分支上提交时,才会意外地推送超出预期的内容。
其次,简单(但有问题)的解决方案是为推送使用别名,例如push = push -r .
会更加严格。但是,这会覆盖推送命令,因此很难获得原始版本(例如,您可以通过 rawpush = !$HG --config alias.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)
与别名不同,如果明确提供 none,这只会更改要推送的默认修订。请注意,有多个可能有意义的选择。上面的代码默认设置为推送 .
,但您可能更喜欢其他选择。
另请注意,扩展不会覆盖 hg outgoing
命令,但如果您愿意,可以通过复制 wrapcommand
行并将 "outgoing"
替换为 "push"
在重复行中。
要获得原始行为,只需使用 hg push -r 'all()'
,可能作为别名:
[alias]
push-all = push -r 'all()'
编辑:修复了原始代码中忽略分支选项的错误。