##// END OF EJS Templates
Fix long-standing excessive file merges...
mpm@selenic.com -
r990:5007e0bd default
parent child Browse files
Show More
@@ -0,0 +1,73 b''
1 #!/bin/sh
2
3 # This test makes sure that we don't mark a file as merged with its ancestor
4 # when we do a merge.
5
6 cat <<'EOF' > merge
7 #!/bin/sh
8 echo merging for `basename $1`
9 EOF
10 chmod +x merge
11
12 echo creating base
13 hg init a
14 cd a
15 echo 1 > foo
16 echo 1 > bar
17 echo 1 > baz
18 echo 1 > quux
19 hg add foo bar baz quux
20 hg commit -m "base" -d "0 0"
21
22 cd ..
23 hg clone a b
24
25 echo creating branch a
26 cd a
27 echo 2a > foo
28 echo 2a > bar
29 hg commit -m "branch a" -d "0 0"
30
31 echo creating branch b
32
33 cd ..
34 cd b
35 echo 2b > foo
36 echo 2b > baz
37 hg commit -m "branch b" -d "0 0"
38
39 echo "we shouldn't have anything but n state here"
40 hg debugstate | cut -b 1-16,35-
41
42 echo merging
43 hg pull ../a
44 env HGMERGE=../merge hg update -vm --debug
45
46 echo 2m > foo
47 echo 2b > baz
48 echo new > quux
49
50 echo "we shouldn't have anything but foo in merge state here"
51 hg debugstate | cut -b 1-16,35- | grep "^m"
52
53 hg ci -m "merge" -d "0 0"
54
55 echo "main: we should have a merge here"
56 hg debugindex .hg/00changelog.i
57
58 echo "foo: we should have a merge here"
59 hg debugindex .hg/data/foo.i
60
61 echo "bar: we shouldn't have a merge here"
62 hg debugindex .hg/data/bar.i
63
64 echo "baz: we shouldn't have a merge here"
65 hg debugindex .hg/data/baz.i
66
67 echo "quux: we shouldn't have a merge here"
68 hg debugindex .hg/data/quux.i
69
70 echo "everything should be clean now"
71 hg status
72
73 hg verify
@@ -0,0 +1,58 b''
1 creating base
2 creating branch a
3 creating branch b
4 we shouldn't have anything but n state here
5 n 644 2 bar
6 n 644 3 baz
7 n 644 3 foo
8 n 644 2 quux
9 merging
10 pulling from ../a
11 searching for changes
12 adding changesets
13 adding manifests
14 adding file changes
15 added 1 changesets with 2 changes to 2 files
16 (run 'hg update' to get a working copy)
17 merging for foo
18 resolving manifests
19 force None allow 1 moddirstate True linear False
20 ancestor a0486579db29 local ef1b4dbe2193 remote 336d8406d617
21 remote bar is newer, get
22 foo versions differ, resolve
23 getting bar
24 merging foo
25 resolving foo
26 file foo: other 33d1fb69067a ancestor b8e02f643373
27 we shouldn't have anything but foo in merge state here
28 m 644 3 foo
29 main: we should have a merge here
30 rev offset length base linkrev nodeid p1 p2
31 0 0 73 0 0 cdca01651b96 000000000000 000000000000
32 1 73 68 1 1 f6718a9cb7f3 cdca01651b96 000000000000
33 2 141 68 2 2 bdd988058d16 cdca01651b96 000000000000
34 3 209 66 3 3 9da9fbd62226 f6718a9cb7f3 bdd988058d16
35 foo: we should have a merge here
36 rev offset length base linkrev nodeid p1 p2
37 0 0 3 0 0 b8e02f643373 000000000000 000000000000
38 1 3 4 1 1 2ffeddde1b65 b8e02f643373 000000000000
39 2 7 4 2 2 33d1fb69067a b8e02f643373 000000000000
40 3 11 4 3 3 aa27919ee430 2ffeddde1b65 33d1fb69067a
41 bar: we shouldn't have a merge here
42 rev offset length base linkrev nodeid p1 p2
43 0 0 3 0 0 b8e02f643373 000000000000 000000000000
44 1 3 4 1 2 33d1fb69067a b8e02f643373 000000000000
45 baz: we shouldn't have a merge here
46 rev offset length base linkrev nodeid p1 p2
47 0 0 3 0 0 b8e02f643373 000000000000 000000000000
48 1 3 4 1 1 2ffeddde1b65 b8e02f643373 000000000000
49 quux: we shouldn't have a merge here
50 rev offset length base linkrev nodeid p1 p2
51 0 0 3 0 0 b8e02f643373 000000000000 000000000000
52 1 3 5 1 3 6128c0f33108 b8e02f643373 000000000000
53 everything should be clean now
54 checking changesets
55 checking manifests
56 crosschecking files in changesets and manifests
57 checking files
58 4 files, 4 changesets, 10 total revisions
@@ -840,8 +840,30 b' class localrepository:'
840 tm = util.is_exec(self.wjoin(f), mfm.get(f, False))
840 tm = util.is_exec(self.wjoin(f), mfm.get(f, False))
841 r = self.file(f)
841 r = self.file(f)
842 mfm[f] = tm
842 mfm[f] = tm
843 mm[f] = r.add(t, {}, tr, linkrev,
843
844 m1.get(f, nullid), m2.get(f, nullid))
844 fp1 = m1.get(f, nullid)
845 fp2 = m2.get(f, nullid)
846
847 # is the same revision on two branches of a merge?
848 if fp2 == fp1:
849 fp2 = nullid
850
851 if fp2 != nullid:
852 # is one parent an ancestor of the other?
853 fpa = r.ancestor(fp1, fp2)
854 if fpa == fp1:
855 fp1, fp2 = fp2, nullid
856 elif fpa == fp2:
857 fp2 = nullid
858
859 # is the file unmodified from the parent?
860 if t == r.read(fp1):
861 # record the proper existing parent in manifest
862 # no need to add a revision
863 mm[f] = fp1
864 continue
865
866 mm[f] = r.add(t, {}, tr, linkrev, fp1, fp2)
845 if update_dirstate:
867 if update_dirstate:
846 self.dirstate.update([f], "n")
868 self.dirstate.update([f], "n")
847 except IOError:
869 except IOError:
@@ -879,19 +901,20 b' class localrepository:'
879 commit = c + a
901 commit = c + a
880 remove = d
902 remove = d
881
903
882 if not commit and not remove and not force:
904 p1, p2 = self.dirstate.parents()
905 c1 = self.changelog.read(p1)
906 c2 = self.changelog.read(p2)
907 m1 = self.manifest.read(c1[0])
908 mf1 = self.manifest.readflags(c1[0])
909 m2 = self.manifest.read(c2[0])
910
911 if not commit and not remove and not force and p2 == nullid:
883 self.ui.status("nothing changed\n")
912 self.ui.status("nothing changed\n")
884 return None
913 return None
885
914
886 if not self.hook("precommit"):
915 if not self.hook("precommit"):
887 return None
916 return None
888
917
889 p1, p2 = self.dirstate.parents()
890 c1 = self.changelog.read(p1)
891 c2 = self.changelog.read(p2)
892 m1 = self.manifest.read(c1[0])
893 mf1 = self.manifest.readflags(c1[0])
894 m2 = self.manifest.read(c2[0])
895 lock = self.lock()
918 lock = self.lock()
896 tr = self.transaction()
919 tr = self.transaction()
897
920
@@ -918,6 +941,26 b' class localrepository:'
918 r = self.file(f)
941 r = self.file(f)
919 fp1 = m1.get(f, nullid)
942 fp1 = m1.get(f, nullid)
920 fp2 = m2.get(f, nullid)
943 fp2 = m2.get(f, nullid)
944
945 # is the same revision on two branches of a merge?
946 if fp2 == fp1:
947 fp2 = nullid
948
949 if fp2 != nullid:
950 # is one parent an ancestor of the other?
951 fpa = r.ancestor(fp1, fp2)
952 if fpa == fp1:
953 fp1, fp2 = fp2, nullid
954 elif fpa == fp2:
955 fp2 = nullid
956
957 # is the file unmodified from the parent?
958 if not meta and t == r.read(fp1):
959 # record the proper existing parent in manifest
960 # no need to add a revision
961 new[f] = fp1
962 continue
963
921 new[f] = r.add(t, meta, tr, linkrev, fp1, fp2)
964 new[f] = r.add(t, meta, tr, linkrev, fp1, fp2)
922
965
923 # update manifest
966 # update manifest
@@ -1715,12 +1758,7 b' class localrepository:'
1715 self.ui.status("(use update -m to merge across branches" +
1758 self.ui.status("(use update -m to merge across branches" +
1716 " or -C to lose changes)\n")
1759 " or -C to lose changes)\n")
1717 return 1
1760 return 1
1718 # we have to remember what files we needed to get/change
1719 # because any file that's different from either one of its
1720 # parents must be in the changeset
1721 mode = 'm'
1761 mode = 'm'
1722 if moddirstate:
1723 self.dirstate.update(mark.keys(), "m")
1724
1762
1725 if moddirstate:
1763 if moddirstate:
1726 self.dirstate.setparents(p1, p2)
1764 self.dirstate.setparents(p1, p2)
@@ -1739,7 +1777,7 b' class localrepository:'
1739 self.wfile(f, "w").write(t)
1777 self.wfile(f, "w").write(t)
1740 util.set_exec(self.wjoin(f), mf2[f])
1778 util.set_exec(self.wjoin(f), mf2[f])
1741 if moddirstate:
1779 if moddirstate:
1742 self.dirstate.update([f], mode)
1780 self.dirstate.update([f], 'n')
1743
1781
1744 # merge the tricky bits
1782 # merge the tricky bits
1745 files = merge.keys()
1783 files = merge.keys()
@@ -6,7 +6,7 b' adding file changes'
6 added 1 changesets with 1 changes to 1 files
6 added 1 changesets with 1 changes to 1 files
7 (run 'hg update' to get a working copy)
7 (run 'hg update' to get a working copy)
8 bar should remain deleted.
8 bar should remain deleted.
9 6b70e9e451a5a33faad7bbebe627e46b937b7364 644 foo
9 f405ac83a5611071d6b54dd5eb26943b1fdc4460 644 foo
10 pulling from ../A2
10 pulling from ../A2
11 searching for changes
11 searching for changes
12 adding changesets
12 adding changesets
@@ -15,4 +15,4 b' adding file changes'
15 added 1 changesets with 0 changes to 0 files
15 added 1 changesets with 0 changes to 0 files
16 (run 'hg update' to get a working copy)
16 (run 'hg update' to get a working copy)
17 bar should remain deleted.
17 bar should remain deleted.
18 6b70e9e451a5a33faad7bbebe627e46b937b7364 644 foo
18 f9b0e817f6a48de3564c6b2957687c5e7297c5a0 644 foo
@@ -18,4 +18,4 b' searching for changes'
18 adding changesets
18 adding changesets
19 adding manifests
19 adding manifests
20 adding file changes
20 adding file changes
21 added 2 changesets with 2 changes to 2 files
21 added 2 changesets with 1 changes to 1 files
@@ -10,6 +10,4 b' acb14030fe0a+ first'
10 acb14030fe0a21b60322c440ad2d20cf7685a376+ first
10 acb14030fe0a21b60322c440ad2d20cf7685a376+ first
11 M a
11 M a
12 c8edf04160c7 tip
12 c8edf04160c7 tip
13 c8edf04160c7+b9154636be93+ tip
13 c8edf04160c7+b9154636be93 tip
14 M .hgtags
15 M a
General Comments 0
You need to be logged in to leave comments. Login now