Show More
@@ -297,6 +297,8 b' def clone(ui, source, dest=None, pull=Fa' | |||||
297 | fp.write("default = %s\n" % abspath) |
|
297 | fp.write("default = %s\n" % abspath) | |
298 | fp.close() |
|
298 | fp.close() | |
299 |
|
299 | |||
|
300 | dest_repo.ui.setconfig('paths', 'default', abspath) | |||
|
301 | ||||
300 | if update: |
|
302 | if update: | |
301 | dest_repo.ui.status(_("updating working directory\n")) |
|
303 | dest_repo.ui.status(_("updating working directory\n")) | |
302 | if update is not True: |
|
304 | if update is not True: |
@@ -7,7 +7,7 b'' | |||||
7 |
|
7 | |||
8 | from node import nullid, nullrev, hex, bin |
|
8 | from node import nullid, nullrev, hex, bin | |
9 | from i18n import _ |
|
9 | from i18n import _ | |
10 | import util, filemerge, copies |
|
10 | import util, filemerge, copies, subrepo | |
11 | import errno, os, shutil |
|
11 | import errno, os, shutil | |
12 |
|
12 | |||
13 | class mergestate(object): |
|
13 | class mergestate(object): | |
@@ -241,12 +241,15 b' def applyupdates(repo, action, wctx, mct' | |||||
241 | ms.reset(wctx.parents()[0].node()) |
|
241 | ms.reset(wctx.parents()[0].node()) | |
242 | moves = [] |
|
242 | moves = [] | |
243 | action.sort(key=actionkey) |
|
243 | action.sort(key=actionkey) | |
|
244 | substate = wctx.substate # prime | |||
244 |
|
245 | |||
245 | # prescan for merges |
|
246 | # prescan for merges | |
246 | for a in action: |
|
247 | for a in action: | |
247 | f, m = a[:2] |
|
248 | f, m = a[:2] | |
248 | if m == 'm': # merge |
|
249 | if m == 'm': # merge | |
249 | f2, fd, flags, move = a[2:] |
|
250 | f2, fd, flags, move = a[2:] | |
|
251 | if f == '.hgsubstate': # merged internally | |||
|
252 | continue | |||
250 | repo.ui.debug(_("preserving %s for resolve of %s\n") % (f, fd)) |
|
253 | repo.ui.debug(_("preserving %s for resolve of %s\n") % (f, fd)) | |
251 | fcl = wctx[f] |
|
254 | fcl = wctx[f] | |
252 | fco = mctx[f2] |
|
255 | fco = mctx[f2] | |
@@ -270,6 +273,8 b' def applyupdates(repo, action, wctx, mct' | |||||
270 | if m == "r": # remove |
|
273 | if m == "r": # remove | |
271 | repo.ui.note(_("removing %s\n") % f) |
|
274 | repo.ui.note(_("removing %s\n") % f) | |
272 | audit_path(f) |
|
275 | audit_path(f) | |
|
276 | if f == '.hgsubstate': # subrepo states need updating | |||
|
277 | subrepo.submerge(repo, wctx, mctx, wctx) | |||
273 | try: |
|
278 | try: | |
274 | util.unlink(repo.wjoin(f)) |
|
279 | util.unlink(repo.wjoin(f)) | |
275 | except OSError, inst: |
|
280 | except OSError, inst: | |
@@ -278,6 +283,9 b' def applyupdates(repo, action, wctx, mct' | |||||
278 | (f, inst.strerror)) |
|
283 | (f, inst.strerror)) | |
279 | removed += 1 |
|
284 | removed += 1 | |
280 | elif m == "m": # merge |
|
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 | f2, fd, flags, move = a[2:] |
|
289 | f2, fd, flags, move = a[2:] | |
282 | r = ms.resolve(fd, wctx, mctx) |
|
290 | r = ms.resolve(fd, wctx, mctx) | |
283 | if r > 0: |
|
291 | if r > 0: | |
@@ -297,6 +305,8 b' def applyupdates(repo, action, wctx, mct' | |||||
297 | t = mctx.filectx(f).data() |
|
305 | t = mctx.filectx(f).data() | |
298 | repo.wwrite(f, t, flags) |
|
306 | repo.wwrite(f, t, flags) | |
299 | updated += 1 |
|
307 | updated += 1 | |
|
308 | if f == '.hgsubstate': # subrepo states need updating | |||
|
309 | subrepo.submerge(repo, wctx, mctx, wctx) | |||
300 | elif m == "d": # directory rename |
|
310 | elif m == "d": # directory rename | |
301 | f2, fd, flags = a[2:] |
|
311 | f2, fd, flags = a[2:] | |
302 | if f: |
|
312 | if f: |
@@ -6,8 +6,9 b'' | |||||
6 | # GNU General Public License version 2, incorporated herein by reference. |
|
6 | # GNU General Public License version 2, incorporated herein by reference. | |
7 |
|
7 | |||
8 | import errno, os |
|
8 | import errno, os | |
|
9 | from i18n import _ | |||
9 | import config, util, node, error |
|
10 | import config, util, node, error | |
10 | localrepo = None |
|
11 | localrepo = hg = None | |
11 |
|
12 | |||
12 | nullstate = ('', '') |
|
13 | nullstate = ('', '') | |
13 |
|
14 | |||
@@ -43,14 +44,81 b' def writestate(repo, state):' | |||||
43 | ''.join(['%s %s\n' % (state[s][1], s) |
|
44 | ''.join(['%s %s\n' % (state[s][1], s) | |
44 | for s in sorted(state)]), '') |
|
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 | def subrepo(ctx, path): |
|
113 | def subrepo(ctx, path): | |
47 | # subrepo inherently violates our import layering rules |
|
114 | # subrepo inherently violates our import layering rules | |
48 | # because it wants to make repo objects from deep inside the stack |
|
115 | # because it wants to make repo objects from deep inside the stack | |
49 | # so we manually delay the circular imports to not break |
|
116 | # so we manually delay the circular imports to not break | |
50 | # scripts that don't use our demand-loading |
|
117 | # scripts that don't use our demand-loading | |
51 | global localrepo |
|
118 | global localrepo, hg | |
52 | import localrepo as l |
|
119 | import localrepo as l, hg as h | |
53 | localrepo = l |
|
120 | localrepo = l | |
|
121 | hg = h | |||
54 |
|
122 | |||
55 | state = ctx.substate.get(path, nullstate) |
|
123 | state = ctx.substate.get(path, nullstate) | |
56 | if state[0].startswith('['): # future expansion |
|
124 | if state[0].startswith('['): # future expansion | |
@@ -64,7 +132,13 b' class hgsubrepo(object):' | |||||
64 | self._state = state |
|
132 | self._state = state | |
65 | r = ctx._repo |
|
133 | r = ctx._repo | |
66 | root = r.wjoin(path) |
|
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 | def dirty(self): |
|
143 | def dirty(self): | |
70 | r = self._state[1] |
|
144 | r = self._state[1] | |
@@ -80,3 +154,25 b' class hgsubrepo(object):' | |||||
80 | if not n: |
|
154 | if not n: | |
81 | return self._repo['.'].hex() # different version checked out |
|
155 | return self._repo['.'].hex() # different version checked out | |
82 | return node.hex(n) |
|
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