merge: remember rename copies and parents properly on commit
authorMatt Mackall <mpm@selenic.com>
Sun, 08 Oct 2006 19:57:45 -0500
changeset 3292 764688cf51e5
parent 3291 0b5d626b354e
child 3293 4546a5e31cb8
merge: remember rename copies and parents properly on commit record copies in dirstate even if rename was remote this lets us record it properly at commit teach checkfilemerge about copies, including merge cases pull old copy code out of commit extend rename-merge1 test to show file index
mercurial/localrepo.py
mercurial/merge.py
tests/test-rename-merge1
tests/test-rename-merge1.out
tests/test-rename-merge2.out
--- a/mercurial/localrepo.py	Sat Oct 07 15:16:47 2006 -0400
+++ b/mercurial/localrepo.py	Sun Oct 08 19:57:45 2006 -0500
@@ -462,11 +462,33 @@
                             desc=_('working directory of %s') % self.origroot)
 
     def checkfilemerge(self, filename, text, filelog, manifest1, manifest2):
-        "determine whether a new filenode is needed"
+        """
+        Determine whether a new filenode is needed and what parent
+        and rename information is needed for a file commit.
+
+        Returns (old entry, file parent 1, file parent 2, metadata)
+
+        If old entry is not None, a commit is not needed.
+        """
         fp1 = manifest1.get(filename, nullid)
         fp2 = manifest2.get(filename, nullid)
 
-        if fp2 != nullid:
+        meta = {}
+        cp = self.dirstate.copied(filename)
+        if cp:
+            meta["copy"] = cp
+            if not manifest2: # not a branch merge
+                meta["copyrev"] = hex(manifest1.get(cp, nullid))
+                fp2 = nullid
+            elif fp2 != nullid: # copied on remote side
+                meta["copyrev"] = hex(manifest1.get(cp, nullid))
+            else: # copied on local side, reversed
+                meta["copyrev"] = hex(manifest2.get(cp))
+                fp2 = nullid
+            self.ui.debug(_(" %s: copy %s:%s\n") %
+                          (filename, cp, meta["copyrev"]))
+            fp1 = nullid
+        elif fp2 != nullid:
             # is one parent an ancestor of the other?
             fpa = filelog.ancestor(fp1, fp2)
             if fpa == fp1:
@@ -475,10 +497,11 @@
                 fp2 = nullid
 
             # is the file unmodified from the parent? report existing entry
+            # fixme: use filelog.cmp()
             if fp2 == nullid and text == filelog.read(fp1):
-                return (fp1, None, None)
+                return (fp1, None, None, {})
 
-        return (None, fp1, fp2)
+        return (None, fp1, fp2, meta)
 
     def rawcommit(self, files, text, user, date, p1=None, p2=None, wlock=None):
         orig_parent = self.dirstate.parents()[0] or nullid
@@ -506,12 +529,12 @@
                 m1.set(f, util.is_exec(self.wjoin(f), m1.execf(f)))
                 r = self.file(f)
 
-                (entry, fp1, fp2) = self.checkfilemerge(f, t, r, m1, m2)
+                entry, fp1, fp2, meta = self.checkfilemerge(f, t, r, m1, m2)
                 if entry:
                     m1[f] = entry
                     continue
 
-                m1[f] = r.add(t, {}, tr, linkrev, fp1, fp2)
+                m1[f] = r.add(t, meta, tr, linkrev, fp1, fp2)
                 changed.append(f)
                 if update_dirstate:
                     self.dirstate.update([f], "n")
@@ -589,18 +612,10 @@
 
             r = self.file(f)
 
-            meta = {}
-            cp = self.dirstate.copied(f)
-            if cp:
-                meta["copy"] = cp
-                meta["copyrev"] = hex(m1.get(cp, m2.get(cp, nullid)))
-                self.ui.debug(_(" %s: copy %s:%s\n") % (f, cp, meta["copyrev"]))
-                fp1, fp2 = nullid, nullid
-            else:
-                entry, fp1, fp2 = self.checkfilemerge(f, t, r, m1, m2)
-                if entry:
-                    new[f] = entry
-                    continue
+            entry, fp1, fp2, meta = self.checkfilemerge(f, t, r, m1, m2)
+            if entry:
+                new[f] = entry
+                continue
 
             new[f] = r.add(t, meta, tr, linkrev, fp1, fp2)
             # remember what we've added so that we can later calculate
--- a/mercurial/merge.py	Sat Oct 07 15:16:47 2006 -0400
+++ b/mercurial/merge.py	Sun Oct 08 19:57:45 2006 -0500
@@ -359,6 +359,8 @@
                 repo.dirstate.update([f], 'r')
             if f != fd:
                 repo.dirstate.copy(f, fd)
+            else:
+                repo.dirstate.copy(f2, fd)
 
 def update(repo, node, branchmerge=False, force=False, partial=None,
            wlock=None, show_stats=True, remind=True):
--- a/tests/test-rename-merge1	Sat Oct 07 15:16:47 2006 -0400
+++ b/tests/test-rename-merge1	Sun Oct 08 19:57:45 2006 -0500
@@ -23,3 +23,5 @@
 hg status -AC
 cat b
 hg ci -m "merge" -d "0 0"
+hg debugindex .hg/data/b.i
+hg debugrename b
\ No newline at end of file
--- a/tests/test-rename-merge1.out	Sat Oct 07 15:16:47 2006 -0400
+++ b/tests/test-rename-merge1.out	Sun Oct 08 19:57:45 2006 -0500
@@ -20,3 +20,7 @@
 R a
 C c2
 blahblah
+   rev    offset  length   base linkrev nodeid       p1           p2
+     0         0      67      0       1 dc51707dfc98 000000000000 000000000000
+     1        67      72      1       3 b2494a44f0a9 000000000000 dc51707dfc98
+renamed from a:dd03b83622e78778b403775d0d074b9ac7387a66
--- a/tests/test-rename-merge2.out	Sat Oct 07 15:16:47 2006 -0400
+++ b/tests/test-rename-merge2.out	Sun Oct 08 19:57:45 2006 -0500
@@ -42,6 +42,7 @@
 --------------
 M a
 M b
+  a
 --------------
 
 --------------
@@ -85,6 +86,7 @@
 (branch merge, don't forget to commit)
 --------------
 M b
+  a
 --------------
 
 --------------
@@ -128,6 +130,7 @@
 (branch merge, don't forget to commit)
 --------------
 M b
+  a
 C a
 --------------
 
@@ -172,6 +175,7 @@
 (branch merge, don't forget to commit)
 --------------
 M b
+  a
 --------------
 
 --------------
@@ -430,6 +434,7 @@
 (branch merge, don't forget to commit)
 --------------
 M b
+  a
 --------------
 
 --------------
@@ -452,6 +457,7 @@
 (branch merge, don't forget to commit)
 --------------
 M b
+  a
 M c
 --------------