changeset 3295:764688cf51e5

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
author Matt Mackall <mpm@selenic.com>
date Sun, 08 Oct 2006 19:57:45 -0500
parents 0b5d626b354e
children 4546a5e31cb8
files mercurial/localrepo.py mercurial/merge.py tests/test-rename-merge1 tests/test-rename-merge1.out tests/test-rename-merge2.out
diffstat 5 files changed, 47 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -462,11 +462,33 @@ class localrepository(repo.repository):
                             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 @@ class localrepository(repo.repository):
                 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 @@ class localrepository(repo.repository):
                 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 @@ class localrepository(repo.repository):
 
             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
+++ b/mercurial/merge.py
@@ -359,6 +359,8 @@ def recordupdates(repo, action, branchme
                 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
+++ b/tests/test-rename-merge1
@@ -23,3 +23,5 @@ hg merge -y --debug
 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
+++ b/tests/test-rename-merge1.out
@@ -20,3 +20,7 @@ M b2
 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
+++ b/tests/test-rename-merge2.out
@@ -42,6 +42,7 @@ 1 files updated, 2 files merged, 0 files
 --------------
 M a
 M b
+  a
 --------------
 
 --------------
@@ -85,6 +86,7 @@ 0 files updated, 2 files merged, 0 files
 (branch merge, don't forget to commit)
 --------------
 M b
+  a
 --------------
 
 --------------
@@ -128,6 +130,7 @@ 0 files updated, 2 files merged, 0 files
 (branch merge, don't forget to commit)
 --------------
 M b
+  a
 C a
 --------------
 
@@ -172,6 +175,7 @@ 0 files updated, 2 files merged, 0 files
 (branch merge, don't forget to commit)
 --------------
 M b
+  a
 --------------
 
 --------------
@@ -430,6 +434,7 @@ 0 files updated, 2 files merged, 0 files
 (branch merge, don't forget to commit)
 --------------
 M b
+  a
 --------------
 
 --------------
@@ -452,6 +457,7 @@ 1 files updated, 2 files merged, 0 files
 (branch merge, don't forget to commit)
 --------------
 M b
+  a
 M c
 --------------