Mercurial : 번들에 비밀 변동 집합을 포함합니까?
-
10-12-2019 - |
문제
Mercurial을 사용하면 다른 리포지토리에있는 것으로 알려지지 않은 모든 변경 세트를 어떻게 묶을 수 있습니까? 비밀 변동 집합을 포함하여
bundle
의 --base
옵션이 비밀 변화를 포함하는 것으로 알고 있지만 --base
동작을 원하지 않습니다.(그리고 비밀 변화는 항상 항상 이지만 은 결코 포함되지 않고 이 포함되어 있지 않다는 것 같습니다. 별도의 옵션이 없어야합니까?)
fyi, 나는 일반적으로 잠재적으로 위험한 역사를 눌러 시도하기 전에 해당 로컬 Repo에만있는 모든 변경 세트를 백업하고 싶습니다.
해결책
You are correct that hg bundle
will normally exclude secret changesets. This is because it's just running the equivalent of hg outgoing
and bundling these changesets.
So some work-arounds:
If you know that you have at least one draft or public outgoing changeset as an ancestor of your secret changesets, then you can use
$ hg bundle --base "parents(outgoing())"
to get what you want. The
outgoing()
revset will pick the missing draft and public changesets andparents(outgoing()
will be suitable bases. Since you use--base
you get all descendants (public, draft, and secret) from these bases.You could temporarily make your secret changesets draft, bundle, and then mark them secret again:
$ secret=$(hg log --template "{rev} " -r "secret()"); \ hg phase -d $secret; \ hg bundle out.hg; \ hg phase -f -s $secret
(I use Zsh and there I had to use
${=secret}
instead of$secret
because Zsh doesn't do word splitting on parameter expansion by default.)It's important to chain the commands with
;
instead of&&
since you'll want to reset the phases regardless of what happens in thehg bundle
call — passing wrong parameters tohg bundle
should not mean that you lose all the information about the secret changesets. Note also that since secret changesets only have secret descendants, there's no information loss with this technique.You can turn this into a shell alias:
[alias] bundle-all = !secret=$(hg log --template "{rev} " -r "secret()"); hg phase -d $secret; hg bundle $@; hg phase -f -s $secret
The
$@
is expanded by Mercurial before the alias is invoked and this lets you insert the necessary arguments forhg bundle
.
Note that phase information cannot be stored in bundles — the bundle format has not been changed to accommodate it.
다른 팁
If you know there is at least one public changeset, you can use this:
hg bundle -r "not public()" --base public()
OTOH, that won't work if there are no public changesets, use this instead:
hg bundle -r "not public()" --base null
The problem with Martin's answer is that it relies on outgoing, which in turn relies on a direct connection to the push repo. If you don't always have an internet connection to that repo, these methods work well for me. It's also somewhat simpler than the phase dance.
One test for whether there are any public changesets is to capture the output of:
hg log -r public() -l 1 --template "{rev}"
and test its length, or the presence of [0-9].