changeset 760:eb9ebc7ed061

git_handler: store hg extra data in git deterministically by sorting it Previously, we'd iterate over the extra elements in arbitrary order. We now sort the elements and store them in deterministic order. Without sorting, the included test fails half the time.
author Siddharth Agarwal <sid0@fb.com>
date Sun, 31 Aug 2014 05:13:39 -0700
parents 1d16139b8e50
children ba42476afeda
files hggit/git_handler.py tests/commitextra.py tests/test-extra.t tests/testutil
diffstat 4 files changed, 65 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/hggit/git_handler.py
+++ b/hggit/git_handler.py
@@ -586,7 +586,9 @@
             for oldfile, newfile in renames:
                 extra_message += "rename : " + oldfile + " => " + newfile + "\n"
 
-        for key, value in extra.iteritems():
+        extraitems = extra.items()
+        extraitems.sort()
+        for key, value in extraitems:
             if key in ('author', 'committer', 'encoding', 'message', 'branch', 'hg-git'):
                 continue
             else:
new file mode 100644
--- /dev/null
+++ b/tests/commitextra.py
@@ -0,0 +1,24 @@
+'''test helper extension to create commits with multiple extra fields'''
+
+from mercurial import cmdutil, commands, scmutil
+
+cmdtable = {}
+command = cmdutil.command(cmdtable)
+testedwith = 'internal'
+
+@command('commitextra',
+         [('', 'field', [],
+           'extra data to store', 'FIELD=VALUE'),
+         ] + commands.commitopts + commands.commitopts2,
+         'commitextra')
+def commitextra(ui, repo, *pats, **opts):
+    '''make a commit with extra fields'''
+    fields = opts.get('field')
+    extras = {}
+    for field in fields:
+        k, v = field.split('=', 1)
+        extras[k] = v
+    message = cmdutil.logmessage(ui, opts)
+    repo.commit(message, opts.get('user'), opts.get('date'),
+                match=scmutil.match(repo[None], pats, opts), extra=extras)
+    return 0
--- a/tests/test-extra.t
+++ b/tests/test-extra.t
@@ -26,8 +26,18 @@
   saved backup bundle to $TESTTMP/*.hg (glob)
   $ hg up 2
   1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+
+Add a commit with multiple extra fields
+  $ touch d
+  $ hg add d
+  $ fn_hg_commitextra --field zzzzzzz=datazzz --field aaaaaaa=dataaaa
   $ hg log --graph --template "{rev} {node} {desc|firstline}\n{join(extras, '\n')}\n\n"
-  @  2 dcec77c6ae3cff594c4435e5820bec4ec9e57440 b
+  @  3 f15e01c73845392d86a5ed10fb0753d09bca13d3
+  |  aaaaaaa=dataaaa
+  |  branch=default
+  |  zzzzzzz=datazzz
+  |
+  o  2 dcec77c6ae3cff594c4435e5820bec4ec9e57440 b
   |  branch=default
   |  rebase_source=bb8ddb1031b5d9afd7caa5aa9d24c735222e3636
   |
@@ -43,15 +53,32 @@
   pushing to $TESTTMP/gitrepo
   searching for changes
   adding objects
-  added 2 commits with 2 trees and 0 blobs
+  added 3 commits with 3 trees and 0 blobs
   adding reference refs/heads/b1
-  updating reference refs/heads/master
+
+  $ cd ../gitrepo
+  $ git cat-file commit b1
+  tree 1b773a2eb70f29397356f8069c285394835ff85a
+  parent 99316cce06b9b5aa9e5a3f4df124939583791dda
+  author test <none@none> 1167609613 +0000
+  committer test <none@none> 1167609613 +0000
+  
+  
+  
+  --HG--
+  extra : aaaaaaa : dataaaa
+  extra : zzzzzzz : datazzz
 
   $ cd ..
   $ hg clone -q gitrepo hgrepo2
   $ cd hgrepo2
   $ hg log --graph --template "{rev} {node} {desc|firstline}\n{join(extras, '\n')}\n\n"
-  @  2 dcec77c6ae3cff594c4435e5820bec4ec9e57440 b
+  @  3 f15e01c73845392d86a5ed10fb0753d09bca13d3
+  |  aaaaaaa=dataaaa
+  |  branch=default
+  |  zzzzzzz=datazzz
+  |
+  o  2 dcec77c6ae3cff594c4435e5820bec4ec9e57440 b
   |  branch=default
   |  rebase_source=bb8ddb1031b5d9afd7caa5aa9d24c735222e3636
   |
--- a/tests/testutil
+++ b/tests/testutil
@@ -43,6 +43,13 @@
     count=`expr $count + 1`
 }
 
+fn_hg_commitextra() {
+    HGDATE="2007-01-01 00:00:$count +0000"
+    hg --config extensions.commitextra=$TESTDIR/commitextra.py commitextra \
+        -d "$HGDATE" "$@" >/dev/null || echo "hg commit error"
+    count=`expr $count + 1`
+}
+
 fn_git_tag() {
     GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000"
     GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"