Mercurial > hg
diff mercurial/copies.py @ 6430:a6a66e812c34
copies: teach symmetric difference about working revisions
- use changelog.count() as a pseudo revision number
- abort early in copies if revs are the same
- eliminate working dir hacks in copies
- yield results as they're found
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Sat, 29 Mar 2008 12:39:47 -0500 |
parents | 532ca442b903 |
children | a42d8d3e6ea9 |
line wrap: on
line diff
--- a/mercurial/copies.py Sat Mar 29 12:39:47 2008 -0500 +++ b/mercurial/copies.py Sat Mar 29 12:39:47 2008 -0500 @@ -53,7 +53,7 @@ old.sort() return [o[1] for o in old] -def _symmetricdifference(a, b, pfunc): +def _symmetricdifference(repo, a, b): """find revisions that are ancestors of a or b, but not both""" # basic idea: # - mark a and b with different sides @@ -64,8 +64,13 @@ # - clear side of any parent that has children on different sides # - track number of unvisited nodes that might still be on a side # - quit when interesting nodes is zero - if a == b: - return [a] + + cl = repo.changelog + working = cl.count() + if a is None: + a = working + if b is None: + b = working side = {a: -1, b: 1} visit = [-a, -b] @@ -74,9 +79,11 @@ while interesting: r = -heapq.heappop(visit) - if side[r]: - interesting -= 1 - for p in pfunc(r): + if r == working: + parents = [cl.rev(p) for p in repo.dirstate.parents()] + else: + parents = cl.parentrevs(r) + for p in parents: if p not in side: # first time we see p; add it to visit side[p] = side[r] @@ -87,26 +94,19 @@ # p was interesting but now we know better side[p] = 0 interesting -= 1 - - return [r for r in side if side[r]] + if side[r]: + interesting -= 1 + yield r def copies(repo, c1, c2, ca, checkdirs=False): """ Find moves and copies between context c1 and c2 """ # avoid silly behavior for update from empty dir - if not c1 or not c2: + if not c1 or not c2 or c1 == c2: return {}, {} - rev1, rev2 = c1.rev(), c2.rev() - if rev1 is None: # c1 is a workingctx - rev1 = c1.parents()[0].rev() - if rev2 is None: # c2 is a workingctx - rev2 = c2.parents()[0].rev() - pr = repo.changelog.parentrevs - def parents(rev): - return [p for p in pr(rev) if p != nullrev] - limit = min(_symmetricdifference(rev1, rev2, parents)) + limit = min(_symmetricdifference(repo, c1.rev(), c2.rev())) m1 = c1.manifest() m2 = c2.manifest() ma = ca.manifest()