##// END OF EJS Templates
subrepo: add update/merge logic
Matt Mackall -
r8814:ab668c92 default
parent child Browse files
Show More
@@ -297,6 +297,8 b' def clone(ui, source, dest=None, pull=Fa'
297 297 fp.write("default = %s\n" % abspath)
298 298 fp.close()
299 299
300 dest_repo.ui.setconfig('paths', 'default', abspath)
301
300 302 if update:
301 303 dest_repo.ui.status(_("updating working directory\n"))
302 304 if update is not True:
@@ -7,7 +7,7 b''
7 7
8 8 from node import nullid, nullrev, hex, bin
9 9 from i18n import _
10 import util, filemerge, copies
10 import util, filemerge, copies, subrepo
11 11 import errno, os, shutil
12 12
13 13 class mergestate(object):
@@ -241,12 +241,15 b' def applyupdates(repo, action, wctx, mct'
241 241 ms.reset(wctx.parents()[0].node())
242 242 moves = []
243 243 action.sort(key=actionkey)
244 substate = wctx.substate # prime
244 245
245 246 # prescan for merges
246 247 for a in action:
247 248 f, m = a[:2]
248 249 if m == 'm': # merge
249 250 f2, fd, flags, move = a[2:]
251 if f == '.hgsubstate': # merged internally
252 continue
250 253 repo.ui.debug(_("preserving %s for resolve of %s\n") % (f, fd))
251 254 fcl = wctx[f]
252 255 fco = mctx[f2]
@@ -270,6 +273,8 b' def applyupdates(repo, action, wctx, mct'
270 273 if m == "r": # remove
271 274 repo.ui.note(_("removing %s\n") % f)
272 275 audit_path(f)
276 if f == '.hgsubstate': # subrepo states need updating
277 subrepo.submerge(repo, wctx, mctx, wctx)
273 278 try:
274 279 util.unlink(repo.wjoin(f))
275 280 except OSError, inst:
@@ -278,6 +283,9 b' def applyupdates(repo, action, wctx, mct'
278 283 (f, inst.strerror))
279 284 removed += 1
280 285 elif m == "m": # merge
286 if f == '.hgsubstate': # subrepo states need updating
287 subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx))
288 continue
281 289 f2, fd, flags, move = a[2:]
282 290 r = ms.resolve(fd, wctx, mctx)
283 291 if r > 0:
@@ -297,6 +305,8 b' def applyupdates(repo, action, wctx, mct'
297 305 t = mctx.filectx(f).data()
298 306 repo.wwrite(f, t, flags)
299 307 updated += 1
308 if f == '.hgsubstate': # subrepo states need updating
309 subrepo.submerge(repo, wctx, mctx, wctx)
300 310 elif m == "d": # directory rename
301 311 f2, fd, flags = a[2:]
302 312 if f:
@@ -6,8 +6,9 b''
6 6 # GNU General Public License version 2, incorporated herein by reference.
7 7
8 8 import errno, os
9 from i18n import _
9 10 import config, util, node, error
10 localrepo = None
11 localrepo = hg = None
11 12
12 13 nullstate = ('', '')
13 14
@@ -43,14 +44,81 b' def writestate(repo, state):'
43 44 ''.join(['%s %s\n' % (state[s][1], s)
44 45 for s in sorted(state)]), '')
45 46
47 def submerge(repo, wctx, mctx, actx):
48 if mctx == actx: # backwards?
49 actx = wctx.p1()
50 s1 = wctx.substate
51 s2 = mctx.substate
52 sa = actx.substate
53 sm = {}
54
55 for s, l in s1.items():
56 a = sa.get(s, nullstate)
57 if s in s2:
58 r = s2[s]
59 if l == r or r == a: # no change or local is newer
60 sm[s] = l
61 continue
62 elif l == a: # other side changed
63 wctx.sub(s).get(r)
64 sm[s] = r
65 elif l[0] != r[0]: # sources differ
66 if repo.ui.prompt(
67 _(' subrepository sources for %s differ\n'
68 'use (l)ocal source (%s) or (r)emote source (%s)?'
69 % (s, l[0], r[0]),
70 (_('&Local'), _('&Remote')), _('l'))) == _('r'):
71 wctx.sub(s).get(r)
72 sm[s] = r
73 elif l[1] == a[1]: # local side is unchanged
74 wctx.sub(s).get(r)
75 sm[s] = r
76 else:
77 wctx.sub(s).merge(r)
78 sm[s] = l
79 elif l == a: # remote removed, local unchanged
80 wctx.sub(s).remove()
81 else:
82 if repo.ui.prompt(
83 _(' local changed subrepository %s which remote removed\n'
84 'use (c)hanged version or (d)elete?' % s,
85 (_('&Changed'), _('&Delete')), _('c'))) == _('d'):
86 wctx.sub(s).remove()
87
88 for s, r in s2.items():
89 if s in s1:
90 continue
91 elif s not in sa:
92 wctx.sub(s).get(r)
93 sm[s] = r
94 elif r != sa[s]:
95 if repo.ui.prompt(
96 _(' remote changed subrepository %s which local removed\n'
97 'use (c)hanged version or (d)elete?' % s,
98 (_('&Changed'), _('&Delete')), _('c'))) == _('c'):
99 wctx.sub(s).get(r)
100 sm[s] = r
101
102 # record merged .hgsubstate
103 writestate(repo, sm)
104
105 def _abssource(repo):
106 if hasattr(repo, '_subparent'):
107 source = repo._subsource
108 if source.startswith('/') or '://' in source:
109 return source
110 return os.path.join(_abssource(repo._subparent), repo._subsource)
111 return repo.ui.config('paths', 'default', repo.root)
112
46 113 def subrepo(ctx, path):
47 114 # subrepo inherently violates our import layering rules
48 115 # because it wants to make repo objects from deep inside the stack
49 116 # so we manually delay the circular imports to not break
50 117 # scripts that don't use our demand-loading
51 global localrepo
52 import localrepo as l
118 global localrepo, hg
119 import localrepo as l, hg as h
53 120 localrepo = l
121 hg = h
54 122
55 123 state = ctx.substate.get(path, nullstate)
56 124 if state[0].startswith('['): # future expansion
@@ -64,7 +132,13 b' class hgsubrepo(object):'
64 132 self._state = state
65 133 r = ctx._repo
66 134 root = r.wjoin(path)
67 self._repo = localrepo.localrepository(r.ui, root)
135 if os.path.exists(os.path.join(root, '.hg')):
136 self._repo = localrepo.localrepository(r.ui, root)
137 else:
138 util.makedirs(root)
139 self._repo = localrepo.localrepository(r.ui, root, create=True)
140 self._repo._subparent = r
141 self._repo._subsource = state[0]
68 142
69 143 def dirty(self):
70 144 r = self._state[1]
@@ -80,3 +154,25 b' class hgsubrepo(object):'
80 154 if not n:
81 155 return self._repo['.'].hex() # different version checked out
82 156 return node.hex(n)
157
158 def remove(self):
159 # we can't fully delete the repository as it may contain
160 # local-only history
161 self._repo.ui.note(_('removing subrepo %s\n') % self._path)
162 hg.clean(self._repo, node.nullid, False)
163
164 def get(self, state):
165 source, revision = state
166 try:
167 self._repo.lookup(revision)
168 except error.RepoError:
169 self._repo._subsource = source
170 self._repo.ui.status(_('pulling subrepo %s\n') % self._path)
171 srcurl = _abssource(self._repo)
172 other = hg.repository(self._repo.ui, srcurl)
173 self._repo.pull(other)
174
175 hg.clean(self._repo, revision, False)
176
177 def merge(self, state):
178 hg.merge(self._repo, state[1], remind=False)
General Comments 0
You need to be logged in to leave comments. Login now