Show More
@@ -0,0 +1,72 b'' | |||||
|
1 | #!/bin/sh | |||
|
2 | ||||
|
3 | "$TESTDIR/hghave" svn || exit 80 | |||
|
4 | ||||
|
5 | escapedwd=$(pwd | \ | |||
|
6 | python -c \ | |||
|
7 | "import sys,urllib; print urllib.pathname2url(sys.stdin.read().strip())" | |||
|
8 | ) | |||
|
9 | filterpath="sed s+$escapedwd+/root+" | |||
|
10 | ||||
|
11 | echo % create subversion repo | |||
|
12 | ||||
|
13 | SVNREPO="file://$escapedwd/svn-repo" | |||
|
14 | WCROOT="$(pwd)/svn-wc" | |||
|
15 | svnadmin create svn-repo | |||
|
16 | svn co $SVNREPO svn-wc | |||
|
17 | cd svn-wc | |||
|
18 | echo alpha > alpha | |||
|
19 | svn add alpha | |||
|
20 | svn ci -m 'Add alpha' | |||
|
21 | cd .. | |||
|
22 | ||||
|
23 | echo % create hg repo | |||
|
24 | ||||
|
25 | rm -rf sub | |||
|
26 | mkdir sub | |||
|
27 | cd sub | |||
|
28 | hg init t | |||
|
29 | cd t | |||
|
30 | ||||
|
31 | echo % first revision, no sub | |||
|
32 | echo a > a | |||
|
33 | hg ci -Am0 | |||
|
34 | ||||
|
35 | echo % add first svn sub | |||
|
36 | echo "s = [svn]$SVNREPO" >> .hgsub | |||
|
37 | svn co --quiet $SVNREPO s | |||
|
38 | hg add .hgsub | |||
|
39 | hg ci -m1 | |||
|
40 | echo % debugsub | |||
|
41 | hg debugsub | $filterpath | |||
|
42 | ||||
|
43 | echo | |||
|
44 | echo % change file in svn and hg, commit | |||
|
45 | echo a >> a | |||
|
46 | echo alpha >> s/alpha | |||
|
47 | hg commit -m 'Message!' | |||
|
48 | hg debugsub | $filterpath | |||
|
49 | ||||
|
50 | echo | |||
|
51 | echo a > s/a | |||
|
52 | echo % should be empty despite change to s/a | |||
|
53 | hg st | |||
|
54 | ||||
|
55 | echo | |||
|
56 | echo % add a commit from svn | |||
|
57 | pushd "$WCROOT" > /dev/null | |||
|
58 | svn up | |||
|
59 | echo xyz >> alpha | |||
|
60 | svn ci -m 'amend a from svn' | |||
|
61 | popd > /dev/null | |||
|
62 | echo % this commit from hg will fail | |||
|
63 | echo zzz >> s/alpha | |||
|
64 | hg ci -m 'amend alpha from hg' | |||
|
65 | ||||
|
66 | echo | |||
|
67 | echo % clone | |||
|
68 | cd .. | |||
|
69 | hg clone t tc | |||
|
70 | cd tc | |||
|
71 | echo % debugsub in clone | |||
|
72 | hg debugsub | $filterpath |
@@ -0,0 +1,48 b'' | |||||
|
1 | % create subversion repo | |||
|
2 | Checked out revision 0. | |||
|
3 | A alpha | |||
|
4 | Adding alpha | |||
|
5 | Transmitting file data . | |||
|
6 | Committed revision 1. | |||
|
7 | % create hg repo | |||
|
8 | % first revision, no sub | |||
|
9 | adding a | |||
|
10 | % add first svn sub | |||
|
11 | committing subrepository s | |||
|
12 | % debugsub | |||
|
13 | path s | |||
|
14 | source file:///root/svn-repo | |||
|
15 | revision 1 | |||
|
16 | ||||
|
17 | % change file in svn and hg, commit | |||
|
18 | committing subrepository s | |||
|
19 | Sending s/alpha | |||
|
20 | Transmitting file data . | |||
|
21 | Committed revision 2. | |||
|
22 | At revision 2. | |||
|
23 | path s | |||
|
24 | source file:///root/svn-repo | |||
|
25 | revision 2 | |||
|
26 | ||||
|
27 | % should be empty despite change to s/a | |||
|
28 | ||||
|
29 | % add a commit from svn | |||
|
30 | U alpha | |||
|
31 | Updated to revision 2. | |||
|
32 | Sending alpha | |||
|
33 | Transmitting file data . | |||
|
34 | Committed revision 3. | |||
|
35 | % this commit from hg will fail | |||
|
36 | committing subrepository s | |||
|
37 | abort: svn: Commit failed (details follow): | |||
|
38 | svn: File '/alpha' is out of date | |||
|
39 | ||||
|
40 | % clone | |||
|
41 | updating to branch default | |||
|
42 | A s/alpha | |||
|
43 | Checked out revision 2. | |||
|
44 | 3 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
|
45 | % debugsub in clone | |||
|
46 | path s | |||
|
47 | source file:///root/svn-repo | |||
|
48 | revision 2 |
@@ -32,7 +32,7 b' def timer(func, title=None):' | |||||
32 | def perfwalk(ui, repo, *pats): |
|
32 | def perfwalk(ui, repo, *pats): | |
33 | try: |
|
33 | try: | |
34 | m = cmdutil.match(repo, pats, {}) |
|
34 | m = cmdutil.match(repo, pats, {}) | |
35 | timer(lambda: len(list(repo.dirstate.walk(m, True, False)))) |
|
35 | timer(lambda: len(list(repo.dirstate.walk(m, [], True, False)))) | |
36 | except: |
|
36 | except: | |
37 | try: |
|
37 | try: | |
38 | m = cmdutil.match(repo, pats, {}) |
|
38 | m = cmdutil.match(repo, pats, {}) | |
@@ -150,4 +150,3 b' cmdtable = {' | |||||
150 | 'perftemplating': (perftemplating, []), |
|
150 | 'perftemplating': (perftemplating, []), | |
151 | 'perfdiffwd': (perfdiffwd, []), |
|
151 | 'perfdiffwd': (perfdiffwd, []), | |
152 | } |
|
152 | } | |
153 |
|
@@ -42,11 +42,11 b' def reposetup(ui, repo):' | |||||
42 | # to start an inotify server if it won't start. |
|
42 | # to start an inotify server if it won't start. | |
43 | _inotifyon = True |
|
43 | _inotifyon = True | |
44 |
|
44 | |||
45 | def status(self, match, ignored, clean, unknown=True): |
|
45 | def status(self, match, subrepos, ignored, clean, unknown=True): | |
46 | files = match.files() |
|
46 | files = match.files() | |
47 | if '.' in files: |
|
47 | if '.' in files: | |
48 | files = [] |
|
48 | files = [] | |
49 | if self._inotifyon and not ignored and not self._dirty: |
|
49 | if self._inotifyon and not ignored and not subrepos and not self._dirty: | |
50 | cli = client(ui, repo) |
|
50 | cli = client(ui, repo) | |
51 | try: |
|
51 | try: | |
52 | result = cli.statusquery(files, match, False, |
|
52 | result = cli.statusquery(files, match, False, | |
@@ -70,7 +70,7 b' def reposetup(ui, repo):' | |||||
70 | result = r2 |
|
70 | result = r2 | |
71 | return result |
|
71 | return result | |
72 | return super(inotifydirstate, self).status( |
|
72 | return super(inotifydirstate, self).status( | |
73 | match, ignored, clean, unknown) |
|
73 | match, subrepos, ignored, clean, unknown) | |
74 |
|
74 | |||
75 | repo.dirstate.__class__ = inotifydirstate |
|
75 | repo.dirstate.__class__ = inotifydirstate | |
76 |
|
76 |
@@ -638,7 +638,8 b' class workingctx(changectx):' | |||||
638 | return self._parents[0].ancestor(c2) # punt on two parents for now |
|
638 | return self._parents[0].ancestor(c2) # punt on two parents for now | |
639 |
|
639 | |||
640 | def walk(self, match): |
|
640 | def walk(self, match): | |
641 |
return sorted(self._repo.dirstate.walk(match, |
|
641 | return sorted(self._repo.dirstate.walk(match, self.substate.keys(), | |
|
642 | True, False)) | |||
642 |
|
643 | |||
643 | def dirty(self, missing=False): |
|
644 | def dirty(self, missing=False): | |
644 | "check whether a working directory is modified" |
|
645 | "check whether a working directory is modified" |
@@ -425,7 +425,7 b' class dirstate(object):' | |||||
425 | return True |
|
425 | return True | |
426 | return False |
|
426 | return False | |
427 |
|
427 | |||
428 | def walk(self, match, unknown, ignored): |
|
428 | def walk(self, match, subrepos, unknown, ignored): | |
429 | ''' |
|
429 | ''' | |
430 | Walk recursively through the directory tree, finding all files |
|
430 | Walk recursively through the directory tree, finding all files | |
431 | matched by match. |
|
431 | matched by match. | |
@@ -486,7 +486,8 b' class dirstate(object):' | |||||
486 | files = set(match.files()) |
|
486 | files = set(match.files()) | |
487 | if not files or '.' in files: |
|
487 | if not files or '.' in files: | |
488 | files = [''] |
|
488 | files = [''] | |
489 | results = {'.hg': None} |
|
489 | results = dict.fromkeys(subrepos) | |
|
490 | results['.hg'] = None | |||
490 |
|
491 | |||
491 | # step 1: find all explicit files |
|
492 | # step 1: find all explicit files | |
492 | for ff in sorted(files): |
|
493 | for ff in sorted(files): | |
@@ -564,11 +565,12 b' class dirstate(object):' | |||||
564 | if not st is None and not getkind(st.st_mode) in (regkind, lnkkind): |
|
565 | if not st is None and not getkind(st.st_mode) in (regkind, lnkkind): | |
565 | st = None |
|
566 | st = None | |
566 | results[nf] = st |
|
567 | results[nf] = st | |
567 |
|
568 | for s in subrepos: | ||
|
569 | del results[s] | |||
568 | del results['.hg'] |
|
570 | del results['.hg'] | |
569 | return results |
|
571 | return results | |
570 |
|
572 | |||
571 | def status(self, match, ignored, clean, unknown): |
|
573 | def status(self, match, subrepos, ignored, clean, unknown): | |
572 | '''Determine the status of the working copy relative to the |
|
574 | '''Determine the status of the working copy relative to the | |
573 | dirstate and return a tuple of lists (unsure, modified, added, |
|
575 | dirstate and return a tuple of lists (unsure, modified, added, | |
574 | removed, deleted, unknown, ignored, clean), where: |
|
576 | removed, deleted, unknown, ignored, clean), where: | |
@@ -609,7 +611,8 b' class dirstate(object):' | |||||
609 | dadd = deleted.append |
|
611 | dadd = deleted.append | |
610 | cadd = clean.append |
|
612 | cadd = clean.append | |
611 |
|
613 | |||
612 |
for fn, st in self.walk(match, listunknown, |
|
614 | for fn, st in self.walk(match, subrepos, listunknown, | |
|
615 | listignored).iteritems(): | |||
613 | if fn not in dmap: |
|
616 | if fn not in dmap: | |
614 | if (listignored or match.exact(fn)) and self._dirignore(fn): |
|
617 | if (listignored or match.exact(fn)) and self._dirignore(fn): | |
615 | if listignored: |
|
618 | if listignored: |
@@ -1000,7 +1000,9 b' class localrepository(repo.repository):' | |||||
1000 | match.bad = bad |
|
1000 | match.bad = bad | |
1001 |
|
1001 | |||
1002 | if working: # we need to scan the working dir |
|
1002 | if working: # we need to scan the working dir | |
1003 | s = self.dirstate.status(match, listignored, listclean, listunknown) |
|
1003 | subrepos = ctx1.substate.keys() | |
|
1004 | s = self.dirstate.status(match, subrepos, listignored, | |||
|
1005 | listclean, listunknown) | |||
1004 | cmp, modified, added, removed, deleted, unknown, ignored, clean = s |
|
1006 | cmp, modified, added, removed, deleted, unknown, ignored, clean = s | |
1005 |
|
1007 | |||
1006 | # check for any possibly clean files |
|
1008 | # check for any possibly clean files |
@@ -5,23 +5,23 b'' | |||||
5 | # This software may be used and distributed according to the terms of the |
|
5 | # This software may be used and distributed according to the terms of the | |
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, re | |
9 | from i18n import _ |
|
9 | from i18n import _ | |
10 | import config, util, node, error |
|
10 | import config, util, node, error | |
11 | hg = None |
|
11 | hg = None | |
12 |
|
12 | |||
13 | nullstate = ('', '') |
|
13 | nullstate = ('', '', 'empty') | |
14 |
|
14 | |||
15 | def state(ctx): |
|
15 | def state(ctx): | |
16 | p = config.config() |
|
16 | p = config.config() | |
17 | def read(f, sections=None, remap=None): |
|
17 | def read(f, sections=None, remap=None): | |
18 | if f in ctx: |
|
18 | if f in ctx: | |
19 | try: |
|
19 | p.parse(f, ctx[f].data(), sections, remap, read) | |
20 | p.parse(f, ctx[f].data(), sections, remap) |
|
20 | else: | |
21 | except IOError, err: |
|
21 | raise util.Abort(_("subrepo spec file %s not found") % f) | |
22 | if err.errno != errno.ENOENT: |
|
22 | ||
23 | raise |
|
23 | if '.hgsub' in ctx: | |
24 | read('.hgsub') |
|
24 | read('.hgsub') | |
25 |
|
25 | |||
26 | rev = {} |
|
26 | rev = {} | |
27 | if '.hgsubstate' in ctx: |
|
27 | if '.hgsubstate' in ctx: | |
@@ -35,7 +35,13 b' def state(ctx):' | |||||
35 |
|
35 | |||
36 | state = {} |
|
36 | state = {} | |
37 | for path, src in p[''].items(): |
|
37 | for path, src in p[''].items(): | |
38 | state[path] = (src, rev.get(path, '')) |
|
38 | kind = 'hg' | |
|
39 | if src.startswith('['): | |||
|
40 | if ']' not in src: | |||
|
41 | raise util.Abort(_('missing ] in subrepo source')) | |||
|
42 | kind, src = src.split(']', 1) | |||
|
43 | kind = kind[1:] | |||
|
44 | state[path] = (src, rev.get(path, ''), kind) | |||
39 |
|
45 | |||
40 | return state |
|
46 | return state | |
41 |
|
47 | |||
@@ -45,6 +51,7 b' def writestate(repo, state):' | |||||
45 | for s in sorted(state)]), '') |
|
51 | for s in sorted(state)]), '') | |
46 |
|
52 | |||
47 | def submerge(repo, wctx, mctx, actx): |
|
53 | def submerge(repo, wctx, mctx, actx): | |
|
54 | # working context, merging context, ancestor context | |||
48 | if mctx == actx: # backwards? |
|
55 | if mctx == actx: # backwards? | |
49 | actx = wctx.p1() |
|
56 | actx = wctx.p1() | |
50 | s1 = wctx.substate |
|
57 | s1 = wctx.substate | |
@@ -56,7 +63,7 b' def submerge(repo, wctx, mctx, actx):' | |||||
56 |
|
63 | |||
57 | def debug(s, msg, r=""): |
|
64 | def debug(s, msg, r=""): | |
58 | if r: |
|
65 | if r: | |
59 | r = "%s:%s" % r |
|
66 | r = "%s:%s:%s" % r | |
60 | repo.ui.debug(" subrepo %s: %s %s\n" % (s, msg, r)) |
|
67 | repo.ui.debug(" subrepo %s: %s %s\n" % (s, msg, r)) | |
61 |
|
68 | |||
62 | for s, l in s1.items(): |
|
69 | for s, l in s1.items(): | |
@@ -105,7 +112,7 b' def submerge(repo, wctx, mctx, actx):' | |||||
105 | continue |
|
112 | continue | |
106 | elif s not in sa: |
|
113 | elif s not in sa: | |
107 | debug(s, "remote added, get", r) |
|
114 | debug(s, "remote added, get", r) | |
108 |
|
|
115 | mctx.sub(s).get(r) | |
109 | sm[s] = r |
|
116 | sm[s] = r | |
110 | elif r != sa[s]: |
|
117 | elif r != sa[s]: | |
111 | if repo.ui.promptchoice( |
|
118 | if repo.ui.promptchoice( | |
@@ -145,9 +152,9 b' def subrepo(ctx, path):' | |||||
145 |
|
152 | |||
146 | util.path_auditor(ctx._repo.root)(path) |
|
153 | util.path_auditor(ctx._repo.root)(path) | |
147 | state = ctx.substate.get(path, nullstate) |
|
154 | state = ctx.substate.get(path, nullstate) | |
148 | if state[0].startswith('['): # future expansion |
|
155 | if state[2] not in types: | |
149 |
raise |
|
156 | raise util.Abort(_('unknown subrepo type %s') % t) | |
150 |
return |
|
157 | return types[state[2]](ctx, path, state[:2]) | |
151 |
|
158 | |||
152 | # subrepo classes need to implement the following methods: |
|
159 | # subrepo classes need to implement the following methods: | |
153 | # __init__(self, ctx, path, state) |
|
160 | # __init__(self, ctx, path, state) | |
@@ -204,7 +211,7 b' class hgsubrepo(object):' | |||||
204 | hg.clean(self._repo, node.nullid, False) |
|
211 | hg.clean(self._repo, node.nullid, False) | |
205 |
|
212 | |||
206 | def _get(self, state): |
|
213 | def _get(self, state): | |
207 | source, revision = state |
|
214 | source, revision, kind = state | |
208 | try: |
|
215 | try: | |
209 | self._repo.lookup(revision) |
|
216 | self._repo.lookup(revision) | |
210 | except error.RepoError: |
|
217 | except error.RepoError: | |
@@ -216,7 +223,7 b' class hgsubrepo(object):' | |||||
216 |
|
223 | |||
217 | def get(self, state): |
|
224 | def get(self, state): | |
218 | self._get(state) |
|
225 | self._get(state) | |
219 | source, revision = state |
|
226 | source, revision, kind = state | |
220 | self._repo.ui.debug("getting subrepo %s\n" % self._path) |
|
227 | self._repo.ui.debug("getting subrepo %s\n" % self._path) | |
221 | hg.clean(self._repo, revision, False) |
|
228 | hg.clean(self._repo, revision, False) | |
222 |
|
229 | |||
@@ -242,3 +249,89 b' class hgsubrepo(object):' | |||||
242 | dsturl = _abssource(self._repo, True) |
|
249 | dsturl = _abssource(self._repo, True) | |
243 | other = hg.repository(self._repo.ui, dsturl) |
|
250 | other = hg.repository(self._repo.ui, dsturl) | |
244 | self._repo.push(other, force) |
|
251 | self._repo.push(other, force) | |
|
252 | ||||
|
253 | class svnsubrepo(object): | |||
|
254 | def __init__(self, ctx, path, state): | |||
|
255 | self._path = path | |||
|
256 | self._state = state | |||
|
257 | self._ctx = ctx | |||
|
258 | self._ui = ctx._repo.ui | |||
|
259 | ||||
|
260 | def _svncommand(self, commands): | |||
|
261 | cmd = ['svn'] + commands + [self._path] | |||
|
262 | cmd = [util.shellquote(arg) for arg in cmd] | |||
|
263 | cmd = util.quotecommand(' '.join(cmd)) | |||
|
264 | write, read, err = util.popen3(cmd) | |||
|
265 | retdata = read.read() | |||
|
266 | err = err.read().strip() | |||
|
267 | if err: | |||
|
268 | raise util.Abort(err) | |||
|
269 | return retdata | |||
|
270 | ||||
|
271 | def _wcrev(self): | |||
|
272 | info = self._svncommand(['info']) | |||
|
273 | mat = re.search('Revision: ([\d]+)\n', info) | |||
|
274 | if not mat: | |||
|
275 | return 0 | |||
|
276 | return mat.groups()[0] | |||
|
277 | ||||
|
278 | def _url(self): | |||
|
279 | info = self._svncommand(['info']) | |||
|
280 | mat = re.search('URL: ([^\n]+)\n', info) | |||
|
281 | if not mat: | |||
|
282 | return 0 | |||
|
283 | return mat.groups()[0] | |||
|
284 | ||||
|
285 | def _wcclean(self): | |||
|
286 | status = self._svncommand(['status']) | |||
|
287 | status = '\n'.join([s for s in status.splitlines() if s[0] != '?']) | |||
|
288 | if status.strip(): | |||
|
289 | return False | |||
|
290 | return True | |||
|
291 | ||||
|
292 | def dirty(self): | |||
|
293 | if self._wcrev() == self._state[1] and self._wcclean(): | |||
|
294 | return False | |||
|
295 | return True | |||
|
296 | ||||
|
297 | def commit(self, text, user, date): | |||
|
298 | # user and date are out of our hands since svn is centralized | |||
|
299 | if self._wcclean(): | |||
|
300 | return self._wcrev() | |||
|
301 | commitinfo = self._svncommand(['commit', '-m', text]) | |||
|
302 | self._ui.status(commitinfo) | |||
|
303 | newrev = re.search('Committed revision ([\d]+).', commitinfo) | |||
|
304 | if not newrev: | |||
|
305 | raise util.Abort(commitinfo.splitlines()[-1]) | |||
|
306 | newrev = newrev.groups()[0] | |||
|
307 | self._ui.status(self._svncommand(['update', '-r', newrev])) | |||
|
308 | return newrev | |||
|
309 | ||||
|
310 | def remove(self): | |||
|
311 | if self.dirty(): | |||
|
312 | self._repo.ui.warn('Not removing repo %s because' | |||
|
313 | 'it has changes.\n' % self._path) | |||
|
314 | return | |||
|
315 | self._repo.ui.note('removing subrepo %s\n' % self._path) | |||
|
316 | shutil.rmtree(self._ctx.repo.join(self._path)) | |||
|
317 | ||||
|
318 | def get(self, state): | |||
|
319 | status = self._svncommand(['checkout', state[0], '--revision', state[1]]) | |||
|
320 | if not re.search('Checked out revision [\d]+.', status): | |||
|
321 | raise util.Abort(status.splitlines()[-1]) | |||
|
322 | self._ui.status(status) | |||
|
323 | ||||
|
324 | def merge(self, state): | |||
|
325 | old = int(self._state[1]) | |||
|
326 | new = int(state[1]) | |||
|
327 | if new > old: | |||
|
328 | self.get(state) | |||
|
329 | ||||
|
330 | def push(self, force): | |||
|
331 | # nothing for svn | |||
|
332 | pass | |||
|
333 | ||||
|
334 | types = { | |||
|
335 | 'hg': hgsubrepo, | |||
|
336 | 'svn': svnsubrepo, | |||
|
337 | } |
@@ -104,3 +104,9 b' cd ../tc' | |||||
104 | hg pull | sed 's/ .*sub/ ...sub/g' |
|
104 | hg pull | sed 's/ .*sub/ ...sub/g' | |
105 | hg up # should pull t |
|
105 | hg up # should pull t | |
106 | cat t/t |
|
106 | cat t/t | |
|
107 | ||||
|
108 | echo % bogus subrepo path aborts | |||
|
109 | echo 'bogus=[boguspath' >> .hgsub | |||
|
110 | hg ci -m 'bogus subrepo path' | |||
|
111 | ||||
|
112 | exit 0 |
@@ -57,7 +57,7 b' resolving manifests' | |||||
57 | ancestor 1f14a2e2d3ec local f0d2028bf86d+ remote 1831e14459c4 |
|
57 | ancestor 1f14a2e2d3ec local f0d2028bf86d+ remote 1831e14459c4 | |
58 | .hgsubstate: versions differ -> m |
|
58 | .hgsubstate: versions differ -> m | |
59 | subrepo merge f0d2028bf86d+ 1831e14459c4 1f14a2e2d3ec |
|
59 | subrepo merge f0d2028bf86d+ 1831e14459c4 1f14a2e2d3ec | |
60 | subrepo t: other changed, get t:6747d179aa9a688023c4b0cad32e4c92bb7f34ad |
|
60 | subrepo t: other changed, get t:6747d179aa9a688023c4b0cad32e4c92bb7f34ad:hg | |
61 | getting subrepo t |
|
61 | getting subrepo t | |
62 | resolving manifests |
|
62 | resolving manifests | |
63 | overwrite True partial False |
|
63 | overwrite True partial False | |
@@ -79,7 +79,7 b' resolving manifests' | |||||
79 | ancestor 1831e14459c4 local e45c8b14af55+ remote f94576341bcf |
|
79 | ancestor 1831e14459c4 local e45c8b14af55+ remote f94576341bcf | |
80 | .hgsubstate: versions differ -> m |
|
80 | .hgsubstate: versions differ -> m | |
81 | subrepo merge e45c8b14af55+ f94576341bcf 1831e14459c4 |
|
81 | subrepo merge e45c8b14af55+ f94576341bcf 1831e14459c4 | |
82 | subrepo t: both sides changed, merge with t:7af322bc1198a32402fe903e0b7ebcfc5c9bf8f4 |
|
82 | subrepo t: both sides changed, merge with t:7af322bc1198a32402fe903e0b7ebcfc5c9bf8f4:hg | |
83 | merging subrepo t |
|
83 | merging subrepo t | |
84 | searching for copies back to rev 2 |
|
84 | searching for copies back to rev 2 | |
85 | resolving manifests |
|
85 | resolving manifests | |
@@ -201,3 +201,5 b' adding file changes' | |||||
201 | added 1 changesets with 1 changes to 1 files |
|
201 | added 1 changesets with 1 changes to 1 files | |
202 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
202 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
203 | blah |
|
203 | blah | |
|
204 | % bogus subrepo path aborts | |||
|
205 | abort: missing ] in subrepo source |
General Comments 0
You need to be logged in to leave comments.
Login now