[PATCH 4 of 4 NEW-CONCEPT] track-tags: write all tag changes to a file

Augie Fackler raf at durin42.com
Mon Apr 3 20:50:05 UTC 2017


On Thu, Mar 30, 2017 at 05:03:42PM +0200, Pierre-Yves David wrote:
> # HG changeset patch
> # User Pierre-Yves David <pierre-yves.david at ens-lyon.org>
> # Date 1490688902 -7200
> #      Tue Mar 28 10:15:02 2017 +0200
> # Node ID 46005886092380991a30c2a02486c2876ecac341
> # Parent  2dcaa99d6160561166269f192a89b25f84fd4667
> # EXP-Topic tags
> # Available At https://www.mercurial-scm.org/repo/users/marmoute/mercurial/
> #              hg pull https://www.mercurial-scm.org/repo/users/marmoute/mercurial/ -r 460058860923
> track-tags: write all tag changes to a file

Overall, the feature seems reasonable, and having the hook information
seems right. Should this be integrated with the journal code somehow?

>
> The tag changes information we compute are not written to disk. This gives
> hooks full acces to that data.
>
> The format picked for that file use a 2 characters prefix for the action:
>
>     -R: tag removed
>     +A: tag added
>     -M: tag moved (old value)
>     +M: tag moved (new value)
>
> This format allows hooks to easily select the line that matters to them without
> having to post process the file too much. Here is
> a couple of example:
>
>  * to select all newly tagged changeset, match "^+",
>  * to detect tag move, match "^.M",
>  * to detect tag deletion, match "-R".
>
> Once again we rely on the fact the tag tests run through all possible
> situations to test this change.
>
> diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
> --- a/mercurial/localrepo.py
> +++ b/mercurial/localrepo.py
> @@ -1015,6 +1015,25 @@ class localrepository(object):
>          # and do not use caches as much as it could.  The current focus is on
>          # the behavior of the feature so we disable it by default. The flag
>          # will be removed when we are happy with the performance impact.
> +        #
> +        # Once this feature is no longer experimental move the following
> +        # documentation to the appropriate help section:
> +        #
> +        # The ``HG_TAG_MOVED`` variable will be set if the transaction touched
> +        # tags (new or changed or deleted tags). In addition the details of
> +        # these changes are made available in a file at:
> +        #     ``REPOROOT/.hg/changes/tags.changes``.
> +        # Make sure you check for HG_TAG_MOVED before reading that file as it
> +        # might exist from a previous transaction even if no tag were touched
> +        # in this one. Change are recorded in a line base format::
> +        #
> +        #     <action> <hex-node> <tag-name>\n
> +        #
> +        # Actions are defined as follow:
> +        #   "-R": tag is removed,
> +        #   "+A": tag is added,
> +        #   "-M": tag is moved (old value),
> +        #   "+M": tag is moved (new value),
>          tracktags = lambda x: None
>          # experimental config: experimental.hook-track-tags
>          shouldtracktags = self.ui.configbool('experimental', 'hook-track-tags',
> @@ -1031,6 +1050,12 @@ class localrepository(object):
>                  changes = tagsmod.difftags(repo.ui, repo, oldfnodes, newfnodes)
>                  if changes:
>                      tr2.hookargs['tag_moved'] = '1'
> +                    with repo.vfs('changes/tags.changes', 'w',
> +                                  atomictemp=True) as changesfile:
> +                        # note: we do not register the file to the transaction
> +                        # because we needs it to still exist on the transaction
> +                        # is close (for txnclose hooks)
> +                        tagsmod.writediff(changesfile, changes)
>          def validate(tr2):
>              """will run pre-closing hooks"""
>              # XXX the transaction API is a bit lacking here so we take a hacky
> diff --git a/mercurial/tags.py b/mercurial/tags.py
> --- a/mercurial/tags.py
> +++ b/mercurial/tags.py
> @@ -129,6 +129,44 @@ def difftags(ui, repo, oldfnodes, newfno
>      entries.sort()
>      return entries
>
> +def writediff(fp, difflist):
> +    """write tags diff information to a file.
> +
> +    Data are stored with a line based format:
> +
> +        <action> <hex-node> <tag-name>\n
> +
> +    Action are defined as follow:
> +       -R tag is removed,
> +       +A tag is added,
> +       -M tag is moved (old value),
> +       +M tag is moved (new value),
> +
> +    Example:
> +
> +         +A 875517b4806a848f942811a315a5bce30804ae85 t5
> +
> +    See documentation of difftags output for details about the input.
> +    """
> +    add = '+A %s %s\n'
> +    remove = '-R %s %s\n'
> +    updateold = '-M %s %s\n'
> +    updatenew = '+M %s %s\n'
> +    for tag, old, new in difflist:
> +        # translate to hex
> +        if old is not None:
> +            old = hex(old)
> +        if new is not None:
> +            new = hex(new)
> +        # write to file
> +        if old is None:
> +            fp.write(add % (new, tag))
> +        elif new is None:
> +            fp.write(remove % (old, tag))
> +        else:
> +            fp.write(updateold % (old, tag))
> +            fp.write(updatenew % (new, tag))
> +
>  def findglobaltags(ui, repo):
>      '''Find global tags in a repo: return a tagsmap
>
> diff --git a/tests/test-tag.t b/tests/test-tag.t
> --- a/tests/test-tag.t
> +++ b/tests/test-tag.t
> @@ -11,6 +11,7 @@
>    > # file...
>    > if [ -n "\$HG_TAG_MOVED" ]; then
>    >     echo 'hook: tag changes detected'
> +  >     sed 's/^/hook: /' .hg/changes/tags.changes
>    > fi
>    > EOF
>    $ chmod +x taghook.sh
> @@ -37,6 +38,7 @@ specified)
>
>    $ HGEDITOR=cat hg tag "bleah"
>    hook: tag changes detected
> +  hook: +A acb14030fe0a21b60322c440ad2d20cf7685a376 bleah
>    $ hg history
>    changeset:   1:d4f0d2909abc
>    tag:         tip
> @@ -86,13 +88,21 @@ specified)
>
>    $ hg tag -r 0 "bleah0"
>    hook: tag changes detected
> +  hook: +A acb14030fe0a21b60322c440ad2d20cf7685a376 bleah0
>    $ hg tag -l -r 1 "bleah1"
>    $ hg tag gack gawk gorp
>    hook: tag changes detected
> +  hook: +A 336fccc858a4eb69609a291105009e484a6b6b8d gack
> +  hook: +A 336fccc858a4eb69609a291105009e484a6b6b8d gawk
> +  hook: +A 336fccc858a4eb69609a291105009e484a6b6b8d gorp
>    $ hg tag -f gack
>    hook: tag changes detected
> +  hook: -M 336fccc858a4eb69609a291105009e484a6b6b8d gack
> +  hook: +M 799667b6f2d9b957f73fa644a918c2df22bab58f gack
>    $ hg tag --remove gack gorp
>    hook: tag changes detected
> +  hook: -R 799667b6f2d9b957f73fa644a918c2df22bab58f gack
> +  hook: -R 336fccc858a4eb69609a291105009e484a6b6b8d gorp
>
>    $ hg tag "bleah "
>    abort: tag 'bleah' already exists (use -f to force)
> @@ -105,8 +115,10 @@ specified)
>    [255]
>    $ hg tag -r 0 "  bleahbleah  "
>    hook: tag changes detected
> +  hook: +A acb14030fe0a21b60322c440ad2d20cf7685a376 bleahbleah
>    $ hg tag -r 0 " bleah bleah "
>    hook: tag changes detected
> +  hook: +A acb14030fe0a21b60322c440ad2d20cf7685a376 bleah bleah
>
>    $ cat .hgtags
>    acb14030fe0a21b60322c440ad2d20cf7685a376 bleah
> @@ -136,6 +148,7 @@ tagging on a non-head revision
>    [255]
>    $ hg tag -f "foobar"
>    hook: tag changes detected
> +  hook: +A acb14030fe0a21b60322c440ad2d20cf7685a376 foobar
>    $ cat .hgtags
>    acb14030fe0a21b60322c440ad2d20cf7685a376 foobar
>    $ cat .hg/localtags
> @@ -194,18 +207,23 @@ cloning local tags
>
>    $ hg clone -q -rbleah1 test test1
>    hook: tag changes detected
> +  hook: +A acb14030fe0a21b60322c440ad2d20cf7685a376 bleah
>    $ hg -R test1 parents --style=compact
>    1[tip]   d4f0d2909abc   1970-01-01 00:00 +0000   test
>      Added tag bleah for changeset acb14030fe0a
>
>    $ hg clone -q -r5 test#bleah1 test2
>    hook: tag changes detected
> +  hook: +A acb14030fe0a21b60322c440ad2d20cf7685a376 bleah
> +  hook: +A acb14030fe0a21b60322c440ad2d20cf7685a376 bleah0
> +  hook: +A 336fccc858a4eb69609a291105009e484a6b6b8d gawk
>    $ hg -R test2 parents --style=compact
>    5[tip]   b4bb47aaff09   1970-01-01 00:00 +0000   test
>      Removed tag gack, gorp
>
>    $ hg clone -q -U test#bleah1 test3
>    hook: tag changes detected
> +  hook: +A acb14030fe0a21b60322c440ad2d20cf7685a376 bleah
>    $ hg -R test3 parents --style=compact
>
>    $ cd test
> @@ -234,6 +252,7 @@ doesn't end with EOL
>    acb14030fe0a21b60322c440ad2d20cf7685a376 foobar
>    $ hg tag newline
>    hook: tag changes detected
> +  hook: +A a0eea09de1eeec777b46f2085260a373b2fbc293 newline
>    $ cat .hgtags; echo
>    acb14030fe0a21b60322c440ad2d20cf7685a376 foobar
>    a0eea09de1eeec777b46f2085260a373b2fbc293 newline
> @@ -248,6 +267,7 @@ tag and branch using same name
>    $ hg tag tag-and-branch-same-name
>    warning: tag tag-and-branch-same-name conflicts with existing branch name
>    hook: tag changes detected
> +  hook: +A fc93d2ea1cd78e91216c6cfbbf26747c10ce11ae tag-and-branch-same-name
>
>  test custom commit messages
>
> @@ -333,6 +353,7 @@ then, test custom commit message itself
>    HG: changed .hgtags
>    ====
>    hook: tag changes detected
> +  hook: +A 75a534207be6b03576e0c7a4fa5708d045f1c876 custom-tag
>    $ hg log -l1 --template "{desc}\n"
>    custom tag message
>    second line
> @@ -342,6 +363,7 @@ local tag with .hgtags modified
>
>    $ hg tag hgtags-modified
>    hook: tag changes detected
> +  hook: +A 0f26aaea6f74c3ed6c4aad8844403c9ba128d23a hgtags-modified
>    $ hg rollback
>    repository tip rolled back to revision 13 (undo commit)
>    working directory now based on revision 13
> @@ -362,10 +384,16 @@ tagging when at named-branch-head that's
>    (branch merge, don't forget to commit)
>    $ hg ci -m 'merge named branch'
>    hook: tag changes detected
> +  hook: -R acb14030fe0a21b60322c440ad2d20cf7685a376 bleah
> +  hook: -R acb14030fe0a21b60322c440ad2d20cf7685a376 bleah bleah
> +  hook: -R acb14030fe0a21b60322c440ad2d20cf7685a376 bleah0
> +  hook: -R acb14030fe0a21b60322c440ad2d20cf7685a376 bleahbleah
> +  hook: -R 336fccc858a4eb69609a291105009e484a6b6b8d gawk
>    $ hg up 13
>    1 files updated, 0 files merged, 0 files removed, 0 files unresolved
>    $ hg tag new-topo-head
>    hook: tag changes detected
> +  hook: +A 0f26aaea6f74c3ed6c4aad8844403c9ba128d23a new-topo-head
>
>  tagging on null rev
>
> @@ -433,6 +461,7 @@ commit hook on tag used to be run withou
>    > EOF
>    $ hg -R repo-tag --config hooks.commit="sh ../issue3344.sh" tag tag
>    hook: tag changes detected
> +  hook: +A be090ea6625635128e90f7d89df8beeb2bcc1653 tag
>    pushing to $TESTTMP/repo-tag-target (glob)
>    searching for changes
>    adding changesets
> @@ -440,6 +469,7 @@ commit hook on tag used to be run withou
>    adding file changes
>    added 2 changesets with 2 changes to 2 files
>    hook: tag changes detected
> +  hook: +A be090ea6625635128e90f7d89df8beeb2bcc1653 tag
>
>  automatically merge resolvable tag conflicts (i.e. tags that differ in rank)
>  create two clones with some different tags as well as some common tags
> @@ -452,6 +482,7 @@ check that we can merge tags that differ
>    adding f0
>    $ hg tag tbase
>    hook: tag changes detected
> +  hook: +A 6cee5c8f3e5b4ae1a3996d2f6489c3e08eb5aea7 tbase
>    $ hg up -qr '.^'
>    $ hg log -r 'wdir()' -T "{latesttagdistance}\n"
>    1
> @@ -468,15 +499,22 @@ check that we can merge tags that differ
>    adding f1
>    $ hg tag t1 t2 t3
>    hook: tag changes detected
> +  hook: +A 4f3e9b90005b68b4d8a3f4355cedc302a8364f5c t1
> +  hook: +A 4f3e9b90005b68b4d8a3f4355cedc302a8364f5c t2
> +  hook: +A 4f3e9b90005b68b4d8a3f4355cedc302a8364f5c t3
>    $ hg tag --remove t2
>    hook: tag changes detected
> +  hook: -R 4f3e9b90005b68b4d8a3f4355cedc302a8364f5c t2
>    $ hg tag t5
>    hook: tag changes detected
> +  hook: +A 875517b4806a848f942811a315a5bce30804ae85 t5
>    $ echo c2 > f2
>    $ hg ci -A -m2
>    adding f2
>    $ hg tag -f t3
>    hook: tag changes detected
> +  hook: -M 4f3e9b90005b68b4d8a3f4355cedc302a8364f5c t3
> +  hook: +M 79505d5360b07e3e79d1052e347e73c02b8afa5b t3
>
>    $ cd ../repo-automatic-tag-merge
>    $ echo c3 > f3
> @@ -484,6 +522,9 @@ check that we can merge tags that differ
>    adding f3
>    $ hg tag -f t4 t5 t6
>    hook: tag changes detected
> +  hook: +A 9aa4e1292a27a248f8d07339bed9931d54907be7 t4
> +  hook: +A 9aa4e1292a27a248f8d07339bed9931d54907be7 t5
> +  hook: +A 9aa4e1292a27a248f8d07339bed9931d54907be7 t6
>
>    $ hg up -q '.^'
>    $ hg log -r 'wdir()' -T "{changessincelatesttag} changes since {latesttag}\n"
> @@ -497,6 +538,7 @@ check that we can merge tags that differ
>
>    $ hg tag --remove t5
>    hook: tag changes detected
> +  hook: -R 9aa4e1292a27a248f8d07339bed9931d54907be7 t5
>    $ echo c4 > f4
>    $ hg log -r '.' -T "{changessincelatesttag} changes since {latesttag}\n"
>    2 changes since t4:t6
> @@ -516,8 +558,11 @@ check that we can merge tags that differ
>    4 changes since t4:t6
>    $ hg tag t2
>    hook: tag changes detected
> +  hook: +A 929bca7b18d067cbf3844c3896319a940059d748 t2
>    $ hg tag -f t6
>    hook: tag changes detected
> +  hook: -M 9aa4e1292a27a248f8d07339bed9931d54907be7 t6
> +  hook: +M 09af2ce14077a94effef208b49a718f4836d4338 t6
>
>    $ cd ../repo-automatic-tag-merge-clone
>    $ hg pull
> @@ -528,6 +573,10 @@ check that we can merge tags that differ
>    adding file changes
>    added 6 changesets with 6 changes to 3 files (+1 heads)
>    hook: tag changes detected
> +  hook: +A 929bca7b18d067cbf3844c3896319a940059d748 t2
> +  hook: +A 9aa4e1292a27a248f8d07339bed9931d54907be7 t4
> +  hook: -R 875517b4806a848f942811a315a5bce30804ae85 t5
> +  hook: +A 09af2ce14077a94effef208b49a718f4836d4338 t6
>    (run 'hg heads' to see heads, 'hg merge' to merge)
>    $ hg merge --tool internal:tagmerge
>    merging .hgtags
> @@ -589,11 +638,16 @@ detect merge tag conflicts
>    3 files updated, 0 files merged, 2 files removed, 0 files unresolved
>    $ hg tag t7
>    hook: tag changes detected
> +  hook: +A b325cc5b642c5b465bdbe8c09627cb372de3d47d t7
>    $ hg update -C -r 'first(sort(head()))'
>    3 files updated, 0 files merged, 2 files removed, 0 files unresolved
>    $ printf "%s %s\n" `hg log -r . --template "{node} t7"` >> .hgtags
>    $ hg commit -m "manually add conflicting t7 tag"
>    hook: tag changes detected
> +  hook: -R 929bca7b18d067cbf3844c3896319a940059d748 t2
> +  hook: +A 875517b4806a848f942811a315a5bce30804ae85 t5
> +  hook: -M b325cc5b642c5b465bdbe8c09627cb372de3d47d t7
> +  hook: +M ea918d56be86a4afc5a95312e8b6750e1428d9d2 t7
>    $ hg merge --tool internal:tagmerge
>    merging .hgtags
>    automatic .hgtags merge failed
> @@ -629,6 +683,8 @@ handle the loss of tags
>    adding f5
>    $ hg tag -f t7
>    hook: tag changes detected
> +  hook: -M ea918d56be86a4afc5a95312e8b6750e1428d9d2 t7
> +  hook: +M fd3a9e394ce3afb354a496323bf68ac1755a30de t7
>    $ hg update -r 'p1(t7)'
>    1 files updated, 0 files merged, 1 files removed, 0 files unresolved
>    $ printf '' > .hgtags
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


More information about the Mercurial-devel mailing list