[PATCH] check execute bit before removing merge node

Michael Fetterman Michael.Fetterman at cl.cam.ac.uk
Thu Aug 25 07:42:09 CDT 2005


Oops.  Caught a small typo in the last patch.  Fixed below.

Michael

----

Horray for the recent change that fixed the long-standing excessive file
merge issues.

Here's one more fix for that change.  Removing a merge node on a file
should not happen if the file's execute bit has changed status.  This patch
handles that as well, and adds a test case that both checks this, and
checks that the file merging not adding any unnecessary nodes.

Michael Fetterman

# HG changeset patch
# User maf46 at burn.cl.cam.ac.uk
# Node ID 7d6a3289ac85c3fe97be4a246abcf4850d3585ae
# Parent  9344f5dd448843e211af39423542bc23037b6843
Remember to compare execute bits before removing merge nodes

diff -r 9344f5dd4488 -r 7d6a3289ac85 mercurial/hg.py
--- a/mercurial/hg.py	Thu Aug 25 02:19:35 2005
+++ b/mercurial/hg.py	Thu Aug 25 12:38:32 2005
@@ -834,6 +834,7 @@
         m1 = self.manifest.read(c1[0])
         mf1 = self.manifest.readflags(c1[0])
         m2 = self.manifest.read(c2[0])
+        mf2 = self.manifest.readflags(c2[0])
         changed = []
 
         if orig_parent == p1:
@@ -854,6 +855,8 @@
 
                 fp1 = m1.get(f, nullid)
                 fp2 = m2.get(f, nullid)
+                ff1 = mf1.get(f, False)
+                ff2 = mf2.get(f, False)
 
                 # is the same revision on two branches of a merge?
                 if fp2 == fp1:
@@ -864,11 +867,12 @@
                     fpa = r.ancestor(fp1, fp2)
                     if fpa == fp1:
                         fp1, fp2 = fp2, nullid
+                        ff1 = ff2
                     elif fpa == fp2:
                         fp2 = nullid
 
                     # is the file unmodified from the parent?
-                    if t == r.read(fp1):
+                    if mfm[f] == ff1 and t == r.read(fp1):
                         # record the proper existing parent in manifest
                         # no need to add a revision
                         mm[f] = fp1
@@ -921,6 +925,7 @@
         m1 = self.manifest.read(c1[0])
         mf1 = self.manifest.readflags(c1[0])
         m2 = self.manifest.read(c2[0])
+        mf2 = self.manifest.readflags(c2[0])
 
         if not commit and not remove and not force and p2 == nullid:
             self.ui.status("nothing changed\n")
@@ -934,12 +939,13 @@
 
         # check in files
         new = {}
+        newf = {}
         linkrev = self.changelog.count()
         commit.sort()
         for f in commit:
             self.ui.note(f + "\n")
             try:
-                mf1[f] = util.is_exec(self.wjoin(f), mf1.get(f, False))
+                newf[f] = util.is_exec(self.wjoin(f), mf1.get(f, False))
                 t = self.wread(f)
             except IOError:
                 self.ui.warn("trouble committing %s!\n" % f)
@@ -955,6 +961,8 @@
             r = self.file(f)
             fp1 = m1.get(f, nullid)
             fp2 = m2.get(f, nullid)
+            ff1 = mf1.get(f, False)
+            ff2 = mf2.get(f, False)
 
             # is the same revision on two branches of a merge?
             if fp2 == fp1:
@@ -965,11 +973,12 @@
                 fpa = r.ancestor(fp1, fp2)
                 if fpa == fp1:
                     fp1, fp2 = fp2, nullid
+                    ff1 = ff2
                 elif fpa == fp2:
                     fp2 = nullid
 
                 # is the file unmodified from the parent?
-                if not meta and t == r.read(fp1):
+                if not meta and newf[f] == ff1 and t == r.read(fp1):
                     # record the proper existing parent in manifest
                     # no need to add a revision
                     new[f] = fp1
@@ -982,6 +991,7 @@
 
         # update manifest
         m1.update(new)
+        mf1.update(newf)
         for f in remove:
             if f in m1:
                 del m1[f]
