changeset 866:a3b12aa1bcd6

git_handler: don't store rename source if branch info is stored Consider a Mercurial commit with hash 'h1'. Originally, if the only Mercurial field stored is the branch info (which is stored in the commit message rather than as an extra field), we'd store the rename source explicitly as a Git extra field -- let's call the original exported hash 'g1'. In Git, some operations throw all extra fields away. (One such example is a rebase.) If such an operation happens, we'll be left with a frankencommit with the branch info but without the rename source. Let's call this hash 'g2'. For a setup where Git is the source of truth, let's say that this 'g2' frankencommit is what gets pushed to the server. When 'g2' is subsequently imported into Mercurial, we'd look at the fact that it contains a Mercurial field in the commit message and believe that it was a legacy commit from the olden days when all info was stored in the commit message. In that case, in an attempt to preserve the hash, we wouldn't store any extra rename source info, resulting in 'h1'. Then, when the commit is re-exported to Git, we'd add the rename source again and produce 'g1' -- and thus break bidirectionality. Prevent this situation by not storing the rename source if we're adding branch info to the commit message. Then for 'h1' we export as 'g2' directly and never produce 'g1'. What happens if we not only need to store branch info but also other extra info, like renames? For 'h1' we'd produce 'g1', then it'd be rewritten on the Git side to 'g2' throwing away all that extra information. 'g2' being subsequently imported into Mercurial would produce a new hash, say 'h2'. That's fine because the commit did get rewritten in Git. We unfortunately wouldn't perform rename detection thinking that the commit is from Mercurial and had no renames recorded there, but when the commit is re-exported to Git we'd export it to 'g2' again. This at least preserves bidirectionality.
author Siddharth Agarwal <sid0@fb.com>
date Thu, 26 Feb 2015 22:14:44 -0800
parents 3004fd28a8c5
children 82467d4c4db8
files hggit/git_handler.py tests/test-branch-bookmark-suffix.t
diffstat 2 files changed, 11 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/hggit/git_handler.py	Thu Feb 26 18:00:36 2015 -0800
+++ b/hggit/git_handler.py	Thu Feb 26 22:14:44 2015 -0800
@@ -659,7 +659,7 @@
             message += "\n--HG--\n" + extra_message
 
         if (extra.get('hg-git-rename-source', None) != 'git'
-            and not extra_in_message and not git_extra):
+            and not extra_in_message and not git_extra and extra_message == ''):
             # We need to store this if no other metadata is stored. This
             # indicates that when reimporting the commit into Mercurial we'll
             # know not to detect renames.
--- a/tests/test-branch-bookmark-suffix.t	Thu Feb 26 18:00:36 2015 -0800
+++ b/tests/test-branch-bookmark-suffix.t	Thu Feb 26 22:14:44 2015 -0800
@@ -95,8 +95,16 @@
   $ commit -m "append f2"
   $ git push origin
   To $TESTTMP/gitrepo1
-     5cbc2d4..776fecd  branch1 -> branch1
-     26a4009..e67b2e2  branch2 -> branch2
+     bbfe79a..d8aef79  branch1 -> branch1
+     288e92b..f8f8de5  branch2 -> branch2
+make sure the commit doesn't have an HG:rename-source annotation
+  $ git cat-file commit d8aef79
+  tree b5644d8071b8a5963b8d1fd089fb3fdfb14b1203
+  parent bbfe79acf62dcd6a97763e2a67424a6de8a96941
+  author test <test@example.org> 1167609612 +0000
+  committer test <test@example.org> 1167609612 +0000
+  
+  append f1
   $ cd ..
 
   $ cd hgrepo