##// END OF EJS Templates
merge: privatize some functions, unnest some others
Matt Mackall -
r6269:ffdf70e7 default
parent child Browse files
Show More
@@ -9,7 +9,7 b' from node import nullid, nullrev'
9 from i18n import _
9 from i18n import _
10 import errno, util, os, heapq, filemerge
10 import errno, util, os, heapq, filemerge
11
11
12 def checkunknown(wctx, mctx):
12 def _checkunknown(wctx, mctx):
13 "check for collisions between unknown files and files in mctx"
13 "check for collisions between unknown files and files in mctx"
14 man = mctx.manifest()
14 man = mctx.manifest()
15 for f in wctx.unknown():
15 for f in wctx.unknown():
@@ -19,7 +19,7 b' def checkunknown(wctx, mctx):'
19 " from file in requested revision: '%s'")
19 " from file in requested revision: '%s'")
20 % f)
20 % f)
21
21
22 def checkcollision(mctx):
22 def _checkcollision(mctx):
23 "check for case folding collisions in the destination context"
23 "check for case folding collisions in the destination context"
24 folded = {}
24 folded = {}
25 for fn in mctx.manifest():
25 for fn in mctx.manifest():
@@ -29,7 +29,7 b' def checkcollision(mctx):'
29 % (fn, folded[fold]))
29 % (fn, folded[fold]))
30 folded[fold] = fn
30 folded[fold] = fn
31
31
32 def forgetremoved(wctx, mctx, branchmerge):
32 def _forgetremoved(wctx, mctx, branchmerge):
33 """
33 """
34 Forget removed files
34 Forget removed files
35
35
@@ -58,32 +58,54 b' def forgetremoved(wctx, mctx, branchmerg'
58
58
59 return action
59 return action
60
60
61 def _nonoverlap(d1, d2, d3):
62 "Return list of elements in d1 not in d2 or d3"
63 l = [d for d in d1 if d not in d3 and d not in d2]
64 l.sort()
65 return l
66
67 def _dirname(f):
68 s = f.rfind("/")
69 if s == -1:
70 return ""
71 return f[:s]
72
73 def _dirs(files):
74 d = {}
75 for f in files:
76 f = _dirname(f)
77 while f not in d:
78 d[f] = True
79 f = _dirname(f)
80 return d
81
82 def _findoldnames(fctx, limit):
83 "find files that path was copied from, back to linkrev limit"
84 old = {}
85 seen = {}
86 orig = fctx.path()
87 visit = [fctx]
88 while visit:
89 fc = visit.pop()
90 s = str(fc)
91 if s in seen:
92 continue
93 seen[s] = 1
94 if fc.path() != orig and fc.path() not in old:
95 old[fc.path()] = 1
96 if fc.rev() < limit:
97 continue
98 visit += fc.parents()
99
100 old = old.keys()
101 old.sort()
102 return old
103
61 def findcopies(repo, m1, m2, ma, limit):
104 def findcopies(repo, m1, m2, ma, limit):
62 """
105 """
63 Find moves and copies between m1 and m2 back to limit linkrev
106 Find moves and copies between m1 and m2 back to limit linkrev
64 """
107 """
65
108
66 def nonoverlap(d1, d2, d3):
67 "Return list of elements in d1 not in d2 or d3"
68 l = [d for d in d1 if d not in d3 and d not in d2]
69 l.sort()
70 return l
71
72 def dirname(f):
73 s = f.rfind("/")
74 if s == -1:
75 return ""
76 return f[:s]
77
78 def dirs(files):
79 d = {}
80 for f in files:
81 f = dirname(f)
82 while f not in d:
83 d[f] = True
84 f = dirname(f)
85 return d
86
87 wctx = repo.workingctx()
109 wctx = repo.workingctx()
88
110
89 def makectx(f, n):
111 def makectx(f, n):
@@ -92,35 +114,13 b' def findcopies(repo, m1, m2, ma, limit):'
92 return wctx.filectx(f)
114 return wctx.filectx(f)
93 ctx = util.cachefunc(makectx)
115 ctx = util.cachefunc(makectx)
94
116
95 def findold(fctx):
96 "find files that path was copied from, back to linkrev limit"
97 old = {}
98 seen = {}
99 orig = fctx.path()
100 visit = [fctx]
101 while visit:
102 fc = visit.pop()
103 s = str(fc)
104 if s in seen:
105 continue
106 seen[s] = 1
107 if fc.path() != orig and fc.path() not in old:
108 old[fc.path()] = 1
109 if fc.rev() < limit and fc.rev() is not None:
110 continue
111 visit += fc.parents()
112
113 old = old.keys()
114 old.sort()
115 return old
116
117 copy = {}
117 copy = {}
118 fullcopy = {}
118 fullcopy = {}
119 diverge = {}
119 diverge = {}
120
120
121 def checkcopies(c, man, aman):
121 def checkcopies(c, man, aman):
122 '''check possible copies for filectx c'''
122 '''check possible copies for filectx c'''
123 for of in findold(c):
123 for of in _findoldnames(c, limit):
124 fullcopy[c.path()] = of # remember for dir rename detection
124 fullcopy[c.path()] = of # remember for dir rename detection
125 if of not in man: # original file not in other manifest?
125 if of not in man: # original file not in other manifest?
126 if of in ma:
126 if of in ma:
@@ -149,8 +149,8 b' def findcopies(repo, m1, m2, ma, limit):'
149
149
150 repo.ui.debug(_(" searching for copies back to rev %d\n") % limit)
150 repo.ui.debug(_(" searching for copies back to rev %d\n") % limit)
151
151
152 u1 = nonoverlap(m1, m2, ma)
152 u1 = _nonoverlap(m1, m2, ma)
153 u2 = nonoverlap(m2, m1, ma)
153 u2 = _nonoverlap(m2, m1, ma)
154
154
155 if u1:
155 if u1:
156 repo.ui.debug(_(" unmatched files in local:\n %s\n")
156 repo.ui.debug(_(" unmatched files in local:\n %s\n")
@@ -188,14 +188,14 b' def findcopies(repo, m1, m2, ma, limit):'
188 repo.ui.debug(_(" checking for directory renames\n"))
188 repo.ui.debug(_(" checking for directory renames\n"))
189
189
190 # generate a directory move map
190 # generate a directory move map
191 d1, d2 = dirs(m1), dirs(m2)
191 d1, d2 = _dirs(m1), _dirs(m2)
192 invalid = {}
192 invalid = {}
193 dirmove = {}
193 dirmove = {}
194
194
195 # examine each file copy for a potential directory move, which is
195 # examine each file copy for a potential directory move, which is
196 # when all the files in a directory are moved to a new directory
196 # when all the files in a directory are moved to a new directory
197 for dst, src in fullcopy.items():
197 for dst, src in fullcopy.items():
198 dsrc, ddst = dirname(src), dirname(dst)
198 dsrc, ddst = _dirname(src), _dirname(dst)
199 if dsrc in invalid:
199 if dsrc in invalid:
200 # already seen to be uninteresting
200 # already seen to be uninteresting
201 continue
201 continue
@@ -236,7 +236,7 b' def findcopies(repo, m1, m2, ma, limit):'
236
236
237 return copy, diverge
237 return copy, diverge
238
238
239 def symmetricdifference(repo, rev1, rev2):
239 def _symmetricdifference(repo, rev1, rev2):
240 """symmetric difference of the sets of ancestors of rev1 and rev2
240 """symmetric difference of the sets of ancestors of rev1 and rev2
241
241
242 I.e. revisions that are ancestors of rev1 or rev2, but not both.
242 I.e. revisions that are ancestors of rev1 or rev2, but not both.
@@ -340,7 +340,7 b' def manifestmerge(repo, p1, p2, pa, over'
340 if rev1 is None:
340 if rev1 is None:
341 # p1 is a workingctx
341 # p1 is a workingctx
342 rev1 = p1.parents()[0].rev()
342 rev1 = p1.parents()[0].rev()
343 limit = min(symmetricdifference(repo, rev1, p2.rev()))
343 limit = min(_symmetricdifference(repo, rev1, p2.rev()))
344 copy, diverge = findcopies(repo, m1, m2, ma, limit)
344 copy, diverge = findcopies(repo, m1, m2, ma, limit)
345
345
346 for of, fl in diverge.items():
346 for of, fl in diverge.items():
@@ -615,10 +615,10 b' def update(repo, node, branchmerge, forc'
615 ### calculate phase
615 ### calculate phase
616 action = []
616 action = []
617 if not force:
617 if not force:
618 checkunknown(wc, p2)
618 _checkunknown(wc, p2)
619 if not util.checkfolding(repo.path):
619 if not util.checkfolding(repo.path):
620 checkcollision(p2)
620 _checkcollision(p2)
621 action += forgetremoved(wc, p2, branchmerge)
621 action += _forgetremoved(wc, p2, branchmerge)
622 action += manifestmerge(repo, wc, p2, pa, overwrite, partial)
622 action += manifestmerge(repo, wc, p2, pa, overwrite, partial)
623
623
624 ### apply phase
624 ### apply phase
General Comments 0
You need to be logged in to leave comments. Login now