275 filenode: the filenode that should be used by this changeset |
274 filenode: the filenode that should be used by this changeset |
276 touched: one of: None (mean untouched), 'added' or 'modified' |
275 touched: one of: None (mean untouched), 'added' or 'modified' |
277 """ |
276 """ |
278 |
277 |
279 fname = fctx.path() |
278 fname = fctx.path() |
280 fparent1 = manifest1.get(fname, nullid) |
279 fparent1 = manifest1.get(fname, repo.nullid) |
281 fparent2 = manifest2.get(fname, nullid) |
280 fparent2 = manifest2.get(fname, repo.nullid) |
282 touched = None |
281 touched = None |
283 if fparent1 == fparent2 == nullid: |
282 if fparent1 == fparent2 == repo.nullid: |
284 touched = 'added' |
283 touched = 'added' |
285 |
284 |
286 if isinstance(fctx, context.filectx): |
285 if isinstance(fctx, context.filectx): |
287 # This block fast path most comparisons which are usually done. It |
286 # This block fast path most comparisons which are usually done. It |
288 # assumes that bare filectx is used and no merge happened, hence no |
287 # assumes that bare filectx is used and no merge happened, hence no |
289 # need to create a new file revision in this case. |
288 # need to create a new file revision in this case. |
290 node = fctx.filenode() |
289 node = fctx.filenode() |
291 if node in [fparent1, fparent2]: |
290 if node in [fparent1, fparent2]: |
292 repo.ui.debug(b'reusing %s filelog entry\n' % fname) |
291 repo.ui.debug(b'reusing %s filelog entry\n' % fname) |
293 if ( |
292 if ( |
294 fparent1 != nullid and manifest1.flags(fname) != fctx.flags() |
293 fparent1 != repo.nullid |
|
294 and manifest1.flags(fname) != fctx.flags() |
295 ) or ( |
295 ) or ( |
296 fparent2 != nullid and manifest2.flags(fname) != fctx.flags() |
296 fparent2 != repo.nullid |
|
297 and manifest2.flags(fname) != fctx.flags() |
297 ): |
298 ): |
298 touched = 'modified' |
299 touched = 'modified' |
299 return node, touched |
300 return node, touched |
300 |
301 |
301 flog = repo.file(fname) |
302 flog = repo.file(fname) |
325 |
326 |
326 cnode = manifest1.get(cfname) |
327 cnode = manifest1.get(cfname) |
327 newfparent = fparent2 |
328 newfparent = fparent2 |
328 |
329 |
329 if manifest2: # branch merge |
330 if manifest2: # branch merge |
330 if fparent2 == nullid or cnode is None: # copied on remote side |
331 if ( |
|
332 fparent2 == repo.nullid or cnode is None |
|
333 ): # copied on remote side |
331 if cfname in manifest2: |
334 if cfname in manifest2: |
332 cnode = manifest2[cfname] |
335 cnode = manifest2[cfname] |
333 newfparent = fparent1 |
336 newfparent = fparent1 |
334 |
337 |
335 # Here, we used to search backwards through history to try to find |
338 # Here, we used to search backwards through history to try to find |
344 if cnode: |
347 if cnode: |
345 repo.ui.debug(b" %s: copy %s:%s\n" % (fname, cfname, hex(cnode))) |
348 repo.ui.debug(b" %s: copy %s:%s\n" % (fname, cfname, hex(cnode))) |
346 if includecopymeta: |
349 if includecopymeta: |
347 meta[b"copy"] = cfname |
350 meta[b"copy"] = cfname |
348 meta[b"copyrev"] = hex(cnode) |
351 meta[b"copyrev"] = hex(cnode) |
349 fparent1, fparent2 = nullid, newfparent |
352 fparent1, fparent2 = repo.nullid, newfparent |
350 else: |
353 else: |
351 repo.ui.warn( |
354 repo.ui.warn( |
352 _( |
355 _( |
353 b"warning: can't find ancestor for '%s' " |
356 b"warning: can't find ancestor for '%s' " |
354 b"copied from '%s'!\n" |
357 b"copied from '%s'!\n" |
355 ) |
358 ) |
356 % (fname, cfname) |
359 % (fname, cfname) |
357 ) |
360 ) |
358 |
361 |
359 elif fparent1 == nullid: |
362 elif fparent1 == repo.nullid: |
360 fparent1, fparent2 = fparent2, nullid |
363 fparent1, fparent2 = fparent2, repo.nullid |
361 elif fparent2 != nullid: |
364 elif fparent2 != repo.nullid: |
362 if ms.active() and ms.extras(fname).get(b'filenode-source') == b'other': |
365 if ms.active() and ms.extras(fname).get(b'filenode-source') == b'other': |
363 fparent1, fparent2 = fparent2, nullid |
366 fparent1, fparent2 = fparent2, repo.nullid |
364 elif ms.active() and ms.extras(fname).get(b'merged') != b'yes': |
367 elif ms.active() and ms.extras(fname).get(b'merged') != b'yes': |
365 fparent1, fparent2 = fparent1, nullid |
368 fparent1, fparent2 = fparent1, repo.nullid |
366 # is one parent an ancestor of the other? |
369 # is one parent an ancestor of the other? |
367 else: |
370 else: |
368 fparentancestors = flog.commonancestorsheads(fparent1, fparent2) |
371 fparentancestors = flog.commonancestorsheads(fparent1, fparent2) |
369 if fparent1 in fparentancestors: |
372 if fparent1 in fparentancestors: |
370 fparent1, fparent2 = fparent2, nullid |
373 fparent1, fparent2 = fparent2, repo.nullid |
371 elif fparent2 in fparentancestors: |
374 elif fparent2 in fparentancestors: |
372 fparent2 = nullid |
375 fparent2 = repo.nullid |
373 |
376 |
374 force_new_node = False |
377 force_new_node = False |
375 # The file might have been deleted by merge code and user explicitly choose |
378 # The file might have been deleted by merge code and user explicitly choose |
376 # to revert the file and keep it. The other case can be where there is |
379 # to revert the file and keep it. The other case can be where there is |
377 # change-delete or delete-change conflict and user explicitly choose to keep |
380 # change-delete or delete-change conflict and user explicitly choose to keep |
382 and ms.extras(fname).get(b'merge-removal-candidate') == b'yes' |
385 and ms.extras(fname).get(b'merge-removal-candidate') == b'yes' |
383 ): |
386 ): |
384 force_new_node = True |
387 force_new_node = True |
385 # is the file changed? |
388 # is the file changed? |
386 text = fctx.data() |
389 text = fctx.data() |
387 if fparent2 != nullid or meta or flog.cmp(fparent1, text) or force_new_node: |
390 if ( |
|
391 fparent2 != repo.nullid |
|
392 or meta |
|
393 or flog.cmp(fparent1, text) |
|
394 or force_new_node |
|
395 ): |
388 if touched is None: # do not overwrite added |
396 if touched is None: # do not overwrite added |
389 if fparent2 == nullid: |
397 if fparent2 == repo.nullid: |
390 touched = 'modified' |
398 touched = 'modified' |
391 else: |
399 else: |
392 touched = 'merged' |
400 touched = 'merged' |
393 fnode = flog.add(text, meta, tr, linkrev, fparent1, fparent2) |
401 fnode = flog.add(text, meta, tr, linkrev, fparent1, fparent2) |
394 # are just the flags changed during merge? |
402 # are just the flags changed during merge? |