Mercurial: ¿Incluir conjuntos de cambios secretos en el paquete?

Using Mercurial, how can I bundle all changesets not known to be in another repository, incluso secret changesets?

Sé que bundle's --base option happens to include secret changesets, but I don't want the --base behavior. (And it seems unusually weird that secret changesets are Siempre hay incluido con --base pero son nunca included without it. Shouldn't there be a separate option?)

FYI, I commonly want to make a backup of all changesets which are only in my local repo before attempting a potentially dangerous history rewrite.

preguntado el 09 de marzo de 12 a las 16:03

hg help phases - secret changesets are neither pushed, pulled, or cloned -

2 Respuestas

Tienes razón en eso 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 and parents(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} en lugar de $secret because Zsh doesn't do word splitting on parameter expansion by default.)

    It's important to chain the commands with ; en lugar de && since you'll want to reset the phases regardless of what happens in the hg bundle call — passing wrong parameters to hg 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
    

    El $@ is expanded by Mercurial before the alias is invoked and this lets you insert the necessary arguments for hg bundle.

Note that phase information cannot be stored in bundles — the bundle format has not been changed to accommodate it.

respondido 10 mar '12, 10:03

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].

respondido 14 nov., 14:23

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.