Mercurial > public > mercurial-scm > hg
comparison mercurial/merge.py @ 4396:c04c96504a12
merge: clarify the findcopies code
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Thu, 03 May 2007 17:24:43 -0500 |
parents | 8aee687f0214 |
children | 9fe267f77f56 |
comparison
equal
deleted
inserted
replaced
4359:80d3f6f0d8e5 | 4396:c04c96504a12 |
---|---|
131 return l | 131 return l |
132 | 132 |
133 def checkcopies(c, man): | 133 def checkcopies(c, man): |
134 '''check possible copies for filectx c''' | 134 '''check possible copies for filectx c''' |
135 for of in findold(c): | 135 for of in findold(c): |
136 if of not in man: | 136 if of not in man: # original file not in other manifest? |
137 continue | 137 continue |
138 c2 = ctx(of, man[of]) | 138 c2 = ctx(of, man[of]) |
139 ca = c.ancestor(c2) | 139 ca = c.ancestor(c2) |
140 if not ca: # unrelated | 140 if not ca: # unrelated? |
141 continue | 141 continue |
142 # named changed on only one side? | |
142 if ca.path() == c.path() or ca.path() == c2.path(): | 143 if ca.path() == c.path() or ca.path() == c2.path(): |
143 fullcopy[c.path()] = of | 144 fullcopy[c.path()] = of # remember for dir rename detection |
144 if c == ca and c2 == ca: # no merge needed, ignore copy | 145 if c == ca and c2 == ca: # no merge needed, ignore copy |
145 continue | 146 continue |
146 copy[c.path()] = of | 147 copy[c.path()] = of |
147 | 148 |
148 def dirs(files): | 149 def dirs(files): |
177 # generate a directory move map | 178 # generate a directory move map |
178 d1, d2 = dirs(m1), dirs(m2) | 179 d1, d2 = dirs(m1), dirs(m2) |
179 invalid = {} | 180 invalid = {} |
180 dirmove = {} | 181 dirmove = {} |
181 | 182 |
183 # examine each file copy for a potential directory move, which is | |
184 # when all the files in a directory are moved to a new directory | |
182 for dst, src in fullcopy.items(): | 185 for dst, src in fullcopy.items(): |
183 dsrc, ddst = os.path.dirname(src), os.path.dirname(dst) | 186 dsrc, ddst = os.path.dirname(src), os.path.dirname(dst) |
184 if dsrc in invalid: | 187 if dsrc in invalid: |
185 continue | 188 # already seen to be uninteresting |
186 elif (dsrc in d1 and ddst in d1) or (dsrc in d2 and ddst in d2): | 189 continue |
190 elif dsrc in d1 and ddst in d1: | |
191 # directory wasn't entirely moved locally | |
192 invalid[dsrc] = True | |
193 elif dsrc in d2 and ddst in d2: | |
194 # directory wasn't entirely moved remotely | |
187 invalid[dsrc] = True | 195 invalid[dsrc] = True |
188 elif dsrc in dirmove and dirmove[dsrc] != ddst: | 196 elif dsrc in dirmove and dirmove[dsrc] != ddst: |
197 # files from the same directory moved to two different places | |
189 invalid[dsrc] = True | 198 invalid[dsrc] = True |
190 del dirmove[dsrc] | 199 del dirmove[dsrc] |
191 else: | 200 else: |
201 # looks good so far | |
192 dirmove[dsrc + "/"] = ddst + "/" | 202 dirmove[dsrc + "/"] = ddst + "/" |
193 | 203 |
194 del d1, d2, invalid | 204 del d1, d2, invalid |
195 | 205 |
196 if not dirmove: | 206 if not dirmove: |
197 return copy | 207 return copy |
198 | 208 |
199 # check unaccounted nonoverlapping files | 209 # check unaccounted nonoverlapping files against directory moves |
200 for f in u1 + u2: | 210 for f in u1 + u2: |
201 if f not in fullcopy: | 211 if f not in fullcopy: |
202 for d in dirmove: | 212 for d in dirmove: |
203 if f.startswith(d): | 213 if f.startswith(d): |
214 # new file added in a directory that was moved, move it | |
204 copy[f] = dirmove[d] + f[len(d):] | 215 copy[f] = dirmove[d] + f[len(d):] |
205 break | 216 break |
206 | 217 |
207 return copy | 218 return copy |
208 | 219 |