Show More
@@ -5206,17 +5206,7 b' def status(ui, repo, *pats, **opts):' | |||
|
5206 | 5206 | changestates = zip(states, 'MAR!?IC', stat) |
|
5207 | 5207 | |
|
5208 | 5208 | if (opts.get('all') or opts.get('copies')) and not opts.get('no_status'): |
|
5209 | ctx1 = repo[node1] | |
|
5210 | ctx2 = repo[node2] | |
|
5211 | added = stat[1] | |
|
5212 | if node2 is None: | |
|
5213 | added = stat[0] + stat[1] # merged? | |
|
5214 | ||
|
5215 | for k, v in copies.pathcopies(ctx1, ctx2).iteritems(): | |
|
5216 | if k in added: | |
|
5217 | copy[k] = v | |
|
5218 | elif v in added: | |
|
5219 | copy[v] = k | |
|
5209 | copy = copies.pathcopies(repo[node1], repo[node2]) | |
|
5220 | 5210 | |
|
5221 | 5211 | for state, char, files in changestates: |
|
5222 | 5212 | if state in show: |
@@ -84,8 +84,89 b' def _findlimit(repo, a, b):' | |||
|
84 | 84 | return None |
|
85 | 85 | return limit |
|
86 | 86 | |
|
87 | def pathcopies(c1, c2): | |
|
88 | return mergecopies(c1._repo, c1, c2, c1._repo["null"], False)[0] | |
|
87 | def _chain(src, dst, a, b): | |
|
88 | '''chain two sets of copies a->b''' | |
|
89 | t = a.copy() | |
|
90 | for k, v in b.iteritems(): | |
|
91 | if v in t: | |
|
92 | # found a chain | |
|
93 | if t[v] != k: | |
|
94 | # file wasn't renamed back to itself | |
|
95 | t[k] = t[v] | |
|
96 | if v not in dst: | |
|
97 | # chain was a rename, not a copy | |
|
98 | del t[v] | |
|
99 | if v in src: | |
|
100 | # file is a copy of an existing file | |
|
101 | t[k] = v | |
|
102 | return t | |
|
103 | ||
|
104 | def _tracefile(fctx, actx): | |
|
105 | '''return file context that is the ancestor of fctx present in actx''' | |
|
106 | stop = actx.rev() | |
|
107 | am = actx.manifest() | |
|
108 | ||
|
109 | for f in fctx.ancestors(): | |
|
110 | if am.get(f.path(), None) == f.filenode(): | |
|
111 | return f | |
|
112 | if f.rev() < stop: | |
|
113 | return None | |
|
114 | ||
|
115 | def _dirstatecopies(d): | |
|
116 | ds = d._repo.dirstate | |
|
117 | c = ds.copies().copy() | |
|
118 | for k in c.keys(): | |
|
119 | if ds[k] not in 'anm': | |
|
120 | del c[k] | |
|
121 | return c | |
|
122 | ||
|
123 | def _forwardcopies(a, b): | |
|
124 | '''find {dst@b: src@a} copy mapping where a is an ancestor of b''' | |
|
125 | ||
|
126 | # check for working copy | |
|
127 | w = None | |
|
128 | if b.rev() is None: | |
|
129 | w = b | |
|
130 | b = w.p1() | |
|
131 | if a == b: | |
|
132 | # short-circuit to avoid issues with merge states | |
|
133 | return _dirstatecopies(w) | |
|
134 | ||
|
135 | # find where new files came from | |
|
136 | # we currently don't try to find where old files went, too expensive | |
|
137 | # this means we can miss a case like 'hg rm b; hg cp a b' | |
|
138 | cm = {} | |
|
139 | for f in b: | |
|
140 | if f not in a: | |
|
141 | ofctx = _tracefile(b[f], a) | |
|
142 | if ofctx: | |
|
143 | cm[f] = ofctx.path() | |
|
144 | ||
|
145 | # combine copies from dirstate if necessary | |
|
146 | if w is not None: | |
|
147 | cm = _chain(a, w, cm, _dirstatecopies(w)) | |
|
148 | ||
|
149 | return cm | |
|
150 | ||
|
151 | def _backwardcopies(a, b): | |
|
152 | # because the forward mapping is 1:n, we can lose renames here | |
|
153 | # in particular, we find renames better than copies | |
|
154 | f = _forwardcopies(b, a) | |
|
155 | r = {} | |
|
156 | for k, v in f.iteritems(): | |
|
157 | r[v] = k | |
|
158 | return r | |
|
159 | ||
|
160 | def pathcopies(x, y): | |
|
161 | '''find {dst@y: src@x} copy mapping for directed compare''' | |
|
162 | if x == y or not x or not y: | |
|
163 | return {} | |
|
164 | a = y.ancestor(x) | |
|
165 | if a == x: | |
|
166 | return _forwardcopies(x, y) | |
|
167 | if a == y: | |
|
168 | return _backwardcopies(x, y) | |
|
169 | return _chain(x, y, _backwardcopies(x, a), _forwardcopies(a, y)) | |
|
89 | 170 | |
|
90 | 171 | def mergecopies(repo, c1, c2, ca, checkdirs=True): |
|
91 | 172 | """ |
@@ -149,13 +149,11 b' Check patcha is still a git patch:' | |||
|
149 | 149 | -b |
|
150 | 150 | +a |
|
151 | 151 | +c |
|
152 | diff --git a/a b/aa | |
|
153 | copy from a | |
|
154 | copy to aa | |
|
155 | --- a/a | |
|
152 | diff --git a/aa b/aa | |
|
153 | new file mode 100644 | |
|
154 | --- /dev/null | |
|
156 | 155 | +++ b/aa |
|
157 |
@@ - |
|
|
158 | -b | |
|
156 | @@ -0,0 +1,1 @@ | |
|
159 | 157 | +a |
|
160 | 158 | |
|
161 | 159 | Check patcha2 is still a regular patch: |
@@ -560,6 +560,7 b' make a new branch and get diff/status ou' | |||
|
560 | 560 | |
|
561 | 561 | - parent to root: --rev . --rev 0 |
|
562 | 562 | M a |
|
563 | b | |
|
563 | 564 | R b |
|
564 | 565 | |
|
565 | 566 | diff --git a/a b/a |
@@ -611,6 +612,7 b' make a new branch and get diff/status ou' | |||
|
611 | 612 | |
|
612 | 613 | - parent to branch: --rev . --rev 2 |
|
613 | 614 | M a |
|
615 | b | |
|
614 | 616 | A x/y |
|
615 | 617 | R b |
|
616 | 618 | |
@@ -906,6 +908,7 b' make a new branch and get diff/status ou' | |||
|
906 | 908 | |
|
907 | 909 | - parent to root: --rev . --rev 0 |
|
908 | 910 | M a |
|
911 | b | |
|
909 | 912 | R b |
|
910 | 913 | R c |
|
911 | 914 | |
@@ -975,6 +978,7 b' make a new branch and get diff/status ou' | |||
|
975 | 978 | |
|
976 | 979 | - parent to branch: --rev . --rev 2 |
|
977 | 980 | M a |
|
981 | b | |
|
978 | 982 | A x/y |
|
979 | 983 | R b |
|
980 | 984 | R c |
General Comments 0
You need to be logged in to leave comments.
Login now