Mercurial > public > mercurial-scm > hg
comparison mercurial/merge.py @ 4416:bb1800a7d7e1
merge: fix spurious merges for copies in linear updates
We make better use of contexts to accurately identify copies that
don't need merges.
Add a simple test and update other tests.
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Tue, 08 May 2007 02:59:13 -0500 |
parents | 84cd52b48f94 |
children | 0912d8df5e19 |
comparison
equal
deleted
inserted
replaced
4415:1a63b44f90c9 | 4416:bb1800a7d7e1 |
---|---|
6 # of the GNU General Public License, incorporated herein by reference. | 6 # of the GNU General Public License, incorporated herein by reference. |
7 | 7 |
8 from node import * | 8 from node import * |
9 from i18n import gettext as _ | 9 from i18n import gettext as _ |
10 from demandload import * | 10 from demandload import * |
11 demandload(globals(), "errno util os tempfile") | 11 demandload(globals(), "errno util os tempfile context") |
12 | 12 |
13 def filemerge(repo, fw, fo, wctx, mctx): | 13 def filemerge(repo, fw, fo, wctx, mctx): |
14 """perform a 3-way merge in the working directory | 14 """perform a 3-way merge in the working directory |
15 | 15 |
16 fw = filename in the working directory | 16 fw = filename in the working directory |
120 f = dirname(f) | 120 f = dirname(f) |
121 while f not in d: | 121 while f not in d: |
122 d[f] = True | 122 d[f] = True |
123 f = dirname(f) | 123 f = dirname(f) |
124 return d | 124 return d |
125 | |
126 wctx = repo.workingctx() | |
127 | |
128 def makectx(f, n): | |
129 if len(n) == 20: | |
130 return repo.filectx(f, fileid=n) | |
131 return wctx.filectx(f) | |
132 ctx = util.cachefunc(makectx) | |
125 | 133 |
126 def findold(fctx): | 134 def findold(fctx): |
127 "find files that path was copied from, back to linkrev limit" | 135 "find files that path was copied from, back to linkrev limit" |
128 old = {} | 136 old = {} |
129 seen = {} | 137 seen = {} |
158 if not ca: # unrelated? | 166 if not ca: # unrelated? |
159 continue | 167 continue |
160 # named changed on only one side? | 168 # named changed on only one side? |
161 if ca.path() == c.path() or ca.path() == c2.path(): | 169 if ca.path() == c.path() or ca.path() == c2.path(): |
162 fullcopy[c.path()] = of # remember for dir rename detection | 170 fullcopy[c.path()] = of # remember for dir rename detection |
163 if c == c2: # no merge needed, ignore copy | 171 if c == ca or c2 == ca: # no merge needed, ignore copy |
164 continue | 172 continue |
165 copy[c.path()] = of | 173 copy[c.path()] = of |
166 | 174 |
167 if not repo.ui.configbool("merge", "followcopies", True): | 175 if not repo.ui.configbool("merge", "followcopies", True): |
168 return {} | 176 return {} |
169 | 177 |
170 # avoid silly behavior for update from empty dir | 178 # avoid silly behavior for update from empty dir |
171 if not m1 or not m2 or not ma: | 179 if not m1 or not m2 or not ma: |
172 return {} | 180 return {} |
173 | 181 |
174 dcopies = repo.dirstate.copies() | |
175 u1 = nonoverlap(m1, m2, ma) | 182 u1 = nonoverlap(m1, m2, ma) |
176 u2 = nonoverlap(m2, m1, ma) | 183 u2 = nonoverlap(m2, m1, ma) |
177 ctx = util.cachefunc(lambda f, n: repo.filectx(f, fileid=n[:20])) | |
178 | 184 |
179 for f in u1: | 185 for f in u1: |
180 checkcopies(ctx(dcopies.get(f, f), m1[f]), m2) | 186 checkcopies(ctx(f, m1[f]), m2) |
181 | 187 |
182 for f in u2: | 188 for f in u2: |
183 checkcopies(ctx(f, m2[f]), m1) | 189 checkcopies(ctx(f, m2[f]), m1) |
184 | 190 |
185 if not fullcopy or not repo.ui.configbool("merge", "followdirs", True): | 191 if not fullcopy or not repo.ui.configbool("merge", "followdirs", True): |