copies: teach copies about dirstate.copies
When we're using copies() to find changes between the working directory and
its first parent for diff/status/etc., use dirstate.copies() directly.
This avoids doing a full statwalk for simple diffs (
issue1090) and
removes a special case from the status command.
--- a/mercurial/commands.py Tue Jun 03 09:34:14 2008 +0200
+++ b/mercurial/commands.py Tue Jun 03 15:41:09 2008 -0500
@@ -2644,20 +2644,18 @@
changestates = zip(states, 'MAR!?IC', stat)
if (opts['all'] or opts['copies']) and not opts['no_status']:
- if opts.get('rev') == []:
- # fast path, more correct with merge parents
- copy = repo.dirstate.copies()
- else:
- ctxn = repo.changectx(nullid)
- ctx1 = repo.changectx(node1)
- ctx2 = repo.changectx(node2)
- if node2 is None:
- ctx2 = repo.workingctx()
- for k, v in copies.copies(repo, ctx1, ctx2, ctxn)[0].items():
- if v in stat[1]:
- copy[v] = k
- elif k in stat[1]:
- copy[k] = v
+ ctxn = repo.changectx(nullid)
+ ctx1 = repo.changectx(node1)
+ ctx2 = repo.changectx(node2)
+ added = stat[1]
+ if node2 is None:
+ added = stat[0] + stat[1] # merged?
+ ctx2 = repo.workingctx()
+ for k, v in copies.copies(repo, ctx1, ctx2, ctxn)[0].items():
+ if k in added:
+ copy[k] = v
+ elif v in added:
+ copy[v] = k
for state, char, files in changestates:
if state in show:
--- a/mercurial/copies.py Tue Jun 03 09:34:14 2008 +0200
+++ b/mercurial/copies.py Tue Jun 03 15:41:09 2008 -0500
@@ -109,6 +109,10 @@
if not c1 or not c2 or c1 == c2:
return {}, {}
+ # avoid silly behavior for parent -> working dir
+ if c2.node() == None and c1.node() == repo.dirstate.parents()[0]:
+ return repo.dirstate.copies(), {}
+
limit = _findlimit(repo, c1.rev(), c2.rev())
m1 = c1.manifest()
m2 = c2.manifest()
--- a/tests/test-merge-remove.out Tue Jun 03 09:34:14 2008 +0200
+++ b/tests/test-merge-remove.out Tue Jun 03 15:41:09 2008 -0500
@@ -13,7 +13,6 @@
copy: foo -> foo1
R bar
R foo1
- foo
% readding foo1 and bar
adding bar
adding foo1