diff -r 9344f5dd4488 -r 7d6a3289ac85 tests/test-merge7
--- /dev/null	Thu Aug 25 02:19:35 2005
+++ b/tests/test-merge7	Thu Aug 25 12:38:32 2005
@@ -0,0 +1,75 @@
+#!/bin/sh
+
+cat <<'EOF' > merge
+#!/bin/sh
+echo merge invoked for file `basename $1`
+EOF
+chmod +x merge
+export HGMERGE=`/bin/pwd`/merge
+
+mkdir user-foo
+cd user-foo
+
+	hg init
+	echo This is file foo0 > foo
+	hg add foo
+	hg commit -m commit.foo0 -d "0 0" -u foo
+
+cd ..
+hg clone user-foo user-bar
+hg clone user-foo user-baz
+cd user-bar
+
+	echo This is file bar0 > bar
+	hg add bar
+	hg commit -m commit.bar0 -d "0 0" -u bar
+
+cd ../user-foo
+
+	echo This is file foo1 >> foo
+	hg commit -m commit.foo1 -d "0 0" -u foo
+
+cd ../user-bar
+
+	echo This is file bar1 >> bar
+	hg commit -m commit.bar1 -d "0 0" -u bar
+
+	hg pull ../user-foo
+	hg update -m tip
+	hg commit -m commit.merge -d "0 0" -u bar
+
+cd ../user-foo
+
+	echo This is file foo2 >> foo
+	hg commit -m commit.foo2 -d "0 0" -u foo
+
+cd ../user-baz
+
+	echo This is file baz0 > baz
+	hg add baz
+	hg commit -m commit.baz0 -d "0 0" -u baz
+
+cd ../user-bar
+
+	echo This is file bar2 >> bar
+	hg commit -m commit.bar2 -d "0 0" -u bar
+
+	hg pull ../user-baz
+	hg update -m tip
+	# Naughty user bar did a chmod on baz's file...  :)
+	# This tests to see if commit picks up on only the mode changing
+	# during a merge.
+	chmod 755 baz
+	hg commit -m commit.merge -d "0 0" -u bar
+
+	hg pull ../user-foo
+	hg update -m tip
+	hg commit -m commit.merge -d "0 0" -u bar
+
+	# now for the real checks: how many revisions of each file?
+	echo REVISIONS OF FOO
+	hg log foo | grep -e changeset: -e user:
+	echo REVISIONS OF BAR
+	hg log bar | grep -e changeset: -e user:
+	echo REVISIONS OF BAZ
+	hg log baz | grep -e changeset: -e user:
diff -r 9344f5dd4488 -r 7d6a3289ac85 tests/test-merge7.out
--- /dev/null	Thu Aug 25 02:19:35 2005
+++ b/tests/test-merge7.out	Thu Aug 25 12:38:32 2005
@@ -0,0 +1,40 @@
+pulling from ../user-foo
+searching for changes
+adding changesets
+adding manifests
+adding file changes
+added 1 changesets with 1 changes to 1 files (+1 heads)
+(run 'hg update' to get a working copy)
+pulling from ../user-baz
+searching for changes
+adding changesets
+adding manifests
+adding file changes
+added 1 changesets with 1 changes to 1 files (+1 heads)
+(run 'hg update' to get a working copy)
+pulling from ../user-foo
+searching for changes
+adding changesets
+adding manifests
+adding file changes
+added 1 changesets with 1 changes to 1 files (+1 heads)
+(run 'hg update' to get a working copy)
+REVISIONS OF FOO
+changeset:   8:c0ae2ba13dfa
+user:        foo
+changeset:   3:cb5e7c3a2518
+user:        foo
+changeset:   0:bb3a1fec90ae
+user:        foo
+REVISIONS OF BAR
+changeset:   5:d99a8be9948a
+user:        bar
+changeset:   2:d73f420bf299
+user:        bar
+changeset:   1:fb4a26443b4d
+user:        bar
+REVISIONS OF BAZ
+changeset:   7:e7011acdf018
+user:        bar
+changeset:   6:4304fcf849d1
+user:        baz


More information about the Mercurial mailing list