##// END OF EJS Templates
merge: merge file flags together with file content...
Mads Kiilerich -
r18338:384df4db default
parent child Browse files
Show More
@@ -45,11 +45,11 b' class mergestate(object):'
45 45 f.write("\0".join([d] + v) + "\n")
46 46 f.close()
47 47 self._dirty = False
48 def add(self, fcl, fco, fca, fd, flags):
48 def add(self, fcl, fco, fca, fd):
49 49 hash = util.sha1(fcl.path()).hexdigest()
50 50 self._repo.opener.write("merge/" + hash, fcl.data())
51 51 self._state[fd] = ['u', hash, fcl.path(), fca.path(),
52 hex(fca.filenode()), fco.path(), flags]
52 hex(fca.filenode()), fco.path(), fcl.flags()]
53 53 self._dirty = True
54 54 def __contains__(self, dfile):
55 55 return dfile in self._state
@@ -67,12 +67,22 b' class mergestate(object):'
67 67 if self[dfile] == 'r':
68 68 return 0
69 69 state, hash, lfile, afile, anode, ofile, flags = self._state[dfile]
70 fcd = wctx[dfile]
71 fco = octx[ofile]
72 fca = self._repo.filectx(afile, fileid=anode)
73 # "premerge" x flags
74 flo = fco.flags()
75 fla = fca.flags()
76 if 'x' in flags + flo + fla and 'l' not in flags + flo + fla:
77 if fca.node() == nullid:
78 self._repo.ui.warn(_('warning: cannot merge flags for %s\n') %
79 afile)
80 elif flags == fla:
81 flags = flo
82 # restore local
70 83 f = self._repo.opener("merge/" + hash)
71 84 self._repo.wwrite(dfile, f.read(), flags)
72 85 f.close()
73 fcd = wctx[dfile]
74 fco = octx[ofile]
75 fca = self._repo.filectx(afile, fileid=anode)
76 86 r = filemerge.filemerge(self._repo, self._local, lfile, fcd, fco, fca)
77 87 if r is None:
78 88 # no real conflict
@@ -183,32 +193,6 b' def manifestmerge(repo, p1, p2, pa, over'
183 193 partial = function to filter file lists
184 194 """
185 195
186 def fmerge(f, f2, fa):
187 """merge flags"""
188 a, m, n = ma.flags(fa), m1.flags(f), m2.flags(f2)
189 if m == n: # flags agree
190 return m # unchanged
191 if m and n and not a: # flags set, don't agree, differ from parent
192 r = repo.ui.promptchoice(
193 _(" conflicting flags for %s\n"
194 "(n)one, e(x)ec or sym(l)ink?") % f,
195 (_("&None"), _("E&xec"), _("Sym&link")), 0)
196 if r == 1:
197 return "x" # Exec
198 if r == 2:
199 return "l" # Symlink
200 return ""
201 if m and m != a: # changed from a to m
202 return m
203 if n and n != a: # changed from a to n
204 if (n == 'l' or a == 'l') and m1.get(f) != ma.get(f):
205 # can't automatically merge symlink flag when there
206 # are file-level conflicts here, let filemerge take
207 # care of it
208 return m
209 return n
210 return '' # flag was cleared
211
212 196 def act(msg, m, f, *args):
213 197 repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
214 198 actions.append((f, m) + args)
@@ -248,17 +232,25 b' def manifestmerge(repo, p1, p2, pa, over'
248 232 if partial and not partial(f):
249 233 continue
250 234 if f in m2:
251 rflags = fmerge(f, f, f)
235 n2 = m2[f]
236 fl1, fl2, fla = m1.flags(f), m2.flags(f), ma.flags(f)
237 nol = 'l' not in fl1 + fl2 + fla
252 238 a = ma.get(f, nullid)
253 if n == m2[f] or m2[f] == a: # same or local newer
254 # is file locally modified or flags need changing?
255 # dirstate flags may need to be made current
256 if m1.flags(f) != rflags or n[20:]:
257 act("update permissions", "e", f, rflags)
258 elif n == a: # remote newer
259 act("remote is newer", "g", f, rflags)
260 else: # both changed
261 act("versions differ", "m", f, f, f, rflags, False)
239 if n == n2 and fl1 == fl2:
240 pass # same - keep local
241 elif n2 == a and fl2 == fla:
242 pass # remote unchanged - keep local
243 elif n == a and fl1 == fla: # local unchanged - use remote
244 if n == n2: # optimization: keep local content
245 act("update permissions", "e", f, fl2)
246 else:
247 act("remote is newer", "g", f, fl2)
248 elif nol and n2 == a: # remote only changed 'x'
249 act("update permissions", "e", f, fl2)
250 elif nol and n == a: # local only changed 'x'
251 act("remote is newer", "g", f, fl)
252 else: # both changed something
253 act("versions differ", "m", f, f, f, False)
262 254 elif f in copied: # files we'll deal with on m2 side
263 255 pass
264 256 elif f in movewithdir: # directory rename
@@ -267,8 +259,7 b' def manifestmerge(repo, p1, p2, pa, over'
267 259 m1.flags(f))
268 260 elif f in copy: # case 2 A,B/B/B or case 4,21 A/B/B
269 261 f2 = copy[f]
270 act("local copied/moved to " + f2, "m", f, f2, f,
271 fmerge(f, f2, f2), False)
262 act("local copied/moved to " + f2, "m", f, f2, f, False)
272 263 elif f in ma: # clean, a different, no remote
273 264 if n != ma[f]:
274 265 if repo.ui.promptchoice(
@@ -296,16 +287,15 b' def manifestmerge(repo, p1, p2, pa, over'
296 287 f2 = copy[f]
297 288 if f2 in m2: # rename case 1, A/A,B/A
298 289 act("remote copied to " + f, "m",
299 f2, f, f, fmerge(f2, f, f2), False)
290 f2, f, f, False)
300 291 else: # case 3,20 A/B/A
301 292 act("remote moved to " + f, "m",
302 f2, f, f, fmerge(f2, f, f2), True)
293 f2, f, f, True)
303 294 elif f not in ma:
304 295 if (not overwrite
305 296 and _checkunknownfile(repo, p1, p2, f)):
306 rflags = fmerge(f, f, f)
307 297 act("remote differs from untracked local",
308 "m", f, f, f, rflags, False)
298 "m", f, f, f, False)
309 299 else:
310 300 act("remote created", "g", f, m2.flags(f))
311 301 elif n != ma[f]:
@@ -341,7 +331,7 b' def applyupdates(repo, actions, wctx, mc'
341 331 for a in actions:
342 332 f, m = a[:2]
343 333 if m == "m": # merge
344 f2, fd, flags, move = a[2:]
334 f2, fd, move = a[2:]
345 335 if fd == '.hgsubstate': # merged internally
346 336 continue
347 337 repo.ui.debug("preserving %s for resolve of %s\n" % (f, fd))
@@ -356,7 +346,7 b' def applyupdates(repo, actions, wctx, mc'
356 346 fca = fcl.ancestor(fco, actx)
357 347 if not fca:
358 348 fca = repo.filectx(f, fileid=nullrev)
359 ms.add(fcl, fco, fca, fd, flags)
349 ms.add(fcl, fco, fca, fd)
360 350 if f != fd and move:
361 351 moves.append(f)
362 352
@@ -390,7 +380,7 b' def applyupdates(repo, actions, wctx, mc'
390 380 subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx),
391 381 overwrite)
392 382 continue
393 f2, fd, flags, move = a[2:]
383 f2, fd, move = a[2:]
394 384 audit(fd)
395 385 r = ms.resolve(fd, wctx, mctx)
396 386 if r is not None and r > 0:
@@ -484,7 +474,7 b' def recordupdates(repo, actions, branchm'
484 474 else:
485 475 repo.dirstate.normal(f)
486 476 elif m == "m": # merge
487 f2, fd, flag, move = a[2:]
477 f2, fd, move = a[2:]
488 478 if branchmerge:
489 479 # We've done a branch merge, mark this file as merged
490 480 # so that we properly record the merger later
@@ -34,16 +34,28 b' Symlink is local parent, executable is o'
34 34 resolving manifests
35 35 overwrite: False, partial: False
36 36 ancestor: c334dc3be0da, local: 521a1e40188f+, remote: 3574f3e69b1c
37 conflicting flags for a
38 (n)one, e(x)ec or sym(l)ink? n
39 a: update permissions -> e
37 a: versions differ -> m
38 preserving a for resolve of a
40 39 updating: a 1/1 files (100.00%)
41 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
42 (branch merge, don't forget to commit)
40 picked tool 'internal:merge' for a (binary False symlink True)
41 merging a
42 my a@521a1e40188f+ other a@3574f3e69b1c ancestor a@c334dc3be0da
43 warning: internal:merge cannot merge symlinks for a
44 merging a incomplete! (edit conflicts, then use 'hg resolve --mark')
45 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
46 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
47 [1]
43 48
44 49 $ tellmeabout a
45 a is a plain file with content:
46 symlink (no-eol)
50 a is a symlink:
51 a -> symlink
52 $ hg resolve a --tool internal:other
53 $ tellmeabout a
54 a is an executable file with content:
55 a
56 $ hg st
57 M a
58 ? a.orig
47 59
48 60 Symlink is other parent, executable is local:
49 61
@@ -55,17 +67,21 b' Symlink is other parent, executable is l'
55 67 resolving manifests
56 68 overwrite: False, partial: False
57 69 ancestor: c334dc3be0da, local: 3574f3e69b1c+, remote: 521a1e40188f
58 conflicting flags for a
59 (n)one, e(x)ec or sym(l)ink? n
60 a: remote is newer -> g
70 a: versions differ -> m
71 preserving a for resolve of a
61 72 updating: a 1/1 files (100.00%)
62 getting a
63 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
64 (branch merge, don't forget to commit)
73 picked tool 'internal:merge' for a (binary False symlink True)
74 merging a
75 my a@3574f3e69b1c+ other a@521a1e40188f ancestor a@c334dc3be0da
76 warning: internal:merge cannot merge symlinks for a
77 merging a incomplete! (edit conflicts, then use 'hg resolve --mark')
78 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
79 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
80 [1]
65 81
66 82 $ tellmeabout a
67 a is a plain file with content:
68 symlink (no-eol)
83 a is an executable file with content:
84 a
69 85
70 86 Update to link without local change should get us a symlink (issue3316):
71 87
@@ -74,6 +90,7 b' Update to link without local change shou'
74 90 $ hg up
75 91 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
76 92 $ hg st
93 ? a.orig
77 94
78 95 Update to link with local change should cause a merge prompt (issue3200):
79 96
@@ -119,18 +136,24 b' where that was what happened.'
119 136 $ ln -s base f
120 137 $ hg ci -qm2
121 138 $ hg merge
122 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
123 (branch merge, don't forget to commit)
139 merging f
140 warning: internal:merge cannot merge symlinks for f
141 merging f incomplete! (edit conflicts, then use 'hg resolve --mark')
142 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
143 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
144 [1]
124 145 $ tellmeabout f
125 146 f is a symlink:
126 f -> file
127 content
128
147 f -> base
129 148
130 149 $ hg up -Cqr1
131 150 $ hg merge
132 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
133 (branch merge, don't forget to commit)
151 merging f
152 warning: internal:merge cannot merge symlinks for f
153 merging f incomplete! (edit conflicts, then use 'hg resolve --mark')
154 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
155 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
156 [1]
134 157 $ tellmeabout f
135 158 f is a plain file with content:
136 159 file
@@ -152,19 +175,27 b" Test removed 'x' flag merged with change"
152 175 $ ln -s dangling f
153 176 $ hg ci -qm2
154 177 $ hg merge
155 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
156 (branch merge, don't forget to commit)
178 merging f
179 warning: internal:merge cannot merge symlinks for f
180 merging f incomplete! (edit conflicts, then use 'hg resolve --mark')
181 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
182 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
183 [1]
157 184 $ tellmeabout f
158 185 f is a symlink:
159 186 f -> dangling
160 187
161 188 $ hg up -Cqr1
162 189 $ hg merge
163 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
164 (branch merge, don't forget to commit)
190 merging f
191 warning: internal:merge cannot merge symlinks for f
192 merging f incomplete! (edit conflicts, then use 'hg resolve --mark')
193 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
194 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
195 [1]
165 196 $ tellmeabout f
166 f is a symlink:
167 f -> dangling
197 f is a plain file with content:
198 f
168 199
169 200 $ cd ..
170 201
@@ -210,13 +241,10 b' h: l vs l, different'
210 241 $ hg ci -Aqm2
211 242
212 243 $ hg merge
213 conflicting flags for e
214 (n)one, e(x)ec or sym(l)ink? n
215 conflicting flags for d
216 (n)one, e(x)ec or sym(l)ink? n
217 244 merging a
218 245 warning: conflicts during merge.
219 246 merging a incomplete! (edit conflicts, then use 'hg resolve --mark')
247 warning: cannot merge flags for b
220 248 merging b
221 249 warning: conflicts during merge.
222 250 merging b incomplete! (edit conflicts, then use 'hg resolve --mark')
@@ -229,7 +257,7 b' h: l vs l, different'
229 257 merging h
230 258 warning: internal:merge cannot merge symlinks for h
231 259 merging h incomplete! (edit conflicts, then use 'hg resolve --mark')
232 2 files updated, 0 files merged, 0 files removed, 5 files unresolved
260 3 files updated, 0 files merged, 0 files removed, 5 files unresolved
233 261 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
234 262 [1]
235 263 $ hg resolve -l
@@ -246,21 +274,21 b' h: l vs l, different'
246 274 1
247 275 >>>>>>> other
248 276 $ tellmeabout b
249 b is an executable file with content:
277 b is a plain file with content:
250 278 <<<<<<< local
251 279 2
252 280 =======
253 281 1
254 282 >>>>>>> other
255 283 $ tellmeabout c
256 c is an executable file with content:
284 c is a plain file with content:
257 285 x
258 286 $ tellmeabout d
259 d is a plain file with content:
260 2 (no-eol)
287 d is a symlink:
288 d -> 2
261 289 $ tellmeabout e
262 e is a plain file with content:
263 x (no-eol)
290 e is a symlink:
291 e -> x
264 292 $ tellmeabout f
265 293 f is a symlink:
266 294 f -> 2
@@ -273,13 +301,10 b' h: l vs l, different'
273 301
274 302 $ hg up -Cqr1
275 303 $ hg merge
276 conflicting flags for e
277 (n)one, e(x)ec or sym(l)ink? n
278 conflicting flags for d
279 (n)one, e(x)ec or sym(l)ink? n
280 304 merging a
281 305 warning: conflicts during merge.
282 306 merging a incomplete! (edit conflicts, then use 'hg resolve --mark')
307 warning: cannot merge flags for b
283 308 merging b
284 309 warning: conflicts during merge.
285 310 merging b incomplete! (edit conflicts, then use 'hg resolve --mark')
@@ -292,7 +317,7 b' h: l vs l, different'
292 317 merging h
293 318 warning: internal:merge cannot merge symlinks for h
294 319 merging h incomplete! (edit conflicts, then use 'hg resolve --mark')
295 1 files updated, 0 files merged, 0 files removed, 5 files unresolved
320 3 files updated, 0 files merged, 0 files removed, 5 files unresolved
296 321 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
297 322 [1]
298 323 $ tellmeabout a
@@ -310,13 +335,13 b' h: l vs l, different'
310 335 2
311 336 >>>>>>> other
312 337 $ tellmeabout c
313 c is an executable file with content:
338 c is a plain file with content:
314 339 x
315 340 $ tellmeabout d
316 d is a plain file with content:
341 d is an executable file with content:
317 342 1
318 343 $ tellmeabout e
319 e is a plain file with content:
344 e is an executable file with content:
320 345 x (no-eol)
321 346 $ tellmeabout f
322 347 f is a plain file with content:
General Comments 0
You need to be logged in to leave comments. Login now