##// END OF EJS Templates
diff: support diffing explicit files in subrepos...
Matt Harbison -
r42177:db26dbbe default
parent child Browse files
Show More
@@ -1,169 +1,171 b''
1 Subrepositories let you nest external repositories or projects into a
1 Subrepositories let you nest external repositories or projects into a
2 parent Mercurial repository, and make commands operate on them as a
2 parent Mercurial repository, and make commands operate on them as a
3 group.
3 group.
4
4
5 Mercurial currently supports Mercurial, Git, and Subversion
5 Mercurial currently supports Mercurial, Git, and Subversion
6 subrepositories.
6 subrepositories.
7
7
8 Subrepositories are made of three components:
8 Subrepositories are made of three components:
9
9
10 1. Nested repository checkouts. They can appear anywhere in the
10 1. Nested repository checkouts. They can appear anywhere in the
11 parent working directory.
11 parent working directory.
12
12
13 2. Nested repository references. They are defined in ``.hgsub``, which
13 2. Nested repository references. They are defined in ``.hgsub``, which
14 should be placed in the root of working directory, and
14 should be placed in the root of working directory, and
15 tell where the subrepository checkouts come from. Mercurial
15 tell where the subrepository checkouts come from. Mercurial
16 subrepositories are referenced like::
16 subrepositories are referenced like::
17
17
18 path/to/nested = https://example.com/nested/repo/path
18 path/to/nested = https://example.com/nested/repo/path
19
19
20 Git and Subversion subrepos are also supported::
20 Git and Subversion subrepos are also supported::
21
21
22 path/to/nested = [git]git://example.com/nested/repo/path
22 path/to/nested = [git]git://example.com/nested/repo/path
23 path/to/nested = [svn]https://example.com/nested/trunk/path
23 path/to/nested = [svn]https://example.com/nested/trunk/path
24
24
25 where ``path/to/nested`` is the checkout location relatively to the
25 where ``path/to/nested`` is the checkout location relatively to the
26 parent Mercurial root, and ``https://example.com/nested/repo/path``
26 parent Mercurial root, and ``https://example.com/nested/repo/path``
27 is the source repository path. The source can also reference a
27 is the source repository path. The source can also reference a
28 filesystem path.
28 filesystem path.
29
29
30 Note that ``.hgsub`` does not exist by default in Mercurial
30 Note that ``.hgsub`` does not exist by default in Mercurial
31 repositories, you have to create and add it to the parent
31 repositories, you have to create and add it to the parent
32 repository before using subrepositories.
32 repository before using subrepositories.
33
33
34 3. Nested repository states. They are defined in ``.hgsubstate``, which
34 3. Nested repository states. They are defined in ``.hgsubstate``, which
35 is placed in the root of working directory, and
35 is placed in the root of working directory, and
36 capture whatever information is required to restore the
36 capture whatever information is required to restore the
37 subrepositories to the state they were committed in a parent
37 subrepositories to the state they were committed in a parent
38 repository changeset. Mercurial automatically record the nested
38 repository changeset. Mercurial automatically record the nested
39 repositories states when committing in the parent repository.
39 repositories states when committing in the parent repository.
40
40
41 .. note::
41 .. note::
42
42
43 The ``.hgsubstate`` file should not be edited manually.
43 The ``.hgsubstate`` file should not be edited manually.
44
44
45
45
46 Adding a Subrepository
46 Adding a Subrepository
47 ======================
47 ======================
48
48
49 If ``.hgsub`` does not exist, create it and add it to the parent
49 If ``.hgsub`` does not exist, create it and add it to the parent
50 repository. Clone or checkout the external projects where you want it
50 repository. Clone or checkout the external projects where you want it
51 to live in the parent repository. Edit ``.hgsub`` and add the
51 to live in the parent repository. Edit ``.hgsub`` and add the
52 subrepository entry as described above. At this point, the
52 subrepository entry as described above. At this point, the
53 subrepository is tracked and the next commit will record its state in
53 subrepository is tracked and the next commit will record its state in
54 ``.hgsubstate`` and bind it to the committed changeset.
54 ``.hgsubstate`` and bind it to the committed changeset.
55
55
56 Synchronizing a Subrepository
56 Synchronizing a Subrepository
57 =============================
57 =============================
58
58
59 Subrepos do not automatically track the latest changeset of their
59 Subrepos do not automatically track the latest changeset of their
60 sources. Instead, they are updated to the changeset that corresponds
60 sources. Instead, they are updated to the changeset that corresponds
61 with the changeset checked out in the top-level changeset. This is so
61 with the changeset checked out in the top-level changeset. This is so
62 developers always get a consistent set of compatible code and
62 developers always get a consistent set of compatible code and
63 libraries when they update.
63 libraries when they update.
64
64
65 Thus, updating subrepos is a manual process. Simply check out target
65 Thus, updating subrepos is a manual process. Simply check out target
66 subrepo at the desired revision, test in the top-level repo, then
66 subrepo at the desired revision, test in the top-level repo, then
67 commit in the parent repository to record the new combination.
67 commit in the parent repository to record the new combination.
68
68
69 Deleting a Subrepository
69 Deleting a Subrepository
70 ========================
70 ========================
71
71
72 To remove a subrepository from the parent repository, delete its
72 To remove a subrepository from the parent repository, delete its
73 reference from ``.hgsub``, then remove its files.
73 reference from ``.hgsub``, then remove its files.
74
74
75 Interaction with Mercurial Commands
75 Interaction with Mercurial Commands
76 ===================================
76 ===================================
77
77
78 :add: add does not recurse in subrepos unless -S/--subrepos is
78 :add: add does not recurse in subrepos unless -S/--subrepos is
79 specified. However, if you specify the full path of a file in a
79 specified. However, if you specify the full path of a file in a
80 subrepo, it will be added even without -S/--subrepos specified.
80 subrepo, it will be added even without -S/--subrepos specified.
81 Subversion subrepositories are currently silently
81 Subversion subrepositories are currently silently
82 ignored.
82 ignored.
83
83
84 :addremove: addremove does not recurse into subrepos unless
84 :addremove: addremove does not recurse into subrepos unless
85 -S/--subrepos is specified. However, if you specify the full
85 -S/--subrepos is specified. However, if you specify the full
86 path of a directory in a subrepo, addremove will be performed on
86 path of a directory in a subrepo, addremove will be performed on
87 it even without -S/--subrepos being specified. Git and
87 it even without -S/--subrepos being specified. Git and
88 Subversion subrepositories will print a warning and continue.
88 Subversion subrepositories will print a warning and continue.
89
89
90 :archive: archive does not recurse in subrepositories unless
90 :archive: archive does not recurse in subrepositories unless
91 -S/--subrepos is specified.
91 -S/--subrepos is specified.
92
92
93 :cat: Git subrepositories only support exact file matches.
93 :cat: Git subrepositories only support exact file matches.
94 Subversion subrepositories are currently ignored.
94 Subversion subrepositories are currently ignored.
95
95
96 :commit: commit creates a consistent snapshot of the state of the
96 :commit: commit creates a consistent snapshot of the state of the
97 entire project and its subrepositories. If any subrepositories
97 entire project and its subrepositories. If any subrepositories
98 have been modified, Mercurial will abort. Mercurial can be made
98 have been modified, Mercurial will abort. Mercurial can be made
99 to instead commit all modified subrepositories by specifying
99 to instead commit all modified subrepositories by specifying
100 -S/--subrepos, or setting "ui.commitsubrepos=True" in a
100 -S/--subrepos, or setting "ui.commitsubrepos=True" in a
101 configuration file (see :hg:`help config`). After there are no
101 configuration file (see :hg:`help config`). After there are no
102 longer any modified subrepositories, it records their state and
102 longer any modified subrepositories, it records their state and
103 finally commits it in the parent repository. The --addremove
103 finally commits it in the parent repository. The --addremove
104 option also honors the -S/--subrepos option. However, Git and
104 option also honors the -S/--subrepos option. However, Git and
105 Subversion subrepositories will print a warning and abort.
105 Subversion subrepositories will print a warning and abort.
106
106
107 :diff: diff does not recurse in subrepos unless -S/--subrepos is
107 :diff: diff does not recurse in subrepos unless -S/--subrepos is
108 specified. Changes are displayed as usual, on the subrepositories
108 specified. However, if you specify the full path of a file or
109 elements. Subversion subrepositories are currently silently ignored.
109 directory in a subrepo, it will be diffed even without
110 -S/--subrepos being specified. Subversion subrepositories are
111 currently silently ignored.
110
112
111 :files: files does not recurse into subrepos unless -S/--subrepos is
113 :files: files does not recurse into subrepos unless -S/--subrepos is
112 specified. However, if you specify the full path of a file or
114 specified. However, if you specify the full path of a file or
113 directory in a subrepo, it will be displayed even without
115 directory in a subrepo, it will be displayed even without
114 -S/--subrepos being specified. Git and Subversion subrepositories
116 -S/--subrepos being specified. Git and Subversion subrepositories
115 are currently silently ignored.
117 are currently silently ignored.
116
118
117 :forget: forget currently only handles exact file matches in subrepos.
119 :forget: forget currently only handles exact file matches in subrepos.
118 Git and Subversion subrepositories are currently silently ignored.
120 Git and Subversion subrepositories are currently silently ignored.
119
121
120 :incoming: incoming does not recurse in subrepos unless -S/--subrepos
122 :incoming: incoming does not recurse in subrepos unless -S/--subrepos
121 is specified. Git and Subversion subrepositories are currently
123 is specified. Git and Subversion subrepositories are currently
122 silently ignored.
124 silently ignored.
123
125
124 :outgoing: outgoing does not recurse in subrepos unless -S/--subrepos
126 :outgoing: outgoing does not recurse in subrepos unless -S/--subrepos
125 is specified. Git and Subversion subrepositories are currently
127 is specified. Git and Subversion subrepositories are currently
126 silently ignored.
128 silently ignored.
127
129
128 :pull: pull is not recursive since it is not clear what to pull prior
130 :pull: pull is not recursive since it is not clear what to pull prior
129 to running :hg:`update`. Listing and retrieving all
131 to running :hg:`update`. Listing and retrieving all
130 subrepositories changes referenced by the parent repository pulled
132 subrepositories changes referenced by the parent repository pulled
131 changesets is expensive at best, impossible in the Subversion
133 changesets is expensive at best, impossible in the Subversion
132 case.
134 case.
133
135
134 :push: Mercurial will automatically push all subrepositories first
136 :push: Mercurial will automatically push all subrepositories first
135 when the parent repository is being pushed. This ensures new
137 when the parent repository is being pushed. This ensures new
136 subrepository changes are available when referenced by top-level
138 subrepository changes are available when referenced by top-level
137 repositories. Push is a no-op for Subversion subrepositories.
139 repositories. Push is a no-op for Subversion subrepositories.
138
140
139 :serve: serve does not recurse into subrepositories unless
141 :serve: serve does not recurse into subrepositories unless
140 -S/--subrepos is specified. Git and Subversion subrepositories
142 -S/--subrepos is specified. Git and Subversion subrepositories
141 are currently silently ignored.
143 are currently silently ignored.
142
144
143 :status: status does not recurse into subrepositories unless
145 :status: status does not recurse into subrepositories unless
144 -S/--subrepos is specified. Subrepository changes are displayed as
146 -S/--subrepos is specified. Subrepository changes are displayed as
145 regular Mercurial changes on the subrepository
147 regular Mercurial changes on the subrepository
146 elements. Subversion subrepositories are currently silently
148 elements. Subversion subrepositories are currently silently
147 ignored.
149 ignored.
148
150
149 :remove: remove does not recurse into subrepositories unless
151 :remove: remove does not recurse into subrepositories unless
150 -S/--subrepos is specified. However, if you specify a file or
152 -S/--subrepos is specified. However, if you specify a file or
151 directory path in a subrepo, it will be removed even without
153 directory path in a subrepo, it will be removed even without
152 -S/--subrepos. Git and Subversion subrepositories are currently
154 -S/--subrepos. Git and Subversion subrepositories are currently
153 silently ignored.
155 silently ignored.
154
156
155 :update: update restores the subrepos in the state they were
157 :update: update restores the subrepos in the state they were
156 originally committed in target changeset. If the recorded
158 originally committed in target changeset. If the recorded
157 changeset is not available in the current subrepository, Mercurial
159 changeset is not available in the current subrepository, Mercurial
158 will pull it in first before updating. This means that updating
160 will pull it in first before updating. This means that updating
159 can require network access when using subrepositories.
161 can require network access when using subrepositories.
160
162
161 Remapping Subrepositories Sources
163 Remapping Subrepositories Sources
162 =================================
164 =================================
163
165
164 A subrepository source location may change during a project life,
166 A subrepository source location may change during a project life,
165 invalidating references stored in the parent repository history. To
167 invalidating references stored in the parent repository history. To
166 fix this, rewriting rules can be defined in parent repository ``hgrc``
168 fix this, rewriting rules can be defined in parent repository ``hgrc``
167 file or in Mercurial configuration. See the ``[subpaths]`` section in
169 file or in Mercurial configuration. See the ``[subpaths]`` section in
168 hgrc(5) for more details.
170 hgrc(5) for more details.
169
171
@@ -1,938 +1,938 b''
1 # logcmdutil.py - utility for log-like commands
1 # logcmdutil.py - utility for log-like commands
2 #
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
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 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import itertools
10 import itertools
11 import os
11 import os
12 import posixpath
12 import posixpath
13
13
14 from .i18n import _
14 from .i18n import _
15 from .node import (
15 from .node import (
16 nullid,
16 nullid,
17 wdirid,
17 wdirid,
18 wdirrev,
18 wdirrev,
19 )
19 )
20
20
21 from . import (
21 from . import (
22 dagop,
22 dagop,
23 error,
23 error,
24 formatter,
24 formatter,
25 graphmod,
25 graphmod,
26 match as matchmod,
26 match as matchmod,
27 mdiff,
27 mdiff,
28 patch,
28 patch,
29 pathutil,
29 pathutil,
30 pycompat,
30 pycompat,
31 revset,
31 revset,
32 revsetlang,
32 revsetlang,
33 scmutil,
33 scmutil,
34 smartset,
34 smartset,
35 templatekw,
35 templatekw,
36 templater,
36 templater,
37 util,
37 util,
38 )
38 )
39 from .utils import (
39 from .utils import (
40 dateutil,
40 dateutil,
41 stringutil,
41 stringutil,
42 )
42 )
43
43
44 def getlimit(opts):
44 def getlimit(opts):
45 """get the log limit according to option -l/--limit"""
45 """get the log limit according to option -l/--limit"""
46 limit = opts.get('limit')
46 limit = opts.get('limit')
47 if limit:
47 if limit:
48 try:
48 try:
49 limit = int(limit)
49 limit = int(limit)
50 except ValueError:
50 except ValueError:
51 raise error.Abort(_('limit must be a positive integer'))
51 raise error.Abort(_('limit must be a positive integer'))
52 if limit <= 0:
52 if limit <= 0:
53 raise error.Abort(_('limit must be positive'))
53 raise error.Abort(_('limit must be positive'))
54 else:
54 else:
55 limit = None
55 limit = None
56 return limit
56 return limit
57
57
58 def diffordiffstat(ui, repo, diffopts, node1, node2, match,
58 def diffordiffstat(ui, repo, diffopts, node1, node2, match,
59 changes=None, stat=False, fp=None, graphwidth=0,
59 changes=None, stat=False, fp=None, graphwidth=0,
60 prefix='', root='', listsubrepos=False, hunksfilterfn=None):
60 prefix='', root='', listsubrepos=False, hunksfilterfn=None):
61 '''show diff or diffstat.'''
61 '''show diff or diffstat.'''
62 ctx1 = repo[node1]
62 ctx1 = repo[node1]
63 ctx2 = repo[node2]
63 ctx2 = repo[node2]
64 if root:
64 if root:
65 relroot = pathutil.canonpath(repo.root, repo.getcwd(), root)
65 relroot = pathutil.canonpath(repo.root, repo.getcwd(), root)
66 else:
66 else:
67 relroot = ''
67 relroot = ''
68 copysourcematch = None
68 copysourcematch = None
69 def compose(f, g):
69 def compose(f, g):
70 return lambda x: f(g(x))
70 return lambda x: f(g(x))
71 def pathfn(f):
71 def pathfn(f):
72 return posixpath.join(prefix, f)
72 return posixpath.join(prefix, f)
73 if relroot != '':
73 if relroot != '':
74 # XXX relative roots currently don't work if the root is within a
74 # XXX relative roots currently don't work if the root is within a
75 # subrepo
75 # subrepo
76 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
76 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
77 uirelroot = uipathfn(pathfn(relroot))
77 uirelroot = uipathfn(pathfn(relroot))
78 relroot += '/'
78 relroot += '/'
79 for matchroot in match.files():
79 for matchroot in match.files():
80 if not matchroot.startswith(relroot):
80 if not matchroot.startswith(relroot):
81 ui.warn(_('warning: %s not inside relative root %s\n') %
81 ui.warn(_('warning: %s not inside relative root %s\n') %
82 (uipathfn(pathfn(matchroot)), uirelroot))
82 (uipathfn(pathfn(matchroot)), uirelroot))
83
83
84 relrootmatch = scmutil.match(ctx2, pats=[relroot], default='path')
84 relrootmatch = scmutil.match(ctx2, pats=[relroot], default='path')
85 match = matchmod.intersectmatchers(match, relrootmatch)
85 match = matchmod.intersectmatchers(match, relrootmatch)
86 copysourcematch = relrootmatch
86 copysourcematch = relrootmatch
87
87
88 checkroot = (repo.ui.configbool('devel', 'all-warnings') or
88 checkroot = (repo.ui.configbool('devel', 'all-warnings') or
89 repo.ui.configbool('devel', 'check-relroot'))
89 repo.ui.configbool('devel', 'check-relroot'))
90 def relrootpathfn(f):
90 def relrootpathfn(f):
91 if checkroot and not f.startswith(relroot):
91 if checkroot and not f.startswith(relroot):
92 raise AssertionError(
92 raise AssertionError(
93 "file %s doesn't start with relroot %s" % (f, relroot))
93 "file %s doesn't start with relroot %s" % (f, relroot))
94 return f[len(relroot):]
94 return f[len(relroot):]
95 pathfn = compose(relrootpathfn, pathfn)
95 pathfn = compose(relrootpathfn, pathfn)
96
96
97 if stat:
97 if stat:
98 diffopts = diffopts.copy(context=0, noprefix=False)
98 diffopts = diffopts.copy(context=0, noprefix=False)
99 width = 80
99 width = 80
100 if not ui.plain():
100 if not ui.plain():
101 width = ui.termwidth() - graphwidth
101 width = ui.termwidth() - graphwidth
102 # If an explicit --root was given, don't respect ui.relative-paths
102 # If an explicit --root was given, don't respect ui.relative-paths
103 if not relroot:
103 if not relroot:
104 pathfn = compose(scmutil.getuipathfn(repo), pathfn)
104 pathfn = compose(scmutil.getuipathfn(repo), pathfn)
105
105
106 chunks = ctx2.diff(ctx1, match, changes, opts=diffopts, pathfn=pathfn,
106 chunks = ctx2.diff(ctx1, match, changes, opts=diffopts, pathfn=pathfn,
107 copysourcematch=copysourcematch,
107 copysourcematch=copysourcematch,
108 hunksfilterfn=hunksfilterfn)
108 hunksfilterfn=hunksfilterfn)
109
109
110 if fp is not None or ui.canwritewithoutlabels():
110 if fp is not None or ui.canwritewithoutlabels():
111 out = fp or ui
111 out = fp or ui
112 if stat:
112 if stat:
113 chunks = [patch.diffstat(util.iterlines(chunks), width=width)]
113 chunks = [patch.diffstat(util.iterlines(chunks), width=width)]
114 for chunk in util.filechunkiter(util.chunkbuffer(chunks)):
114 for chunk in util.filechunkiter(util.chunkbuffer(chunks)):
115 out.write(chunk)
115 out.write(chunk)
116 else:
116 else:
117 if stat:
117 if stat:
118 chunks = patch.diffstatui(util.iterlines(chunks), width=width)
118 chunks = patch.diffstatui(util.iterlines(chunks), width=width)
119 else:
119 else:
120 chunks = patch.difflabel(lambda chunks, **kwargs: chunks, chunks,
120 chunks = patch.difflabel(lambda chunks, **kwargs: chunks, chunks,
121 opts=diffopts)
121 opts=diffopts)
122 if ui.canbatchlabeledwrites():
122 if ui.canbatchlabeledwrites():
123 def gen():
123 def gen():
124 for chunk, label in chunks:
124 for chunk, label in chunks:
125 yield ui.label(chunk, label=label)
125 yield ui.label(chunk, label=label)
126 for chunk in util.filechunkiter(util.chunkbuffer(gen())):
126 for chunk in util.filechunkiter(util.chunkbuffer(gen())):
127 ui.write(chunk)
127 ui.write(chunk)
128 else:
128 else:
129 for chunk, label in chunks:
129 for chunk, label in chunks:
130 ui.write(chunk, label=label)
130 ui.write(chunk, label=label)
131
131
132 if listsubrepos:
132 for subpath, sub in scmutil.itersubrepos(ctx1, ctx2):
133 for subpath, sub in scmutil.itersubrepos(ctx1, ctx2):
133 tempnode2 = node2
134 tempnode2 = node2
134 try:
135 try:
135 if node2 is not None:
136 if node2 is not None:
136 tempnode2 = ctx2.substate[subpath][1]
137 tempnode2 = ctx2.substate[subpath][1]
137 except KeyError:
138 except KeyError:
138 # A subrepo that existed in node1 was deleted between node1 and
139 # A subrepo that existed in node1 was deleted between node1 and
139 # node2 (inclusive). Thus, ctx2's substate won't contain that
140 # node2 (inclusive). Thus, ctx2's substate won't contain that
140 # subpath. The best we can do is to ignore it.
141 # subpath. The best we can do is to ignore it.
141 tempnode2 = None
142 tempnode2 = None
142 submatch = matchmod.subdirmatcher(subpath, match)
143 submatch = matchmod.subdirmatcher(subpath, match)
143 subprefix = repo.wvfs.reljoin(prefix, subpath)
144 subprefix = repo.wvfs.reljoin(prefix, subpath)
144 if listsubrepos or match.exact(subpath) or any(submatch.files()):
145 sub.diff(ui, diffopts, tempnode2, submatch, changes=changes,
145 sub.diff(ui, diffopts, tempnode2, submatch, changes=changes,
146 stat=stat, fp=fp, prefix=subprefix)
146 stat=stat, fp=fp, prefix=subprefix)
147
147
148 class changesetdiffer(object):
148 class changesetdiffer(object):
149 """Generate diff of changeset with pre-configured filtering functions"""
149 """Generate diff of changeset with pre-configured filtering functions"""
150
150
151 def _makefilematcher(self, ctx):
151 def _makefilematcher(self, ctx):
152 return scmutil.matchall(ctx.repo())
152 return scmutil.matchall(ctx.repo())
153
153
154 def _makehunksfilter(self, ctx):
154 def _makehunksfilter(self, ctx):
155 return None
155 return None
156
156
157 def showdiff(self, ui, ctx, diffopts, graphwidth=0, stat=False):
157 def showdiff(self, ui, ctx, diffopts, graphwidth=0, stat=False):
158 repo = ctx.repo()
158 repo = ctx.repo()
159 node = ctx.node()
159 node = ctx.node()
160 prev = ctx.p1().node()
160 prev = ctx.p1().node()
161 diffordiffstat(ui, repo, diffopts, prev, node,
161 diffordiffstat(ui, repo, diffopts, prev, node,
162 match=self._makefilematcher(ctx), stat=stat,
162 match=self._makefilematcher(ctx), stat=stat,
163 graphwidth=graphwidth,
163 graphwidth=graphwidth,
164 hunksfilterfn=self._makehunksfilter(ctx))
164 hunksfilterfn=self._makehunksfilter(ctx))
165
165
166 def changesetlabels(ctx):
166 def changesetlabels(ctx):
167 labels = ['log.changeset', 'changeset.%s' % ctx.phasestr()]
167 labels = ['log.changeset', 'changeset.%s' % ctx.phasestr()]
168 if ctx.obsolete():
168 if ctx.obsolete():
169 labels.append('changeset.obsolete')
169 labels.append('changeset.obsolete')
170 if ctx.isunstable():
170 if ctx.isunstable():
171 labels.append('changeset.unstable')
171 labels.append('changeset.unstable')
172 for instability in ctx.instabilities():
172 for instability in ctx.instabilities():
173 labels.append('instability.%s' % instability)
173 labels.append('instability.%s' % instability)
174 return ' '.join(labels)
174 return ' '.join(labels)
175
175
176 class changesetprinter(object):
176 class changesetprinter(object):
177 '''show changeset information when templating not requested.'''
177 '''show changeset information when templating not requested.'''
178
178
179 def __init__(self, ui, repo, differ=None, diffopts=None, buffered=False):
179 def __init__(self, ui, repo, differ=None, diffopts=None, buffered=False):
180 self.ui = ui
180 self.ui = ui
181 self.repo = repo
181 self.repo = repo
182 self.buffered = buffered
182 self.buffered = buffered
183 self._differ = differ or changesetdiffer()
183 self._differ = differ or changesetdiffer()
184 self._diffopts = patch.diffallopts(ui, diffopts)
184 self._diffopts = patch.diffallopts(ui, diffopts)
185 self._includestat = diffopts and diffopts.get('stat')
185 self._includestat = diffopts and diffopts.get('stat')
186 self._includediff = diffopts and diffopts.get('patch')
186 self._includediff = diffopts and diffopts.get('patch')
187 self.header = {}
187 self.header = {}
188 self.hunk = {}
188 self.hunk = {}
189 self.lastheader = None
189 self.lastheader = None
190 self.footer = None
190 self.footer = None
191 self._columns = templatekw.getlogcolumns()
191 self._columns = templatekw.getlogcolumns()
192
192
193 def flush(self, ctx):
193 def flush(self, ctx):
194 rev = ctx.rev()
194 rev = ctx.rev()
195 if rev in self.header:
195 if rev in self.header:
196 h = self.header[rev]
196 h = self.header[rev]
197 if h != self.lastheader:
197 if h != self.lastheader:
198 self.lastheader = h
198 self.lastheader = h
199 self.ui.write(h)
199 self.ui.write(h)
200 del self.header[rev]
200 del self.header[rev]
201 if rev in self.hunk:
201 if rev in self.hunk:
202 self.ui.write(self.hunk[rev])
202 self.ui.write(self.hunk[rev])
203 del self.hunk[rev]
203 del self.hunk[rev]
204
204
205 def close(self):
205 def close(self):
206 if self.footer:
206 if self.footer:
207 self.ui.write(self.footer)
207 self.ui.write(self.footer)
208
208
209 def show(self, ctx, copies=None, **props):
209 def show(self, ctx, copies=None, **props):
210 props = pycompat.byteskwargs(props)
210 props = pycompat.byteskwargs(props)
211 if self.buffered:
211 if self.buffered:
212 self.ui.pushbuffer(labeled=True)
212 self.ui.pushbuffer(labeled=True)
213 self._show(ctx, copies, props)
213 self._show(ctx, copies, props)
214 self.hunk[ctx.rev()] = self.ui.popbuffer()
214 self.hunk[ctx.rev()] = self.ui.popbuffer()
215 else:
215 else:
216 self._show(ctx, copies, props)
216 self._show(ctx, copies, props)
217
217
218 def _show(self, ctx, copies, props):
218 def _show(self, ctx, copies, props):
219 '''show a single changeset or file revision'''
219 '''show a single changeset or file revision'''
220 changenode = ctx.node()
220 changenode = ctx.node()
221 graphwidth = props.get('graphwidth', 0)
221 graphwidth = props.get('graphwidth', 0)
222
222
223 if self.ui.quiet:
223 if self.ui.quiet:
224 self.ui.write("%s\n" % scmutil.formatchangeid(ctx),
224 self.ui.write("%s\n" % scmutil.formatchangeid(ctx),
225 label='log.node')
225 label='log.node')
226 return
226 return
227
227
228 columns = self._columns
228 columns = self._columns
229 self.ui.write(columns['changeset'] % scmutil.formatchangeid(ctx),
229 self.ui.write(columns['changeset'] % scmutil.formatchangeid(ctx),
230 label=changesetlabels(ctx))
230 label=changesetlabels(ctx))
231
231
232 # branches are shown first before any other names due to backwards
232 # branches are shown first before any other names due to backwards
233 # compatibility
233 # compatibility
234 branch = ctx.branch()
234 branch = ctx.branch()
235 # don't show the default branch name
235 # don't show the default branch name
236 if branch != 'default':
236 if branch != 'default':
237 self.ui.write(columns['branch'] % branch, label='log.branch')
237 self.ui.write(columns['branch'] % branch, label='log.branch')
238
238
239 for nsname, ns in self.repo.names.iteritems():
239 for nsname, ns in self.repo.names.iteritems():
240 # branches has special logic already handled above, so here we just
240 # branches has special logic already handled above, so here we just
241 # skip it
241 # skip it
242 if nsname == 'branches':
242 if nsname == 'branches':
243 continue
243 continue
244 # we will use the templatename as the color name since those two
244 # we will use the templatename as the color name since those two
245 # should be the same
245 # should be the same
246 for name in ns.names(self.repo, changenode):
246 for name in ns.names(self.repo, changenode):
247 self.ui.write(ns.logfmt % name,
247 self.ui.write(ns.logfmt % name,
248 label='log.%s' % ns.colorname)
248 label='log.%s' % ns.colorname)
249 if self.ui.debugflag:
249 if self.ui.debugflag:
250 self.ui.write(columns['phase'] % ctx.phasestr(), label='log.phase')
250 self.ui.write(columns['phase'] % ctx.phasestr(), label='log.phase')
251 for pctx in scmutil.meaningfulparents(self.repo, ctx):
251 for pctx in scmutil.meaningfulparents(self.repo, ctx):
252 label = 'log.parent changeset.%s' % pctx.phasestr()
252 label = 'log.parent changeset.%s' % pctx.phasestr()
253 self.ui.write(columns['parent'] % scmutil.formatchangeid(pctx),
253 self.ui.write(columns['parent'] % scmutil.formatchangeid(pctx),
254 label=label)
254 label=label)
255
255
256 if self.ui.debugflag:
256 if self.ui.debugflag:
257 mnode = ctx.manifestnode()
257 mnode = ctx.manifestnode()
258 if mnode is None:
258 if mnode is None:
259 mnode = wdirid
259 mnode = wdirid
260 mrev = wdirrev
260 mrev = wdirrev
261 else:
261 else:
262 mrev = self.repo.manifestlog.rev(mnode)
262 mrev = self.repo.manifestlog.rev(mnode)
263 self.ui.write(columns['manifest']
263 self.ui.write(columns['manifest']
264 % scmutil.formatrevnode(self.ui, mrev, mnode),
264 % scmutil.formatrevnode(self.ui, mrev, mnode),
265 label='ui.debug log.manifest')
265 label='ui.debug log.manifest')
266 self.ui.write(columns['user'] % ctx.user(), label='log.user')
266 self.ui.write(columns['user'] % ctx.user(), label='log.user')
267 self.ui.write(columns['date'] % dateutil.datestr(ctx.date()),
267 self.ui.write(columns['date'] % dateutil.datestr(ctx.date()),
268 label='log.date')
268 label='log.date')
269
269
270 if ctx.isunstable():
270 if ctx.isunstable():
271 instabilities = ctx.instabilities()
271 instabilities = ctx.instabilities()
272 self.ui.write(columns['instability'] % ', '.join(instabilities),
272 self.ui.write(columns['instability'] % ', '.join(instabilities),
273 label='log.instability')
273 label='log.instability')
274
274
275 elif ctx.obsolete():
275 elif ctx.obsolete():
276 self._showobsfate(ctx)
276 self._showobsfate(ctx)
277
277
278 self._exthook(ctx)
278 self._exthook(ctx)
279
279
280 if self.ui.debugflag:
280 if self.ui.debugflag:
281 files = ctx.p1().status(ctx)[:3]
281 files = ctx.p1().status(ctx)[:3]
282 for key, value in zip(['files', 'files+', 'files-'], files):
282 for key, value in zip(['files', 'files+', 'files-'], files):
283 if value:
283 if value:
284 self.ui.write(columns[key] % " ".join(value),
284 self.ui.write(columns[key] % " ".join(value),
285 label='ui.debug log.files')
285 label='ui.debug log.files')
286 elif ctx.files() and self.ui.verbose:
286 elif ctx.files() and self.ui.verbose:
287 self.ui.write(columns['files'] % " ".join(ctx.files()),
287 self.ui.write(columns['files'] % " ".join(ctx.files()),
288 label='ui.note log.files')
288 label='ui.note log.files')
289 if copies and self.ui.verbose:
289 if copies and self.ui.verbose:
290 copies = ['%s (%s)' % c for c in copies]
290 copies = ['%s (%s)' % c for c in copies]
291 self.ui.write(columns['copies'] % ' '.join(copies),
291 self.ui.write(columns['copies'] % ' '.join(copies),
292 label='ui.note log.copies')
292 label='ui.note log.copies')
293
293
294 extra = ctx.extra()
294 extra = ctx.extra()
295 if extra and self.ui.debugflag:
295 if extra and self.ui.debugflag:
296 for key, value in sorted(extra.items()):
296 for key, value in sorted(extra.items()):
297 self.ui.write(columns['extra']
297 self.ui.write(columns['extra']
298 % (key, stringutil.escapestr(value)),
298 % (key, stringutil.escapestr(value)),
299 label='ui.debug log.extra')
299 label='ui.debug log.extra')
300
300
301 description = ctx.description().strip()
301 description = ctx.description().strip()
302 if description:
302 if description:
303 if self.ui.verbose:
303 if self.ui.verbose:
304 self.ui.write(_("description:\n"),
304 self.ui.write(_("description:\n"),
305 label='ui.note log.description')
305 label='ui.note log.description')
306 self.ui.write(description,
306 self.ui.write(description,
307 label='ui.note log.description')
307 label='ui.note log.description')
308 self.ui.write("\n\n")
308 self.ui.write("\n\n")
309 else:
309 else:
310 self.ui.write(columns['summary'] % description.splitlines()[0],
310 self.ui.write(columns['summary'] % description.splitlines()[0],
311 label='log.summary')
311 label='log.summary')
312 self.ui.write("\n")
312 self.ui.write("\n")
313
313
314 self._showpatch(ctx, graphwidth)
314 self._showpatch(ctx, graphwidth)
315
315
316 def _showobsfate(self, ctx):
316 def _showobsfate(self, ctx):
317 # TODO: do not depend on templater
317 # TODO: do not depend on templater
318 tres = formatter.templateresources(self.repo.ui, self.repo)
318 tres = formatter.templateresources(self.repo.ui, self.repo)
319 t = formatter.maketemplater(self.repo.ui, '{join(obsfate, "\n")}',
319 t = formatter.maketemplater(self.repo.ui, '{join(obsfate, "\n")}',
320 defaults=templatekw.keywords,
320 defaults=templatekw.keywords,
321 resources=tres)
321 resources=tres)
322 obsfate = t.renderdefault({'ctx': ctx}).splitlines()
322 obsfate = t.renderdefault({'ctx': ctx}).splitlines()
323
323
324 if obsfate:
324 if obsfate:
325 for obsfateline in obsfate:
325 for obsfateline in obsfate:
326 self.ui.write(self._columns['obsolete'] % obsfateline,
326 self.ui.write(self._columns['obsolete'] % obsfateline,
327 label='log.obsfate')
327 label='log.obsfate')
328
328
329 def _exthook(self, ctx):
329 def _exthook(self, ctx):
330 '''empty method used by extension as a hook point
330 '''empty method used by extension as a hook point
331 '''
331 '''
332
332
333 def _showpatch(self, ctx, graphwidth=0):
333 def _showpatch(self, ctx, graphwidth=0):
334 if self._includestat:
334 if self._includestat:
335 self._differ.showdiff(self.ui, ctx, self._diffopts,
335 self._differ.showdiff(self.ui, ctx, self._diffopts,
336 graphwidth, stat=True)
336 graphwidth, stat=True)
337 if self._includestat and self._includediff:
337 if self._includestat and self._includediff:
338 self.ui.write("\n")
338 self.ui.write("\n")
339 if self._includediff:
339 if self._includediff:
340 self._differ.showdiff(self.ui, ctx, self._diffopts,
340 self._differ.showdiff(self.ui, ctx, self._diffopts,
341 graphwidth, stat=False)
341 graphwidth, stat=False)
342 if self._includestat or self._includediff:
342 if self._includestat or self._includediff:
343 self.ui.write("\n")
343 self.ui.write("\n")
344
344
345 class changesetformatter(changesetprinter):
345 class changesetformatter(changesetprinter):
346 """Format changeset information by generic formatter"""
346 """Format changeset information by generic formatter"""
347
347
348 def __init__(self, ui, repo, fm, differ=None, diffopts=None,
348 def __init__(self, ui, repo, fm, differ=None, diffopts=None,
349 buffered=False):
349 buffered=False):
350 changesetprinter.__init__(self, ui, repo, differ, diffopts, buffered)
350 changesetprinter.__init__(self, ui, repo, differ, diffopts, buffered)
351 self._diffopts = patch.difffeatureopts(ui, diffopts, git=True)
351 self._diffopts = patch.difffeatureopts(ui, diffopts, git=True)
352 self._fm = fm
352 self._fm = fm
353
353
354 def close(self):
354 def close(self):
355 self._fm.end()
355 self._fm.end()
356
356
357 def _show(self, ctx, copies, props):
357 def _show(self, ctx, copies, props):
358 '''show a single changeset or file revision'''
358 '''show a single changeset or file revision'''
359 fm = self._fm
359 fm = self._fm
360 fm.startitem()
360 fm.startitem()
361 fm.context(ctx=ctx)
361 fm.context(ctx=ctx)
362 fm.data(rev=scmutil.intrev(ctx),
362 fm.data(rev=scmutil.intrev(ctx),
363 node=fm.hexfunc(scmutil.binnode(ctx)))
363 node=fm.hexfunc(scmutil.binnode(ctx)))
364
364
365 if self.ui.quiet:
365 if self.ui.quiet:
366 return
366 return
367
367
368 fm.data(branch=ctx.branch(),
368 fm.data(branch=ctx.branch(),
369 phase=ctx.phasestr(),
369 phase=ctx.phasestr(),
370 user=ctx.user(),
370 user=ctx.user(),
371 date=fm.formatdate(ctx.date()),
371 date=fm.formatdate(ctx.date()),
372 desc=ctx.description(),
372 desc=ctx.description(),
373 bookmarks=fm.formatlist(ctx.bookmarks(), name='bookmark'),
373 bookmarks=fm.formatlist(ctx.bookmarks(), name='bookmark'),
374 tags=fm.formatlist(ctx.tags(), name='tag'),
374 tags=fm.formatlist(ctx.tags(), name='tag'),
375 parents=fm.formatlist([fm.hexfunc(c.node())
375 parents=fm.formatlist([fm.hexfunc(c.node())
376 for c in ctx.parents()], name='node'))
376 for c in ctx.parents()], name='node'))
377
377
378 if self.ui.debugflag:
378 if self.ui.debugflag:
379 fm.data(manifest=fm.hexfunc(ctx.manifestnode() or wdirid),
379 fm.data(manifest=fm.hexfunc(ctx.manifestnode() or wdirid),
380 extra=fm.formatdict(ctx.extra()))
380 extra=fm.formatdict(ctx.extra()))
381
381
382 files = ctx.p1().status(ctx)
382 files = ctx.p1().status(ctx)
383 fm.data(modified=fm.formatlist(files[0], name='file'),
383 fm.data(modified=fm.formatlist(files[0], name='file'),
384 added=fm.formatlist(files[1], name='file'),
384 added=fm.formatlist(files[1], name='file'),
385 removed=fm.formatlist(files[2], name='file'))
385 removed=fm.formatlist(files[2], name='file'))
386
386
387 elif self.ui.verbose:
387 elif self.ui.verbose:
388 fm.data(files=fm.formatlist(ctx.files(), name='file'))
388 fm.data(files=fm.formatlist(ctx.files(), name='file'))
389 if copies:
389 if copies:
390 fm.data(copies=fm.formatdict(copies,
390 fm.data(copies=fm.formatdict(copies,
391 key='name', value='source'))
391 key='name', value='source'))
392
392
393 if self._includestat:
393 if self._includestat:
394 self.ui.pushbuffer()
394 self.ui.pushbuffer()
395 self._differ.showdiff(self.ui, ctx, self._diffopts, stat=True)
395 self._differ.showdiff(self.ui, ctx, self._diffopts, stat=True)
396 fm.data(diffstat=self.ui.popbuffer())
396 fm.data(diffstat=self.ui.popbuffer())
397 if self._includediff:
397 if self._includediff:
398 self.ui.pushbuffer()
398 self.ui.pushbuffer()
399 self._differ.showdiff(self.ui, ctx, self._diffopts, stat=False)
399 self._differ.showdiff(self.ui, ctx, self._diffopts, stat=False)
400 fm.data(diff=self.ui.popbuffer())
400 fm.data(diff=self.ui.popbuffer())
401
401
402 class changesettemplater(changesetprinter):
402 class changesettemplater(changesetprinter):
403 '''format changeset information.
403 '''format changeset information.
404
404
405 Note: there are a variety of convenience functions to build a
405 Note: there are a variety of convenience functions to build a
406 changesettemplater for common cases. See functions such as:
406 changesettemplater for common cases. See functions such as:
407 maketemplater, changesetdisplayer, buildcommittemplate, or other
407 maketemplater, changesetdisplayer, buildcommittemplate, or other
408 functions that use changesest_templater.
408 functions that use changesest_templater.
409 '''
409 '''
410
410
411 # Arguments before "buffered" used to be positional. Consider not
411 # Arguments before "buffered" used to be positional. Consider not
412 # adding/removing arguments before "buffered" to not break callers.
412 # adding/removing arguments before "buffered" to not break callers.
413 def __init__(self, ui, repo, tmplspec, differ=None, diffopts=None,
413 def __init__(self, ui, repo, tmplspec, differ=None, diffopts=None,
414 buffered=False):
414 buffered=False):
415 changesetprinter.__init__(self, ui, repo, differ, diffopts, buffered)
415 changesetprinter.__init__(self, ui, repo, differ, diffopts, buffered)
416 # tres is shared with _graphnodeformatter()
416 # tres is shared with _graphnodeformatter()
417 self._tresources = tres = formatter.templateresources(ui, repo)
417 self._tresources = tres = formatter.templateresources(ui, repo)
418 self.t = formatter.loadtemplater(ui, tmplspec,
418 self.t = formatter.loadtemplater(ui, tmplspec,
419 defaults=templatekw.keywords,
419 defaults=templatekw.keywords,
420 resources=tres,
420 resources=tres,
421 cache=templatekw.defaulttempl)
421 cache=templatekw.defaulttempl)
422 self._counter = itertools.count()
422 self._counter = itertools.count()
423
423
424 self._tref = tmplspec.ref
424 self._tref = tmplspec.ref
425 self._parts = {'header': '', 'footer': '',
425 self._parts = {'header': '', 'footer': '',
426 tmplspec.ref: tmplspec.ref,
426 tmplspec.ref: tmplspec.ref,
427 'docheader': '', 'docfooter': '',
427 'docheader': '', 'docfooter': '',
428 'separator': ''}
428 'separator': ''}
429 if tmplspec.mapfile:
429 if tmplspec.mapfile:
430 # find correct templates for current mode, for backward
430 # find correct templates for current mode, for backward
431 # compatibility with 'log -v/-q/--debug' using a mapfile
431 # compatibility with 'log -v/-q/--debug' using a mapfile
432 tmplmodes = [
432 tmplmodes = [
433 (True, ''),
433 (True, ''),
434 (self.ui.verbose, '_verbose'),
434 (self.ui.verbose, '_verbose'),
435 (self.ui.quiet, '_quiet'),
435 (self.ui.quiet, '_quiet'),
436 (self.ui.debugflag, '_debug'),
436 (self.ui.debugflag, '_debug'),
437 ]
437 ]
438 for mode, postfix in tmplmodes:
438 for mode, postfix in tmplmodes:
439 for t in self._parts:
439 for t in self._parts:
440 cur = t + postfix
440 cur = t + postfix
441 if mode and cur in self.t:
441 if mode and cur in self.t:
442 self._parts[t] = cur
442 self._parts[t] = cur
443 else:
443 else:
444 partnames = [p for p in self._parts.keys() if p != tmplspec.ref]
444 partnames = [p for p in self._parts.keys() if p != tmplspec.ref]
445 m = formatter.templatepartsmap(tmplspec, self.t, partnames)
445 m = formatter.templatepartsmap(tmplspec, self.t, partnames)
446 self._parts.update(m)
446 self._parts.update(m)
447
447
448 if self._parts['docheader']:
448 if self._parts['docheader']:
449 self.ui.write(self.t.render(self._parts['docheader'], {}))
449 self.ui.write(self.t.render(self._parts['docheader'], {}))
450
450
451 def close(self):
451 def close(self):
452 if self._parts['docfooter']:
452 if self._parts['docfooter']:
453 if not self.footer:
453 if not self.footer:
454 self.footer = ""
454 self.footer = ""
455 self.footer += self.t.render(self._parts['docfooter'], {})
455 self.footer += self.t.render(self._parts['docfooter'], {})
456 return super(changesettemplater, self).close()
456 return super(changesettemplater, self).close()
457
457
458 def _show(self, ctx, copies, props):
458 def _show(self, ctx, copies, props):
459 '''show a single changeset or file revision'''
459 '''show a single changeset or file revision'''
460 props = props.copy()
460 props = props.copy()
461 props['ctx'] = ctx
461 props['ctx'] = ctx
462 props['index'] = index = next(self._counter)
462 props['index'] = index = next(self._counter)
463 props['revcache'] = {'copies': copies}
463 props['revcache'] = {'copies': copies}
464 graphwidth = props.get('graphwidth', 0)
464 graphwidth = props.get('graphwidth', 0)
465
465
466 # write separator, which wouldn't work well with the header part below
466 # write separator, which wouldn't work well with the header part below
467 # since there's inherently a conflict between header (across items) and
467 # since there's inherently a conflict between header (across items) and
468 # separator (per item)
468 # separator (per item)
469 if self._parts['separator'] and index > 0:
469 if self._parts['separator'] and index > 0:
470 self.ui.write(self.t.render(self._parts['separator'], {}))
470 self.ui.write(self.t.render(self._parts['separator'], {}))
471
471
472 # write header
472 # write header
473 if self._parts['header']:
473 if self._parts['header']:
474 h = self.t.render(self._parts['header'], props)
474 h = self.t.render(self._parts['header'], props)
475 if self.buffered:
475 if self.buffered:
476 self.header[ctx.rev()] = h
476 self.header[ctx.rev()] = h
477 else:
477 else:
478 if self.lastheader != h:
478 if self.lastheader != h:
479 self.lastheader = h
479 self.lastheader = h
480 self.ui.write(h)
480 self.ui.write(h)
481
481
482 # write changeset metadata, then patch if requested
482 # write changeset metadata, then patch if requested
483 key = self._parts[self._tref]
483 key = self._parts[self._tref]
484 self.ui.write(self.t.render(key, props))
484 self.ui.write(self.t.render(key, props))
485 self._showpatch(ctx, graphwidth)
485 self._showpatch(ctx, graphwidth)
486
486
487 if self._parts['footer']:
487 if self._parts['footer']:
488 if not self.footer:
488 if not self.footer:
489 self.footer = self.t.render(self._parts['footer'], props)
489 self.footer = self.t.render(self._parts['footer'], props)
490
490
491 def templatespec(tmpl, mapfile):
491 def templatespec(tmpl, mapfile):
492 if pycompat.ispy3:
492 if pycompat.ispy3:
493 assert not isinstance(tmpl, str), 'tmpl must not be a str'
493 assert not isinstance(tmpl, str), 'tmpl must not be a str'
494 if mapfile:
494 if mapfile:
495 return formatter.templatespec('changeset', tmpl, mapfile)
495 return formatter.templatespec('changeset', tmpl, mapfile)
496 else:
496 else:
497 return formatter.templatespec('', tmpl, None)
497 return formatter.templatespec('', tmpl, None)
498
498
499 def _lookuptemplate(ui, tmpl, style):
499 def _lookuptemplate(ui, tmpl, style):
500 """Find the template matching the given template spec or style
500 """Find the template matching the given template spec or style
501
501
502 See formatter.lookuptemplate() for details.
502 See formatter.lookuptemplate() for details.
503 """
503 """
504
504
505 # ui settings
505 # ui settings
506 if not tmpl and not style: # template are stronger than style
506 if not tmpl and not style: # template are stronger than style
507 tmpl = ui.config('ui', 'logtemplate')
507 tmpl = ui.config('ui', 'logtemplate')
508 if tmpl:
508 if tmpl:
509 return templatespec(templater.unquotestring(tmpl), None)
509 return templatespec(templater.unquotestring(tmpl), None)
510 else:
510 else:
511 style = util.expandpath(ui.config('ui', 'style'))
511 style = util.expandpath(ui.config('ui', 'style'))
512
512
513 if not tmpl and style:
513 if not tmpl and style:
514 mapfile = style
514 mapfile = style
515 if not os.path.split(mapfile)[0]:
515 if not os.path.split(mapfile)[0]:
516 mapname = (templater.templatepath('map-cmdline.' + mapfile)
516 mapname = (templater.templatepath('map-cmdline.' + mapfile)
517 or templater.templatepath(mapfile))
517 or templater.templatepath(mapfile))
518 if mapname:
518 if mapname:
519 mapfile = mapname
519 mapfile = mapname
520 return templatespec(None, mapfile)
520 return templatespec(None, mapfile)
521
521
522 if not tmpl:
522 if not tmpl:
523 return templatespec(None, None)
523 return templatespec(None, None)
524
524
525 return formatter.lookuptemplate(ui, 'changeset', tmpl)
525 return formatter.lookuptemplate(ui, 'changeset', tmpl)
526
526
527 def maketemplater(ui, repo, tmpl, buffered=False):
527 def maketemplater(ui, repo, tmpl, buffered=False):
528 """Create a changesettemplater from a literal template 'tmpl'
528 """Create a changesettemplater from a literal template 'tmpl'
529 byte-string."""
529 byte-string."""
530 spec = templatespec(tmpl, None)
530 spec = templatespec(tmpl, None)
531 return changesettemplater(ui, repo, spec, buffered=buffered)
531 return changesettemplater(ui, repo, spec, buffered=buffered)
532
532
533 def changesetdisplayer(ui, repo, opts, differ=None, buffered=False):
533 def changesetdisplayer(ui, repo, opts, differ=None, buffered=False):
534 """show one changeset using template or regular display.
534 """show one changeset using template or regular display.
535
535
536 Display format will be the first non-empty hit of:
536 Display format will be the first non-empty hit of:
537 1. option 'template'
537 1. option 'template'
538 2. option 'style'
538 2. option 'style'
539 3. [ui] setting 'logtemplate'
539 3. [ui] setting 'logtemplate'
540 4. [ui] setting 'style'
540 4. [ui] setting 'style'
541 If all of these values are either the unset or the empty string,
541 If all of these values are either the unset or the empty string,
542 regular display via changesetprinter() is done.
542 regular display via changesetprinter() is done.
543 """
543 """
544 postargs = (differ, opts, buffered)
544 postargs = (differ, opts, buffered)
545 if opts.get('template') in {'cbor', 'json'}:
545 if opts.get('template') in {'cbor', 'json'}:
546 fm = ui.formatter('log', opts)
546 fm = ui.formatter('log', opts)
547 return changesetformatter(ui, repo, fm, *postargs)
547 return changesetformatter(ui, repo, fm, *postargs)
548
548
549 spec = _lookuptemplate(ui, opts.get('template'), opts.get('style'))
549 spec = _lookuptemplate(ui, opts.get('template'), opts.get('style'))
550
550
551 if not spec.ref and not spec.tmpl and not spec.mapfile:
551 if not spec.ref and not spec.tmpl and not spec.mapfile:
552 return changesetprinter(ui, repo, *postargs)
552 return changesetprinter(ui, repo, *postargs)
553
553
554 return changesettemplater(ui, repo, spec, *postargs)
554 return changesettemplater(ui, repo, spec, *postargs)
555
555
556 def _makematcher(repo, revs, pats, opts):
556 def _makematcher(repo, revs, pats, opts):
557 """Build matcher and expanded patterns from log options
557 """Build matcher and expanded patterns from log options
558
558
559 If --follow, revs are the revisions to follow from.
559 If --follow, revs are the revisions to follow from.
560
560
561 Returns (match, pats, slowpath) where
561 Returns (match, pats, slowpath) where
562 - match: a matcher built from the given pats and -I/-X opts
562 - match: a matcher built from the given pats and -I/-X opts
563 - pats: patterns used (globs are expanded on Windows)
563 - pats: patterns used (globs are expanded on Windows)
564 - slowpath: True if patterns aren't as simple as scanning filelogs
564 - slowpath: True if patterns aren't as simple as scanning filelogs
565 """
565 """
566 # pats/include/exclude are passed to match.match() directly in
566 # pats/include/exclude are passed to match.match() directly in
567 # _matchfiles() revset but walkchangerevs() builds its matcher with
567 # _matchfiles() revset but walkchangerevs() builds its matcher with
568 # scmutil.match(). The difference is input pats are globbed on
568 # scmutil.match(). The difference is input pats are globbed on
569 # platforms without shell expansion (windows).
569 # platforms without shell expansion (windows).
570 wctx = repo[None]
570 wctx = repo[None]
571 match, pats = scmutil.matchandpats(wctx, pats, opts)
571 match, pats = scmutil.matchandpats(wctx, pats, opts)
572 slowpath = match.anypats() or (not match.always() and opts.get('removed'))
572 slowpath = match.anypats() or (not match.always() and opts.get('removed'))
573 if not slowpath:
573 if not slowpath:
574 follow = opts.get('follow') or opts.get('follow_first')
574 follow = opts.get('follow') or opts.get('follow_first')
575 startctxs = []
575 startctxs = []
576 if follow and opts.get('rev'):
576 if follow and opts.get('rev'):
577 startctxs = [repo[r] for r in revs]
577 startctxs = [repo[r] for r in revs]
578 for f in match.files():
578 for f in match.files():
579 if follow and startctxs:
579 if follow and startctxs:
580 # No idea if the path was a directory at that revision, so
580 # No idea if the path was a directory at that revision, so
581 # take the slow path.
581 # take the slow path.
582 if any(f not in c for c in startctxs):
582 if any(f not in c for c in startctxs):
583 slowpath = True
583 slowpath = True
584 continue
584 continue
585 elif follow and f not in wctx:
585 elif follow and f not in wctx:
586 # If the file exists, it may be a directory, so let it
586 # If the file exists, it may be a directory, so let it
587 # take the slow path.
587 # take the slow path.
588 if os.path.exists(repo.wjoin(f)):
588 if os.path.exists(repo.wjoin(f)):
589 slowpath = True
589 slowpath = True
590 continue
590 continue
591 else:
591 else:
592 raise error.Abort(_('cannot follow file not in parent '
592 raise error.Abort(_('cannot follow file not in parent '
593 'revision: "%s"') % f)
593 'revision: "%s"') % f)
594 filelog = repo.file(f)
594 filelog = repo.file(f)
595 if not filelog:
595 if not filelog:
596 # A zero count may be a directory or deleted file, so
596 # A zero count may be a directory or deleted file, so
597 # try to find matching entries on the slow path.
597 # try to find matching entries on the slow path.
598 if follow:
598 if follow:
599 raise error.Abort(
599 raise error.Abort(
600 _('cannot follow nonexistent file: "%s"') % f)
600 _('cannot follow nonexistent file: "%s"') % f)
601 slowpath = True
601 slowpath = True
602
602
603 # We decided to fall back to the slowpath because at least one
603 # We decided to fall back to the slowpath because at least one
604 # of the paths was not a file. Check to see if at least one of them
604 # of the paths was not a file. Check to see if at least one of them
605 # existed in history - in that case, we'll continue down the
605 # existed in history - in that case, we'll continue down the
606 # slowpath; otherwise, we can turn off the slowpath
606 # slowpath; otherwise, we can turn off the slowpath
607 if slowpath:
607 if slowpath:
608 for path in match.files():
608 for path in match.files():
609 if path == '.' or path in repo.store:
609 if path == '.' or path in repo.store:
610 break
610 break
611 else:
611 else:
612 slowpath = False
612 slowpath = False
613
613
614 return match, pats, slowpath
614 return match, pats, slowpath
615
615
616 def _fileancestors(repo, revs, match, followfirst):
616 def _fileancestors(repo, revs, match, followfirst):
617 fctxs = []
617 fctxs = []
618 for r in revs:
618 for r in revs:
619 ctx = repo[r]
619 ctx = repo[r]
620 fctxs.extend(ctx[f].introfilectx() for f in ctx.walk(match))
620 fctxs.extend(ctx[f].introfilectx() for f in ctx.walk(match))
621
621
622 # When displaying a revision with --patch --follow FILE, we have
622 # When displaying a revision with --patch --follow FILE, we have
623 # to know which file of the revision must be diffed. With
623 # to know which file of the revision must be diffed. With
624 # --follow, we want the names of the ancestors of FILE in the
624 # --follow, we want the names of the ancestors of FILE in the
625 # revision, stored in "fcache". "fcache" is populated as a side effect
625 # revision, stored in "fcache". "fcache" is populated as a side effect
626 # of the graph traversal.
626 # of the graph traversal.
627 fcache = {}
627 fcache = {}
628 def filematcher(ctx):
628 def filematcher(ctx):
629 return scmutil.matchfiles(repo, fcache.get(ctx.rev(), []))
629 return scmutil.matchfiles(repo, fcache.get(ctx.rev(), []))
630
630
631 def revgen():
631 def revgen():
632 for rev, cs in dagop.filectxancestors(fctxs, followfirst=followfirst):
632 for rev, cs in dagop.filectxancestors(fctxs, followfirst=followfirst):
633 fcache[rev] = [c.path() for c in cs]
633 fcache[rev] = [c.path() for c in cs]
634 yield rev
634 yield rev
635 return smartset.generatorset(revgen(), iterasc=False), filematcher
635 return smartset.generatorset(revgen(), iterasc=False), filematcher
636
636
637 def _makenofollowfilematcher(repo, pats, opts):
637 def _makenofollowfilematcher(repo, pats, opts):
638 '''hook for extensions to override the filematcher for non-follow cases'''
638 '''hook for extensions to override the filematcher for non-follow cases'''
639 return None
639 return None
640
640
641 _opt2logrevset = {
641 _opt2logrevset = {
642 'no_merges': ('not merge()', None),
642 'no_merges': ('not merge()', None),
643 'only_merges': ('merge()', None),
643 'only_merges': ('merge()', None),
644 '_matchfiles': (None, '_matchfiles(%ps)'),
644 '_matchfiles': (None, '_matchfiles(%ps)'),
645 'date': ('date(%s)', None),
645 'date': ('date(%s)', None),
646 'branch': ('branch(%s)', '%lr'),
646 'branch': ('branch(%s)', '%lr'),
647 '_patslog': ('filelog(%s)', '%lr'),
647 '_patslog': ('filelog(%s)', '%lr'),
648 'keyword': ('keyword(%s)', '%lr'),
648 'keyword': ('keyword(%s)', '%lr'),
649 'prune': ('ancestors(%s)', 'not %lr'),
649 'prune': ('ancestors(%s)', 'not %lr'),
650 'user': ('user(%s)', '%lr'),
650 'user': ('user(%s)', '%lr'),
651 }
651 }
652
652
653 def _makerevset(repo, match, pats, slowpath, opts):
653 def _makerevset(repo, match, pats, slowpath, opts):
654 """Return a revset string built from log options and file patterns"""
654 """Return a revset string built from log options and file patterns"""
655 opts = dict(opts)
655 opts = dict(opts)
656 # follow or not follow?
656 # follow or not follow?
657 follow = opts.get('follow') or opts.get('follow_first')
657 follow = opts.get('follow') or opts.get('follow_first')
658
658
659 # branch and only_branch are really aliases and must be handled at
659 # branch and only_branch are really aliases and must be handled at
660 # the same time
660 # the same time
661 opts['branch'] = opts.get('branch', []) + opts.get('only_branch', [])
661 opts['branch'] = opts.get('branch', []) + opts.get('only_branch', [])
662 opts['branch'] = [repo.lookupbranch(b) for b in opts['branch']]
662 opts['branch'] = [repo.lookupbranch(b) for b in opts['branch']]
663
663
664 if slowpath:
664 if slowpath:
665 # See walkchangerevs() slow path.
665 # See walkchangerevs() slow path.
666 #
666 #
667 # pats/include/exclude cannot be represented as separate
667 # pats/include/exclude cannot be represented as separate
668 # revset expressions as their filtering logic applies at file
668 # revset expressions as their filtering logic applies at file
669 # level. For instance "-I a -X b" matches a revision touching
669 # level. For instance "-I a -X b" matches a revision touching
670 # "a" and "b" while "file(a) and not file(b)" does
670 # "a" and "b" while "file(a) and not file(b)" does
671 # not. Besides, filesets are evaluated against the working
671 # not. Besides, filesets are evaluated against the working
672 # directory.
672 # directory.
673 matchargs = ['r:', 'd:relpath']
673 matchargs = ['r:', 'd:relpath']
674 for p in pats:
674 for p in pats:
675 matchargs.append('p:' + p)
675 matchargs.append('p:' + p)
676 for p in opts.get('include', []):
676 for p in opts.get('include', []):
677 matchargs.append('i:' + p)
677 matchargs.append('i:' + p)
678 for p in opts.get('exclude', []):
678 for p in opts.get('exclude', []):
679 matchargs.append('x:' + p)
679 matchargs.append('x:' + p)
680 opts['_matchfiles'] = matchargs
680 opts['_matchfiles'] = matchargs
681 elif not follow:
681 elif not follow:
682 opts['_patslog'] = list(pats)
682 opts['_patslog'] = list(pats)
683
683
684 expr = []
684 expr = []
685 for op, val in sorted(opts.iteritems()):
685 for op, val in sorted(opts.iteritems()):
686 if not val:
686 if not val:
687 continue
687 continue
688 if op not in _opt2logrevset:
688 if op not in _opt2logrevset:
689 continue
689 continue
690 revop, listop = _opt2logrevset[op]
690 revop, listop = _opt2logrevset[op]
691 if revop and '%' not in revop:
691 if revop and '%' not in revop:
692 expr.append(revop)
692 expr.append(revop)
693 elif not listop:
693 elif not listop:
694 expr.append(revsetlang.formatspec(revop, val))
694 expr.append(revsetlang.formatspec(revop, val))
695 else:
695 else:
696 if revop:
696 if revop:
697 val = [revsetlang.formatspec(revop, v) for v in val]
697 val = [revsetlang.formatspec(revop, v) for v in val]
698 expr.append(revsetlang.formatspec(listop, val))
698 expr.append(revsetlang.formatspec(listop, val))
699
699
700 if expr:
700 if expr:
701 expr = '(' + ' and '.join(expr) + ')'
701 expr = '(' + ' and '.join(expr) + ')'
702 else:
702 else:
703 expr = None
703 expr = None
704 return expr
704 return expr
705
705
706 def _initialrevs(repo, opts):
706 def _initialrevs(repo, opts):
707 """Return the initial set of revisions to be filtered or followed"""
707 """Return the initial set of revisions to be filtered or followed"""
708 follow = opts.get('follow') or opts.get('follow_first')
708 follow = opts.get('follow') or opts.get('follow_first')
709 if opts.get('rev'):
709 if opts.get('rev'):
710 revs = scmutil.revrange(repo, opts['rev'])
710 revs = scmutil.revrange(repo, opts['rev'])
711 elif follow and repo.dirstate.p1() == nullid:
711 elif follow and repo.dirstate.p1() == nullid:
712 revs = smartset.baseset()
712 revs = smartset.baseset()
713 elif follow:
713 elif follow:
714 revs = repo.revs('.')
714 revs = repo.revs('.')
715 else:
715 else:
716 revs = smartset.spanset(repo)
716 revs = smartset.spanset(repo)
717 revs.reverse()
717 revs.reverse()
718 return revs
718 return revs
719
719
720 def getrevs(repo, pats, opts):
720 def getrevs(repo, pats, opts):
721 """Return (revs, differ) where revs is a smartset
721 """Return (revs, differ) where revs is a smartset
722
722
723 differ is a changesetdiffer with pre-configured file matcher.
723 differ is a changesetdiffer with pre-configured file matcher.
724 """
724 """
725 follow = opts.get('follow') or opts.get('follow_first')
725 follow = opts.get('follow') or opts.get('follow_first')
726 followfirst = opts.get('follow_first')
726 followfirst = opts.get('follow_first')
727 limit = getlimit(opts)
727 limit = getlimit(opts)
728 revs = _initialrevs(repo, opts)
728 revs = _initialrevs(repo, opts)
729 if not revs:
729 if not revs:
730 return smartset.baseset(), None
730 return smartset.baseset(), None
731 match, pats, slowpath = _makematcher(repo, revs, pats, opts)
731 match, pats, slowpath = _makematcher(repo, revs, pats, opts)
732 filematcher = None
732 filematcher = None
733 if follow:
733 if follow:
734 if slowpath or match.always():
734 if slowpath or match.always():
735 revs = dagop.revancestors(repo, revs, followfirst=followfirst)
735 revs = dagop.revancestors(repo, revs, followfirst=followfirst)
736 else:
736 else:
737 revs, filematcher = _fileancestors(repo, revs, match, followfirst)
737 revs, filematcher = _fileancestors(repo, revs, match, followfirst)
738 revs.reverse()
738 revs.reverse()
739 if filematcher is None:
739 if filematcher is None:
740 filematcher = _makenofollowfilematcher(repo, pats, opts)
740 filematcher = _makenofollowfilematcher(repo, pats, opts)
741 if filematcher is None:
741 if filematcher is None:
742 def filematcher(ctx):
742 def filematcher(ctx):
743 return match
743 return match
744
744
745 expr = _makerevset(repo, match, pats, slowpath, opts)
745 expr = _makerevset(repo, match, pats, slowpath, opts)
746 if opts.get('graph') and opts.get('rev'):
746 if opts.get('graph') and opts.get('rev'):
747 # User-specified revs might be unsorted, but don't sort before
747 # User-specified revs might be unsorted, but don't sort before
748 # _makerevset because it might depend on the order of revs
748 # _makerevset because it might depend on the order of revs
749 if not (revs.isdescending() or revs.istopo()):
749 if not (revs.isdescending() or revs.istopo()):
750 revs.sort(reverse=True)
750 revs.sort(reverse=True)
751 if expr:
751 if expr:
752 matcher = revset.match(None, expr)
752 matcher = revset.match(None, expr)
753 revs = matcher(repo, revs)
753 revs = matcher(repo, revs)
754 if limit is not None:
754 if limit is not None:
755 revs = revs.slice(0, limit)
755 revs = revs.slice(0, limit)
756
756
757 differ = changesetdiffer()
757 differ = changesetdiffer()
758 differ._makefilematcher = filematcher
758 differ._makefilematcher = filematcher
759 return revs, differ
759 return revs, differ
760
760
761 def _parselinerangeopt(repo, opts):
761 def _parselinerangeopt(repo, opts):
762 """Parse --line-range log option and return a list of tuples (filename,
762 """Parse --line-range log option and return a list of tuples (filename,
763 (fromline, toline)).
763 (fromline, toline)).
764 """
764 """
765 linerangebyfname = []
765 linerangebyfname = []
766 for pat in opts.get('line_range', []):
766 for pat in opts.get('line_range', []):
767 try:
767 try:
768 pat, linerange = pat.rsplit(',', 1)
768 pat, linerange = pat.rsplit(',', 1)
769 except ValueError:
769 except ValueError:
770 raise error.Abort(_('malformatted line-range pattern %s') % pat)
770 raise error.Abort(_('malformatted line-range pattern %s') % pat)
771 try:
771 try:
772 fromline, toline = map(int, linerange.split(':'))
772 fromline, toline = map(int, linerange.split(':'))
773 except ValueError:
773 except ValueError:
774 raise error.Abort(_("invalid line range for %s") % pat)
774 raise error.Abort(_("invalid line range for %s") % pat)
775 msg = _("line range pattern '%s' must match exactly one file") % pat
775 msg = _("line range pattern '%s' must match exactly one file") % pat
776 fname = scmutil.parsefollowlinespattern(repo, None, pat, msg)
776 fname = scmutil.parsefollowlinespattern(repo, None, pat, msg)
777 linerangebyfname.append(
777 linerangebyfname.append(
778 (fname, util.processlinerange(fromline, toline)))
778 (fname, util.processlinerange(fromline, toline)))
779 return linerangebyfname
779 return linerangebyfname
780
780
781 def getlinerangerevs(repo, userrevs, opts):
781 def getlinerangerevs(repo, userrevs, opts):
782 """Return (revs, differ).
782 """Return (revs, differ).
783
783
784 "revs" are revisions obtained by processing "line-range" log options and
784 "revs" are revisions obtained by processing "line-range" log options and
785 walking block ancestors of each specified file/line-range.
785 walking block ancestors of each specified file/line-range.
786
786
787 "differ" is a changesetdiffer with pre-configured file matcher and hunks
787 "differ" is a changesetdiffer with pre-configured file matcher and hunks
788 filter.
788 filter.
789 """
789 """
790 wctx = repo[None]
790 wctx = repo[None]
791
791
792 # Two-levels map of "rev -> file ctx -> [line range]".
792 # Two-levels map of "rev -> file ctx -> [line range]".
793 linerangesbyrev = {}
793 linerangesbyrev = {}
794 for fname, (fromline, toline) in _parselinerangeopt(repo, opts):
794 for fname, (fromline, toline) in _parselinerangeopt(repo, opts):
795 if fname not in wctx:
795 if fname not in wctx:
796 raise error.Abort(_('cannot follow file not in parent '
796 raise error.Abort(_('cannot follow file not in parent '
797 'revision: "%s"') % fname)
797 'revision: "%s"') % fname)
798 fctx = wctx.filectx(fname)
798 fctx = wctx.filectx(fname)
799 for fctx, linerange in dagop.blockancestors(fctx, fromline, toline):
799 for fctx, linerange in dagop.blockancestors(fctx, fromline, toline):
800 rev = fctx.introrev()
800 rev = fctx.introrev()
801 if rev not in userrevs:
801 if rev not in userrevs:
802 continue
802 continue
803 linerangesbyrev.setdefault(
803 linerangesbyrev.setdefault(
804 rev, {}).setdefault(
804 rev, {}).setdefault(
805 fctx.path(), []).append(linerange)
805 fctx.path(), []).append(linerange)
806
806
807 def nofilterhunksfn(fctx, hunks):
807 def nofilterhunksfn(fctx, hunks):
808 return hunks
808 return hunks
809
809
810 def hunksfilter(ctx):
810 def hunksfilter(ctx):
811 fctxlineranges = linerangesbyrev.get(ctx.rev())
811 fctxlineranges = linerangesbyrev.get(ctx.rev())
812 if fctxlineranges is None:
812 if fctxlineranges is None:
813 return nofilterhunksfn
813 return nofilterhunksfn
814
814
815 def filterfn(fctx, hunks):
815 def filterfn(fctx, hunks):
816 lineranges = fctxlineranges.get(fctx.path())
816 lineranges = fctxlineranges.get(fctx.path())
817 if lineranges is not None:
817 if lineranges is not None:
818 for hr, lines in hunks:
818 for hr, lines in hunks:
819 if hr is None: # binary
819 if hr is None: # binary
820 yield hr, lines
820 yield hr, lines
821 continue
821 continue
822 if any(mdiff.hunkinrange(hr[2:], lr)
822 if any(mdiff.hunkinrange(hr[2:], lr)
823 for lr in lineranges):
823 for lr in lineranges):
824 yield hr, lines
824 yield hr, lines
825 else:
825 else:
826 for hunk in hunks:
826 for hunk in hunks:
827 yield hunk
827 yield hunk
828
828
829 return filterfn
829 return filterfn
830
830
831 def filematcher(ctx):
831 def filematcher(ctx):
832 files = list(linerangesbyrev.get(ctx.rev(), []))
832 files = list(linerangesbyrev.get(ctx.rev(), []))
833 return scmutil.matchfiles(repo, files)
833 return scmutil.matchfiles(repo, files)
834
834
835 revs = sorted(linerangesbyrev, reverse=True)
835 revs = sorted(linerangesbyrev, reverse=True)
836
836
837 differ = changesetdiffer()
837 differ = changesetdiffer()
838 differ._makefilematcher = filematcher
838 differ._makefilematcher = filematcher
839 differ._makehunksfilter = hunksfilter
839 differ._makehunksfilter = hunksfilter
840 return revs, differ
840 return revs, differ
841
841
842 def _graphnodeformatter(ui, displayer):
842 def _graphnodeformatter(ui, displayer):
843 spec = ui.config('ui', 'graphnodetemplate')
843 spec = ui.config('ui', 'graphnodetemplate')
844 if not spec:
844 if not spec:
845 return templatekw.getgraphnode # fast path for "{graphnode}"
845 return templatekw.getgraphnode # fast path for "{graphnode}"
846
846
847 spec = templater.unquotestring(spec)
847 spec = templater.unquotestring(spec)
848 if isinstance(displayer, changesettemplater):
848 if isinstance(displayer, changesettemplater):
849 # reuse cache of slow templates
849 # reuse cache of slow templates
850 tres = displayer._tresources
850 tres = displayer._tresources
851 else:
851 else:
852 tres = formatter.templateresources(ui)
852 tres = formatter.templateresources(ui)
853 templ = formatter.maketemplater(ui, spec, defaults=templatekw.keywords,
853 templ = formatter.maketemplater(ui, spec, defaults=templatekw.keywords,
854 resources=tres)
854 resources=tres)
855 def formatnode(repo, ctx):
855 def formatnode(repo, ctx):
856 props = {'ctx': ctx, 'repo': repo}
856 props = {'ctx': ctx, 'repo': repo}
857 return templ.renderdefault(props)
857 return templ.renderdefault(props)
858 return formatnode
858 return formatnode
859
859
860 def displaygraph(ui, repo, dag, displayer, edgefn, getrenamed=None, props=None):
860 def displaygraph(ui, repo, dag, displayer, edgefn, getrenamed=None, props=None):
861 props = props or {}
861 props = props or {}
862 formatnode = _graphnodeformatter(ui, displayer)
862 formatnode = _graphnodeformatter(ui, displayer)
863 state = graphmod.asciistate()
863 state = graphmod.asciistate()
864 styles = state['styles']
864 styles = state['styles']
865
865
866 # only set graph styling if HGPLAIN is not set.
866 # only set graph styling if HGPLAIN is not set.
867 if ui.plain('graph'):
867 if ui.plain('graph'):
868 # set all edge styles to |, the default pre-3.8 behaviour
868 # set all edge styles to |, the default pre-3.8 behaviour
869 styles.update(dict.fromkeys(styles, '|'))
869 styles.update(dict.fromkeys(styles, '|'))
870 else:
870 else:
871 edgetypes = {
871 edgetypes = {
872 'parent': graphmod.PARENT,
872 'parent': graphmod.PARENT,
873 'grandparent': graphmod.GRANDPARENT,
873 'grandparent': graphmod.GRANDPARENT,
874 'missing': graphmod.MISSINGPARENT
874 'missing': graphmod.MISSINGPARENT
875 }
875 }
876 for name, key in edgetypes.items():
876 for name, key in edgetypes.items():
877 # experimental config: experimental.graphstyle.*
877 # experimental config: experimental.graphstyle.*
878 styles[key] = ui.config('experimental', 'graphstyle.%s' % name,
878 styles[key] = ui.config('experimental', 'graphstyle.%s' % name,
879 styles[key])
879 styles[key])
880 if not styles[key]:
880 if not styles[key]:
881 styles[key] = None
881 styles[key] = None
882
882
883 # experimental config: experimental.graphshorten
883 # experimental config: experimental.graphshorten
884 state['graphshorten'] = ui.configbool('experimental', 'graphshorten')
884 state['graphshorten'] = ui.configbool('experimental', 'graphshorten')
885
885
886 for rev, type, ctx, parents in dag:
886 for rev, type, ctx, parents in dag:
887 char = formatnode(repo, ctx)
887 char = formatnode(repo, ctx)
888 copies = None
888 copies = None
889 if getrenamed and ctx.rev():
889 if getrenamed and ctx.rev():
890 copies = []
890 copies = []
891 for fn in ctx.files():
891 for fn in ctx.files():
892 rename = getrenamed(fn, ctx.rev())
892 rename = getrenamed(fn, ctx.rev())
893 if rename:
893 if rename:
894 copies.append((fn, rename))
894 copies.append((fn, rename))
895 edges = edgefn(type, char, state, rev, parents)
895 edges = edgefn(type, char, state, rev, parents)
896 firstedge = next(edges)
896 firstedge = next(edges)
897 width = firstedge[2]
897 width = firstedge[2]
898 displayer.show(ctx, copies=copies,
898 displayer.show(ctx, copies=copies,
899 graphwidth=width, **pycompat.strkwargs(props))
899 graphwidth=width, **pycompat.strkwargs(props))
900 lines = displayer.hunk.pop(rev).split('\n')
900 lines = displayer.hunk.pop(rev).split('\n')
901 if not lines[-1]:
901 if not lines[-1]:
902 del lines[-1]
902 del lines[-1]
903 displayer.flush(ctx)
903 displayer.flush(ctx)
904 for type, char, width, coldata in itertools.chain([firstedge], edges):
904 for type, char, width, coldata in itertools.chain([firstedge], edges):
905 graphmod.ascii(ui, state, type, char, lines, coldata)
905 graphmod.ascii(ui, state, type, char, lines, coldata)
906 lines = []
906 lines = []
907 displayer.close()
907 displayer.close()
908
908
909 def displaygraphrevs(ui, repo, revs, displayer, getrenamed):
909 def displaygraphrevs(ui, repo, revs, displayer, getrenamed):
910 revdag = graphmod.dagwalker(repo, revs)
910 revdag = graphmod.dagwalker(repo, revs)
911 displaygraph(ui, repo, revdag, displayer, graphmod.asciiedges, getrenamed)
911 displaygraph(ui, repo, revdag, displayer, graphmod.asciiedges, getrenamed)
912
912
913 def displayrevs(ui, repo, revs, displayer, getrenamed):
913 def displayrevs(ui, repo, revs, displayer, getrenamed):
914 for rev in revs:
914 for rev in revs:
915 ctx = repo[rev]
915 ctx = repo[rev]
916 copies = None
916 copies = None
917 if getrenamed is not None and rev:
917 if getrenamed is not None and rev:
918 copies = []
918 copies = []
919 for fn in ctx.files():
919 for fn in ctx.files():
920 rename = getrenamed(fn, rev)
920 rename = getrenamed(fn, rev)
921 if rename:
921 if rename:
922 copies.append((fn, rename))
922 copies.append((fn, rename))
923 displayer.show(ctx, copies=copies)
923 displayer.show(ctx, copies=copies)
924 displayer.flush(ctx)
924 displayer.flush(ctx)
925 displayer.close()
925 displayer.close()
926
926
927 def checkunsupportedgraphflags(pats, opts):
927 def checkunsupportedgraphflags(pats, opts):
928 for op in ["newest_first"]:
928 for op in ["newest_first"]:
929 if op in opts and opts[op]:
929 if op in opts and opts[op]:
930 raise error.Abort(_("-G/--graph option is incompatible with --%s")
930 raise error.Abort(_("-G/--graph option is incompatible with --%s")
931 % op.replace("_", "-"))
931 % op.replace("_", "-"))
932
932
933 def graphrevs(repo, nodes, opts):
933 def graphrevs(repo, nodes, opts):
934 limit = getlimit(opts)
934 limit = getlimit(opts)
935 nodes.reverse()
935 nodes.reverse()
936 if limit is not None:
936 if limit is not None:
937 nodes = nodes[:limit]
937 nodes = nodes[:limit]
938 return graphmod.nodes(repo, nodes)
938 return graphmod.nodes(repo, nodes)
@@ -1,1997 +1,2010 b''
1 Let commit recurse into subrepos by default to match pre-2.0 behavior:
1 Let commit recurse into subrepos by default to match pre-2.0 behavior:
2
2
3 $ echo "[ui]" >> $HGRCPATH
3 $ echo "[ui]" >> $HGRCPATH
4 $ echo "commitsubrepos = Yes" >> $HGRCPATH
4 $ echo "commitsubrepos = Yes" >> $HGRCPATH
5
5
6 $ hg init t
6 $ hg init t
7 $ cd t
7 $ cd t
8
8
9 first revision, no sub
9 first revision, no sub
10
10
11 $ echo a > a
11 $ echo a > a
12 $ hg ci -Am0
12 $ hg ci -Am0
13 adding a
13 adding a
14
14
15 add first sub
15 add first sub
16
16
17 $ echo s = s > .hgsub
17 $ echo s = s > .hgsub
18 $ hg add .hgsub
18 $ hg add .hgsub
19 $ hg init s
19 $ hg init s
20 $ echo a > s/a
20 $ echo a > s/a
21
21
22 Issue2232: committing a subrepo without .hgsub
22 Issue2232: committing a subrepo without .hgsub
23
23
24 $ hg ci -mbad s
24 $ hg ci -mbad s
25 abort: can't commit subrepos without .hgsub
25 abort: can't commit subrepos without .hgsub
26 [255]
26 [255]
27
27
28 $ hg -R s add s/a
28 $ hg -R s add s/a
29 $ hg files -S
29 $ hg files -S
30 .hgsub
30 .hgsub
31 a
31 a
32 s/a
32 s/a
33
33
34 `hg files` respects ui.relative-paths
34 `hg files` respects ui.relative-paths
35 BROKEN: shows subrepo paths relative to the subrepo
35 BROKEN: shows subrepo paths relative to the subrepo
36 $ hg files -S --config ui.relative-paths=no
36 $ hg files -S --config ui.relative-paths=no
37 .hgsub
37 .hgsub
38 a
38 a
39 s/a
39 s/a
40
40
41 $ hg -R s ci -Ams0
41 $ hg -R s ci -Ams0
42 $ hg sum
42 $ hg sum
43 parent: 0:f7b1eb17ad24 tip
43 parent: 0:f7b1eb17ad24 tip
44 0
44 0
45 branch: default
45 branch: default
46 commit: 1 added, 1 subrepos
46 commit: 1 added, 1 subrepos
47 update: (current)
47 update: (current)
48 phases: 1 draft
48 phases: 1 draft
49 $ hg ci -m1
49 $ hg ci -m1
50
50
51 test handling .hgsubstate "added" explicitly.
51 test handling .hgsubstate "added" explicitly.
52
52
53 $ hg parents --template '{node}\n{files}\n'
53 $ hg parents --template '{node}\n{files}\n'
54 7cf8cfea66e410e8e3336508dfeec07b3192de51
54 7cf8cfea66e410e8e3336508dfeec07b3192de51
55 .hgsub .hgsubstate
55 .hgsub .hgsubstate
56 $ hg rollback -q
56 $ hg rollback -q
57 $ hg add .hgsubstate
57 $ hg add .hgsubstate
58 $ hg ci -m1
58 $ hg ci -m1
59 $ hg parents --template '{node}\n{files}\n'
59 $ hg parents --template '{node}\n{files}\n'
60 7cf8cfea66e410e8e3336508dfeec07b3192de51
60 7cf8cfea66e410e8e3336508dfeec07b3192de51
61 .hgsub .hgsubstate
61 .hgsub .hgsubstate
62
62
63 Subrepopath which overlaps with filepath, does not change warnings in remove()
63 Subrepopath which overlaps with filepath, does not change warnings in remove()
64
64
65 $ mkdir snot
65 $ mkdir snot
66 $ touch snot/file
66 $ touch snot/file
67 $ hg remove -S snot/file
67 $ hg remove -S snot/file
68 not removing snot/file: file is untracked
68 not removing snot/file: file is untracked
69 [1]
69 [1]
70 $ hg cat snot/filenot
70 $ hg cat snot/filenot
71 snot/filenot: no such file in rev 7cf8cfea66e4
71 snot/filenot: no such file in rev 7cf8cfea66e4
72 [1]
72 [1]
73 $ rm -r snot
73 $ rm -r snot
74
74
75 Revert subrepo and test subrepo fileset keyword:
75 Revert subrepo and test subrepo fileset keyword:
76
76
77 $ echo b > s/a
77 $ echo b > s/a
78 $ hg revert --dry-run "set:subrepo('glob:s*')"
78 $ hg revert --dry-run "set:subrepo('glob:s*')"
79 reverting subrepo s
79 reverting subrepo s
80 reverting s/a
80 reverting s/a
81 $ cat s/a
81 $ cat s/a
82 b
82 b
83 $ hg revert "set:subrepo('glob:s*')"
83 $ hg revert "set:subrepo('glob:s*')"
84 reverting subrepo s
84 reverting subrepo s
85 reverting s/a
85 reverting s/a
86 $ cat s/a
86 $ cat s/a
87 a
87 a
88 $ rm s/a.orig
88 $ rm s/a.orig
89
89
90 Revert subrepo with no backup. The "reverting s/a" line is gone since
90 Revert subrepo with no backup. The "reverting s/a" line is gone since
91 we're really running 'hg update' in the subrepo:
91 we're really running 'hg update' in the subrepo:
92
92
93 $ echo b > s/a
93 $ echo b > s/a
94 $ hg revert --no-backup s
94 $ hg revert --no-backup s
95 reverting subrepo s
95 reverting subrepo s
96
96
97 Issue2022: update -C
97 Issue2022: update -C
98
98
99 $ echo b > s/a
99 $ echo b > s/a
100 $ hg sum
100 $ hg sum
101 parent: 1:7cf8cfea66e4 tip
101 parent: 1:7cf8cfea66e4 tip
102 1
102 1
103 branch: default
103 branch: default
104 commit: 1 subrepos
104 commit: 1 subrepos
105 update: (current)
105 update: (current)
106 phases: 2 draft
106 phases: 2 draft
107 $ hg co -C 1
107 $ hg co -C 1
108 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
108 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
109 $ hg sum
109 $ hg sum
110 parent: 1:7cf8cfea66e4 tip
110 parent: 1:7cf8cfea66e4 tip
111 1
111 1
112 branch: default
112 branch: default
113 commit: (clean)
113 commit: (clean)
114 update: (current)
114 update: (current)
115 phases: 2 draft
115 phases: 2 draft
116
116
117 commands that require a clean repo should respect subrepos
117 commands that require a clean repo should respect subrepos
118
118
119 $ echo b >> s/a
119 $ echo b >> s/a
120 $ hg backout tip
120 $ hg backout tip
121 abort: uncommitted changes in subrepository "s"
121 abort: uncommitted changes in subrepository "s"
122 [255]
122 [255]
123 $ hg revert -C -R s s/a
123 $ hg revert -C -R s s/a
124
124
125 add sub sub
125 add sub sub
126
126
127 $ echo ss = ss > s/.hgsub
127 $ echo ss = ss > s/.hgsub
128 $ hg init s/ss
128 $ hg init s/ss
129 $ echo a > s/ss/a
129 $ echo a > s/ss/a
130 $ hg -R s add s/.hgsub
130 $ hg -R s add s/.hgsub
131 $ hg -R s/ss add s/ss/a
131 $ hg -R s/ss add s/ss/a
132 $ hg sum
132 $ hg sum
133 parent: 1:7cf8cfea66e4 tip
133 parent: 1:7cf8cfea66e4 tip
134 1
134 1
135 branch: default
135 branch: default
136 commit: 1 subrepos
136 commit: 1 subrepos
137 update: (current)
137 update: (current)
138 phases: 2 draft
138 phases: 2 draft
139 $ hg ci -m2
139 $ hg ci -m2
140 committing subrepository s
140 committing subrepository s
141 committing subrepository s/ss
141 committing subrepository s/ss
142 $ hg sum
142 $ hg sum
143 parent: 2:df30734270ae tip
143 parent: 2:df30734270ae tip
144 2
144 2
145 branch: default
145 branch: default
146 commit: (clean)
146 commit: (clean)
147 update: (current)
147 update: (current)
148 phases: 3 draft
148 phases: 3 draft
149
149
150 test handling .hgsubstate "modified" explicitly.
150 test handling .hgsubstate "modified" explicitly.
151
151
152 $ hg parents --template '{node}\n{files}\n'
152 $ hg parents --template '{node}\n{files}\n'
153 df30734270ae757feb35e643b7018e818e78a9aa
153 df30734270ae757feb35e643b7018e818e78a9aa
154 .hgsubstate
154 .hgsubstate
155 $ hg rollback -q
155 $ hg rollback -q
156 $ hg status -A .hgsubstate
156 $ hg status -A .hgsubstate
157 M .hgsubstate
157 M .hgsubstate
158 $ hg ci -m2
158 $ hg ci -m2
159 $ hg parents --template '{node}\n{files}\n'
159 $ hg parents --template '{node}\n{files}\n'
160 df30734270ae757feb35e643b7018e818e78a9aa
160 df30734270ae757feb35e643b7018e818e78a9aa
161 .hgsubstate
161 .hgsubstate
162
162
163 bump sub rev (and check it is ignored by ui.commitsubrepos)
163 bump sub rev (and check it is ignored by ui.commitsubrepos)
164
164
165 $ echo b > s/a
165 $ echo b > s/a
166 $ hg -R s ci -ms1
166 $ hg -R s ci -ms1
167 $ hg --config ui.commitsubrepos=no ci -m3
167 $ hg --config ui.commitsubrepos=no ci -m3
168
168
169 leave sub dirty (and check ui.commitsubrepos=no aborts the commit)
169 leave sub dirty (and check ui.commitsubrepos=no aborts the commit)
170
170
171 $ echo c > s/a
171 $ echo c > s/a
172 $ hg --config ui.commitsubrepos=no ci -m4
172 $ hg --config ui.commitsubrepos=no ci -m4
173 abort: uncommitted changes in subrepository "s"
173 abort: uncommitted changes in subrepository "s"
174 (use --subrepos for recursive commit)
174 (use --subrepos for recursive commit)
175 [255]
175 [255]
176 $ hg id
176 $ hg id
177 f6affe3fbfaa+ tip
177 f6affe3fbfaa+ tip
178 $ hg -R s ci -mc
178 $ hg -R s ci -mc
179 $ hg id
179 $ hg id
180 f6affe3fbfaa+ tip
180 f6affe3fbfaa+ tip
181 $ echo d > s/a
181 $ echo d > s/a
182 $ hg ci -m4
182 $ hg ci -m4
183 committing subrepository s
183 committing subrepository s
184 $ hg tip -R s
184 $ hg tip -R s
185 changeset: 4:02dcf1d70411
185 changeset: 4:02dcf1d70411
186 tag: tip
186 tag: tip
187 user: test
187 user: test
188 date: Thu Jan 01 00:00:00 1970 +0000
188 date: Thu Jan 01 00:00:00 1970 +0000
189 summary: 4
189 summary: 4
190
190
191
191
192 check caching
192 check caching
193
193
194 $ hg co 0
194 $ hg co 0
195 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
195 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
196 $ hg debugsub
196 $ hg debugsub
197
197
198 restore
198 restore
199
199
200 $ hg co
200 $ hg co
201 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
201 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
202 $ hg debugsub
202 $ hg debugsub
203 path s
203 path s
204 source s
204 source s
205 revision 02dcf1d704118aee3ee306ccfa1910850d5b05ef
205 revision 02dcf1d704118aee3ee306ccfa1910850d5b05ef
206
206
207 new branch for merge tests
207 new branch for merge tests
208
208
209 $ hg co 1
209 $ hg co 1
210 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
210 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
211 $ echo t = t >> .hgsub
211 $ echo t = t >> .hgsub
212 $ hg init t
212 $ hg init t
213 $ echo t > t/t
213 $ echo t > t/t
214 $ hg -R t add t
214 $ hg -R t add t
215 adding t/t
215 adding t/t
216
216
217 5
217 5
218
218
219 $ hg ci -m5 # add sub
219 $ hg ci -m5 # add sub
220 committing subrepository t
220 committing subrepository t
221 created new head
221 created new head
222 $ echo t2 > t/t
222 $ echo t2 > t/t
223
223
224 6
224 6
225
225
226 $ hg st -R s
226 $ hg st -R s
227 $ hg ci -m6 # change sub
227 $ hg ci -m6 # change sub
228 committing subrepository t
228 committing subrepository t
229 $ hg debugsub
229 $ hg debugsub
230 path s
230 path s
231 source s
231 source s
232 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
232 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
233 path t
233 path t
234 source t
234 source t
235 revision 6747d179aa9a688023c4b0cad32e4c92bb7f34ad
235 revision 6747d179aa9a688023c4b0cad32e4c92bb7f34ad
236 $ echo t3 > t/t
236 $ echo t3 > t/t
237
237
238 7
238 7
239
239
240 $ hg ci -m7 # change sub again for conflict test
240 $ hg ci -m7 # change sub again for conflict test
241 committing subrepository t
241 committing subrepository t
242 $ hg rm .hgsub
242 $ hg rm .hgsub
243
243
244 8
244 8
245
245
246 $ hg ci -m8 # remove sub
246 $ hg ci -m8 # remove sub
247
247
248 test handling .hgsubstate "removed" explicitly.
248 test handling .hgsubstate "removed" explicitly.
249
249
250 $ hg parents --template '{node}\n{files}\n'
250 $ hg parents --template '{node}\n{files}\n'
251 96615c1dad2dc8e3796d7332c77ce69156f7b78e
251 96615c1dad2dc8e3796d7332c77ce69156f7b78e
252 .hgsub .hgsubstate
252 .hgsub .hgsubstate
253 $ hg rollback -q
253 $ hg rollback -q
254 $ hg remove .hgsubstate
254 $ hg remove .hgsubstate
255 $ hg ci -m8
255 $ hg ci -m8
256 $ hg parents --template '{node}\n{files}\n'
256 $ hg parents --template '{node}\n{files}\n'
257 96615c1dad2dc8e3796d7332c77ce69156f7b78e
257 96615c1dad2dc8e3796d7332c77ce69156f7b78e
258 .hgsub .hgsubstate
258 .hgsub .hgsubstate
259
259
260 merge tests
260 merge tests
261
261
262 $ hg co -C 3
262 $ hg co -C 3
263 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
263 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
264 $ hg merge 5 # test adding
264 $ hg merge 5 # test adding
265 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
265 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
266 (branch merge, don't forget to commit)
266 (branch merge, don't forget to commit)
267 $ hg debugsub
267 $ hg debugsub
268 path s
268 path s
269 source s
269 source s
270 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
270 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
271 path t
271 path t
272 source t
272 source t
273 revision 60ca1237c19474e7a3978b0dc1ca4e6f36d51382
273 revision 60ca1237c19474e7a3978b0dc1ca4e6f36d51382
274 $ hg ci -m9
274 $ hg ci -m9
275 created new head
275 created new head
276 $ hg merge 6 --debug # test change
276 $ hg merge 6 --debug # test change
277 searching for copies back to rev 2
277 searching for copies back to rev 2
278 resolving manifests
278 resolving manifests
279 branchmerge: True, force: False, partial: False
279 branchmerge: True, force: False, partial: False
280 ancestor: 1f14a2e2d3ec, local: f0d2028bf86d+, remote: 1831e14459c4
280 ancestor: 1f14a2e2d3ec, local: f0d2028bf86d+, remote: 1831e14459c4
281 starting 4 threads for background file closing (?)
281 starting 4 threads for background file closing (?)
282 .hgsubstate: versions differ -> m (premerge)
282 .hgsubstate: versions differ -> m (premerge)
283 subrepo merge f0d2028bf86d+ 1831e14459c4 1f14a2e2d3ec
283 subrepo merge f0d2028bf86d+ 1831e14459c4 1f14a2e2d3ec
284 subrepo t: other changed, get t:6747d179aa9a688023c4b0cad32e4c92bb7f34ad:hg
284 subrepo t: other changed, get t:6747d179aa9a688023c4b0cad32e4c92bb7f34ad:hg
285 getting subrepo t
285 getting subrepo t
286 resolving manifests
286 resolving manifests
287 branchmerge: False, force: False, partial: False
287 branchmerge: False, force: False, partial: False
288 ancestor: 60ca1237c194, local: 60ca1237c194+, remote: 6747d179aa9a
288 ancestor: 60ca1237c194, local: 60ca1237c194+, remote: 6747d179aa9a
289 t: remote is newer -> g
289 t: remote is newer -> g
290 getting t
290 getting t
291 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
291 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
292 (branch merge, don't forget to commit)
292 (branch merge, don't forget to commit)
293 $ hg debugsub
293 $ hg debugsub
294 path s
294 path s
295 source s
295 source s
296 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
296 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
297 path t
297 path t
298 source t
298 source t
299 revision 6747d179aa9a688023c4b0cad32e4c92bb7f34ad
299 revision 6747d179aa9a688023c4b0cad32e4c92bb7f34ad
300 $ echo conflict > t/t
300 $ echo conflict > t/t
301 $ hg ci -m10
301 $ hg ci -m10
302 committing subrepository t
302 committing subrepository t
303 $ HGMERGE=internal:merge hg merge --debug 7 # test conflict
303 $ HGMERGE=internal:merge hg merge --debug 7 # test conflict
304 searching for copies back to rev 2
304 searching for copies back to rev 2
305 resolving manifests
305 resolving manifests
306 branchmerge: True, force: False, partial: False
306 branchmerge: True, force: False, partial: False
307 ancestor: 1831e14459c4, local: e45c8b14af55+, remote: f94576341bcf
307 ancestor: 1831e14459c4, local: e45c8b14af55+, remote: f94576341bcf
308 starting 4 threads for background file closing (?)
308 starting 4 threads for background file closing (?)
309 .hgsubstate: versions differ -> m (premerge)
309 .hgsubstate: versions differ -> m (premerge)
310 subrepo merge e45c8b14af55+ f94576341bcf 1831e14459c4
310 subrepo merge e45c8b14af55+ f94576341bcf 1831e14459c4
311 subrepo t: both sides changed
311 subrepo t: both sides changed
312 subrepository t diverged (local revision: 20a0db6fbf6c, remote revision: 7af322bc1198)
312 subrepository t diverged (local revision: 20a0db6fbf6c, remote revision: 7af322bc1198)
313 starting 4 threads for background file closing (?)
313 starting 4 threads for background file closing (?)
314 (M)erge, keep (l)ocal [working copy] or keep (r)emote [merge rev]? m
314 (M)erge, keep (l)ocal [working copy] or keep (r)emote [merge rev]? m
315 merging subrepository "t"
315 merging subrepository "t"
316 searching for copies back to rev 2
316 searching for copies back to rev 2
317 resolving manifests
317 resolving manifests
318 branchmerge: True, force: False, partial: False
318 branchmerge: True, force: False, partial: False
319 ancestor: 6747d179aa9a, local: 20a0db6fbf6c+, remote: 7af322bc1198
319 ancestor: 6747d179aa9a, local: 20a0db6fbf6c+, remote: 7af322bc1198
320 preserving t for resolve of t
320 preserving t for resolve of t
321 starting 4 threads for background file closing (?)
321 starting 4 threads for background file closing (?)
322 t: versions differ -> m (premerge)
322 t: versions differ -> m (premerge)
323 picked tool ':merge' for t (binary False symlink False changedelete False)
323 picked tool ':merge' for t (binary False symlink False changedelete False)
324 merging t
324 merging t
325 my t@20a0db6fbf6c+ other t@7af322bc1198 ancestor t@6747d179aa9a
325 my t@20a0db6fbf6c+ other t@7af322bc1198 ancestor t@6747d179aa9a
326 t: versions differ -> m (merge)
326 t: versions differ -> m (merge)
327 picked tool ':merge' for t (binary False symlink False changedelete False)
327 picked tool ':merge' for t (binary False symlink False changedelete False)
328 my t@20a0db6fbf6c+ other t@7af322bc1198 ancestor t@6747d179aa9a
328 my t@20a0db6fbf6c+ other t@7af322bc1198 ancestor t@6747d179aa9a
329 warning: conflicts while merging t! (edit, then use 'hg resolve --mark')
329 warning: conflicts while merging t! (edit, then use 'hg resolve --mark')
330 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
330 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
331 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
331 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
332 subrepo t: merge with t:7af322bc1198a32402fe903e0b7ebcfc5c9bf8f4:hg
332 subrepo t: merge with t:7af322bc1198a32402fe903e0b7ebcfc5c9bf8f4:hg
333 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
333 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
334 (branch merge, don't forget to commit)
334 (branch merge, don't forget to commit)
335
335
336 should conflict
336 should conflict
337
337
338 $ cat t/t
338 $ cat t/t
339 <<<<<<< local: 20a0db6fbf6c - test: 10
339 <<<<<<< local: 20a0db6fbf6c - test: 10
340 conflict
340 conflict
341 =======
341 =======
342 t3
342 t3
343 >>>>>>> other: 7af322bc1198 - test: 7
343 >>>>>>> other: 7af322bc1198 - test: 7
344
344
345 11: remove subrepo t
345 11: remove subrepo t
346
346
347 $ hg co -C 5
347 $ hg co -C 5
348 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
348 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
349 $ hg revert -r 4 .hgsub # remove t
349 $ hg revert -r 4 .hgsub # remove t
350 $ hg ci -m11
350 $ hg ci -m11
351 created new head
351 created new head
352 $ hg debugsub
352 $ hg debugsub
353 path s
353 path s
354 source s
354 source s
355 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
355 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
356
356
357 local removed, remote changed, keep changed
357 local removed, remote changed, keep changed
358
358
359 $ hg merge 6
359 $ hg merge 6
360 remote [merge rev] changed subrepository t which local [working copy] removed
360 remote [merge rev] changed subrepository t which local [working copy] removed
361 use (c)hanged version or (d)elete? c
361 use (c)hanged version or (d)elete? c
362 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
362 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
363 (branch merge, don't forget to commit)
363 (branch merge, don't forget to commit)
364 BROKEN: should include subrepo t
364 BROKEN: should include subrepo t
365 $ hg debugsub
365 $ hg debugsub
366 path s
366 path s
367 source s
367 source s
368 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
368 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
369 $ cat .hgsubstate
369 $ cat .hgsubstate
370 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
370 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
371 6747d179aa9a688023c4b0cad32e4c92bb7f34ad t
371 6747d179aa9a688023c4b0cad32e4c92bb7f34ad t
372 $ hg ci -m 'local removed, remote changed, keep changed'
372 $ hg ci -m 'local removed, remote changed, keep changed'
373 BROKEN: should include subrepo t
373 BROKEN: should include subrepo t
374 $ hg debugsub
374 $ hg debugsub
375 path s
375 path s
376 source s
376 source s
377 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
377 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
378 BROKEN: should include subrepo t
378 BROKEN: should include subrepo t
379 $ cat .hgsubstate
379 $ cat .hgsubstate
380 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
380 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
381 $ cat t/t
381 $ cat t/t
382 t2
382 t2
383
383
384 local removed, remote changed, keep removed
384 local removed, remote changed, keep removed
385
385
386 $ hg co -C 11
386 $ hg co -C 11
387 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
387 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
388 $ hg merge --config ui.interactive=true 6 <<EOF
388 $ hg merge --config ui.interactive=true 6 <<EOF
389 > d
389 > d
390 > EOF
390 > EOF
391 remote [merge rev] changed subrepository t which local [working copy] removed
391 remote [merge rev] changed subrepository t which local [working copy] removed
392 use (c)hanged version or (d)elete? d
392 use (c)hanged version or (d)elete? d
393 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
393 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
394 (branch merge, don't forget to commit)
394 (branch merge, don't forget to commit)
395 $ hg debugsub
395 $ hg debugsub
396 path s
396 path s
397 source s
397 source s
398 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
398 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
399 $ cat .hgsubstate
399 $ cat .hgsubstate
400 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
400 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
401 $ hg ci -m 'local removed, remote changed, keep removed'
401 $ hg ci -m 'local removed, remote changed, keep removed'
402 created new head
402 created new head
403 $ hg debugsub
403 $ hg debugsub
404 path s
404 path s
405 source s
405 source s
406 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
406 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
407 $ cat .hgsubstate
407 $ cat .hgsubstate
408 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
408 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
409
409
410 local changed, remote removed, keep changed
410 local changed, remote removed, keep changed
411
411
412 $ hg co -C 6
412 $ hg co -C 6
413 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
413 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
414 $ hg merge 11
414 $ hg merge 11
415 local [working copy] changed subrepository t which remote [merge rev] removed
415 local [working copy] changed subrepository t which remote [merge rev] removed
416 use (c)hanged version or (d)elete? c
416 use (c)hanged version or (d)elete? c
417 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
417 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
418 (branch merge, don't forget to commit)
418 (branch merge, don't forget to commit)
419 BROKEN: should include subrepo t
419 BROKEN: should include subrepo t
420 $ hg debugsub
420 $ hg debugsub
421 path s
421 path s
422 source s
422 source s
423 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
423 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
424 BROKEN: should include subrepo t
424 BROKEN: should include subrepo t
425 $ cat .hgsubstate
425 $ cat .hgsubstate
426 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
426 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
427 $ hg ci -m 'local changed, remote removed, keep changed'
427 $ hg ci -m 'local changed, remote removed, keep changed'
428 created new head
428 created new head
429 BROKEN: should include subrepo t
429 BROKEN: should include subrepo t
430 $ hg debugsub
430 $ hg debugsub
431 path s
431 path s
432 source s
432 source s
433 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
433 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
434 BROKEN: should include subrepo t
434 BROKEN: should include subrepo t
435 $ cat .hgsubstate
435 $ cat .hgsubstate
436 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
436 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
437 $ cat t/t
437 $ cat t/t
438 t2
438 t2
439
439
440 local changed, remote removed, keep removed
440 local changed, remote removed, keep removed
441
441
442 $ hg co -C 6
442 $ hg co -C 6
443 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
443 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
444 $ hg merge --config ui.interactive=true 11 <<EOF
444 $ hg merge --config ui.interactive=true 11 <<EOF
445 > d
445 > d
446 > EOF
446 > EOF
447 local [working copy] changed subrepository t which remote [merge rev] removed
447 local [working copy] changed subrepository t which remote [merge rev] removed
448 use (c)hanged version or (d)elete? d
448 use (c)hanged version or (d)elete? d
449 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
449 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
450 (branch merge, don't forget to commit)
450 (branch merge, don't forget to commit)
451 $ hg debugsub
451 $ hg debugsub
452 path s
452 path s
453 source s
453 source s
454 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
454 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
455 $ cat .hgsubstate
455 $ cat .hgsubstate
456 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
456 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
457 $ hg ci -m 'local changed, remote removed, keep removed'
457 $ hg ci -m 'local changed, remote removed, keep removed'
458 created new head
458 created new head
459 $ hg debugsub
459 $ hg debugsub
460 path s
460 path s
461 source s
461 source s
462 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
462 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
463 $ cat .hgsubstate
463 $ cat .hgsubstate
464 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
464 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
465
465
466 clean up to avoid having to fix up the tests below
466 clean up to avoid having to fix up the tests below
467
467
468 $ hg co -C 10
468 $ hg co -C 10
469 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
469 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
470 $ cat >> $HGRCPATH <<EOF
470 $ cat >> $HGRCPATH <<EOF
471 > [extensions]
471 > [extensions]
472 > strip=
472 > strip=
473 > EOF
473 > EOF
474 $ hg strip -r 11:15
474 $ hg strip -r 11:15
475 saved backup bundle to $TESTTMP/t/.hg/strip-backup/*-backup.hg (glob)
475 saved backup bundle to $TESTTMP/t/.hg/strip-backup/*-backup.hg (glob)
476
476
477 clone
477 clone
478
478
479 $ cd ..
479 $ cd ..
480 $ hg clone t tc
480 $ hg clone t tc
481 updating to branch default
481 updating to branch default
482 cloning subrepo s from $TESTTMP/t/s
482 cloning subrepo s from $TESTTMP/t/s
483 cloning subrepo s/ss from $TESTTMP/t/s/ss
483 cloning subrepo s/ss from $TESTTMP/t/s/ss
484 cloning subrepo t from $TESTTMP/t/t
484 cloning subrepo t from $TESTTMP/t/t
485 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
485 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
486 $ cd tc
486 $ cd tc
487 $ hg debugsub
487 $ hg debugsub
488 path s
488 path s
489 source s
489 source s
490 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
490 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
491 path t
491 path t
492 source t
492 source t
493 revision 20a0db6fbf6c3d2836e6519a642ae929bfc67c0e
493 revision 20a0db6fbf6c3d2836e6519a642ae929bfc67c0e
494 $ cd ..
494 $ cd ..
495
495
496 clone with subrepo disabled (update should fail)
496 clone with subrepo disabled (update should fail)
497
497
498 $ hg clone t -U tc2 --config subrepos.allowed=false
498 $ hg clone t -U tc2 --config subrepos.allowed=false
499 $ hg update -R tc2 --config subrepos.allowed=false
499 $ hg update -R tc2 --config subrepos.allowed=false
500 abort: subrepos not enabled
500 abort: subrepos not enabled
501 (see 'hg help config.subrepos' for details)
501 (see 'hg help config.subrepos' for details)
502 [255]
502 [255]
503 $ ls tc2
503 $ ls tc2
504 a
504 a
505
505
506 $ hg clone t tc3 --config subrepos.allowed=false
506 $ hg clone t tc3 --config subrepos.allowed=false
507 updating to branch default
507 updating to branch default
508 abort: subrepos not enabled
508 abort: subrepos not enabled
509 (see 'hg help config.subrepos' for details)
509 (see 'hg help config.subrepos' for details)
510 [255]
510 [255]
511 $ ls tc3
511 $ ls tc3
512 a
512 a
513
513
514 And again with just the hg type disabled
514 And again with just the hg type disabled
515
515
516 $ hg clone t -U tc4 --config subrepos.hg:allowed=false
516 $ hg clone t -U tc4 --config subrepos.hg:allowed=false
517 $ hg update -R tc4 --config subrepos.hg:allowed=false
517 $ hg update -R tc4 --config subrepos.hg:allowed=false
518 abort: hg subrepos not allowed
518 abort: hg subrepos not allowed
519 (see 'hg help config.subrepos' for details)
519 (see 'hg help config.subrepos' for details)
520 [255]
520 [255]
521 $ ls tc4
521 $ ls tc4
522 a
522 a
523
523
524 $ hg clone t tc5 --config subrepos.hg:allowed=false
524 $ hg clone t tc5 --config subrepos.hg:allowed=false
525 updating to branch default
525 updating to branch default
526 abort: hg subrepos not allowed
526 abort: hg subrepos not allowed
527 (see 'hg help config.subrepos' for details)
527 (see 'hg help config.subrepos' for details)
528 [255]
528 [255]
529 $ ls tc5
529 $ ls tc5
530 a
530 a
531
531
532 push
532 push
533
533
534 $ cd tc
534 $ cd tc
535 $ echo bah > t/t
535 $ echo bah > t/t
536 $ hg ci -m11
536 $ hg ci -m11
537 committing subrepository t
537 committing subrepository t
538 $ hg push
538 $ hg push
539 pushing to $TESTTMP/t
539 pushing to $TESTTMP/t
540 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss
540 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss
541 no changes made to subrepo s since last push to $TESTTMP/t/s
541 no changes made to subrepo s since last push to $TESTTMP/t/s
542 pushing subrepo t to $TESTTMP/t/t
542 pushing subrepo t to $TESTTMP/t/t
543 searching for changes
543 searching for changes
544 adding changesets
544 adding changesets
545 adding manifests
545 adding manifests
546 adding file changes
546 adding file changes
547 added 1 changesets with 1 changes to 1 files
547 added 1 changesets with 1 changes to 1 files
548 searching for changes
548 searching for changes
549 adding changesets
549 adding changesets
550 adding manifests
550 adding manifests
551 adding file changes
551 adding file changes
552 added 1 changesets with 1 changes to 1 files
552 added 1 changesets with 1 changes to 1 files
553
553
554 push -f
554 push -f
555
555
556 $ echo bah > s/a
556 $ echo bah > s/a
557 $ hg ci -m12
557 $ hg ci -m12
558 committing subrepository s
558 committing subrepository s
559 $ hg push
559 $ hg push
560 pushing to $TESTTMP/t
560 pushing to $TESTTMP/t
561 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss
561 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss
562 pushing subrepo s to $TESTTMP/t/s
562 pushing subrepo s to $TESTTMP/t/s
563 searching for changes
563 searching for changes
564 abort: push creates new remote head 12a213df6fa9! (in subrepository "s")
564 abort: push creates new remote head 12a213df6fa9! (in subrepository "s")
565 (merge or see 'hg help push' for details about pushing new heads)
565 (merge or see 'hg help push' for details about pushing new heads)
566 [255]
566 [255]
567 $ hg push -f
567 $ hg push -f
568 pushing to $TESTTMP/t
568 pushing to $TESTTMP/t
569 pushing subrepo s/ss to $TESTTMP/t/s/ss
569 pushing subrepo s/ss to $TESTTMP/t/s/ss
570 searching for changes
570 searching for changes
571 no changes found
571 no changes found
572 pushing subrepo s to $TESTTMP/t/s
572 pushing subrepo s to $TESTTMP/t/s
573 searching for changes
573 searching for changes
574 adding changesets
574 adding changesets
575 adding manifests
575 adding manifests
576 adding file changes
576 adding file changes
577 added 1 changesets with 1 changes to 1 files (+1 heads)
577 added 1 changesets with 1 changes to 1 files (+1 heads)
578 pushing subrepo t to $TESTTMP/t/t
578 pushing subrepo t to $TESTTMP/t/t
579 searching for changes
579 searching for changes
580 no changes found
580 no changes found
581 searching for changes
581 searching for changes
582 adding changesets
582 adding changesets
583 adding manifests
583 adding manifests
584 adding file changes
584 adding file changes
585 added 1 changesets with 1 changes to 1 files
585 added 1 changesets with 1 changes to 1 files
586
586
587 check that unmodified subrepos are not pushed
587 check that unmodified subrepos are not pushed
588
588
589 $ hg clone . ../tcc
589 $ hg clone . ../tcc
590 updating to branch default
590 updating to branch default
591 cloning subrepo s from $TESTTMP/tc/s
591 cloning subrepo s from $TESTTMP/tc/s
592 cloning subrepo s/ss from $TESTTMP/tc/s/ss
592 cloning subrepo s/ss from $TESTTMP/tc/s/ss
593 cloning subrepo t from $TESTTMP/tc/t
593 cloning subrepo t from $TESTTMP/tc/t
594 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
594 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
595
595
596 the subrepos on the new clone have nothing to push to its source
596 the subrepos on the new clone have nothing to push to its source
597
597
598 $ hg push -R ../tcc .
598 $ hg push -R ../tcc .
599 pushing to .
599 pushing to .
600 no changes made to subrepo s/ss since last push to s/ss
600 no changes made to subrepo s/ss since last push to s/ss
601 no changes made to subrepo s since last push to s
601 no changes made to subrepo s since last push to s
602 no changes made to subrepo t since last push to t
602 no changes made to subrepo t since last push to t
603 searching for changes
603 searching for changes
604 no changes found
604 no changes found
605 [1]
605 [1]
606
606
607 the subrepos on the source do not have a clean store versus the clone target
607 the subrepos on the source do not have a clean store versus the clone target
608 because they were never explicitly pushed to the source
608 because they were never explicitly pushed to the source
609
609
610 $ hg push ../tcc
610 $ hg push ../tcc
611 pushing to ../tcc
611 pushing to ../tcc
612 pushing subrepo s/ss to ../tcc/s/ss
612 pushing subrepo s/ss to ../tcc/s/ss
613 searching for changes
613 searching for changes
614 no changes found
614 no changes found
615 pushing subrepo s to ../tcc/s
615 pushing subrepo s to ../tcc/s
616 searching for changes
616 searching for changes
617 no changes found
617 no changes found
618 pushing subrepo t to ../tcc/t
618 pushing subrepo t to ../tcc/t
619 searching for changes
619 searching for changes
620 no changes found
620 no changes found
621 searching for changes
621 searching for changes
622 no changes found
622 no changes found
623 [1]
623 [1]
624
624
625 after push their stores become clean
625 after push their stores become clean
626
626
627 $ hg push ../tcc
627 $ hg push ../tcc
628 pushing to ../tcc
628 pushing to ../tcc
629 no changes made to subrepo s/ss since last push to ../tcc/s/ss
629 no changes made to subrepo s/ss since last push to ../tcc/s/ss
630 no changes made to subrepo s since last push to ../tcc/s
630 no changes made to subrepo s since last push to ../tcc/s
631 no changes made to subrepo t since last push to ../tcc/t
631 no changes made to subrepo t since last push to ../tcc/t
632 searching for changes
632 searching for changes
633 no changes found
633 no changes found
634 [1]
634 [1]
635
635
636 updating a subrepo to a different revision or changing
636 updating a subrepo to a different revision or changing
637 its working directory does not make its store dirty
637 its working directory does not make its store dirty
638
638
639 $ hg -R s update '.^'
639 $ hg -R s update '.^'
640 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
640 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
641 $ hg push
641 $ hg push
642 pushing to $TESTTMP/t
642 pushing to $TESTTMP/t
643 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss
643 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss
644 no changes made to subrepo s since last push to $TESTTMP/t/s
644 no changes made to subrepo s since last push to $TESTTMP/t/s
645 no changes made to subrepo t since last push to $TESTTMP/t/t
645 no changes made to subrepo t since last push to $TESTTMP/t/t
646 searching for changes
646 searching for changes
647 no changes found
647 no changes found
648 [1]
648 [1]
649 $ echo foo >> s/a
649 $ echo foo >> s/a
650 $ hg push
650 $ hg push
651 pushing to $TESTTMP/t
651 pushing to $TESTTMP/t
652 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss
652 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss
653 no changes made to subrepo s since last push to $TESTTMP/t/s
653 no changes made to subrepo s since last push to $TESTTMP/t/s
654 no changes made to subrepo t since last push to $TESTTMP/t/t
654 no changes made to subrepo t since last push to $TESTTMP/t/t
655 searching for changes
655 searching for changes
656 no changes found
656 no changes found
657 [1]
657 [1]
658 $ hg -R s update -C tip
658 $ hg -R s update -C tip
659 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
659 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
660
660
661 committing into a subrepo makes its store (but not its parent's store) dirty
661 committing into a subrepo makes its store (but not its parent's store) dirty
662
662
663 $ echo foo >> s/ss/a
663 $ echo foo >> s/ss/a
664 $ hg -R s/ss commit -m 'test dirty store detection'
664 $ hg -R s/ss commit -m 'test dirty store detection'
665
665
666 $ hg out -S -r `hg log -r tip -T "{node|short}"`
666 $ hg out -S -r `hg log -r tip -T "{node|short}"`
667 comparing with $TESTTMP/t
667 comparing with $TESTTMP/t
668 searching for changes
668 searching for changes
669 no changes found
669 no changes found
670 comparing with $TESTTMP/t/s
670 comparing with $TESTTMP/t/s
671 searching for changes
671 searching for changes
672 no changes found
672 no changes found
673 comparing with $TESTTMP/t/s/ss
673 comparing with $TESTTMP/t/s/ss
674 searching for changes
674 searching for changes
675 changeset: 1:79ea5566a333
675 changeset: 1:79ea5566a333
676 tag: tip
676 tag: tip
677 user: test
677 user: test
678 date: Thu Jan 01 00:00:00 1970 +0000
678 date: Thu Jan 01 00:00:00 1970 +0000
679 summary: test dirty store detection
679 summary: test dirty store detection
680
680
681 comparing with $TESTTMP/t/t
681 comparing with $TESTTMP/t/t
682 searching for changes
682 searching for changes
683 no changes found
683 no changes found
684
684
685 $ hg push
685 $ hg push
686 pushing to $TESTTMP/t
686 pushing to $TESTTMP/t
687 pushing subrepo s/ss to $TESTTMP/t/s/ss
687 pushing subrepo s/ss to $TESTTMP/t/s/ss
688 searching for changes
688 searching for changes
689 adding changesets
689 adding changesets
690 adding manifests
690 adding manifests
691 adding file changes
691 adding file changes
692 added 1 changesets with 1 changes to 1 files
692 added 1 changesets with 1 changes to 1 files
693 no changes made to subrepo s since last push to $TESTTMP/t/s
693 no changes made to subrepo s since last push to $TESTTMP/t/s
694 no changes made to subrepo t since last push to $TESTTMP/t/t
694 no changes made to subrepo t since last push to $TESTTMP/t/t
695 searching for changes
695 searching for changes
696 no changes found
696 no changes found
697 [1]
697 [1]
698
698
699 a subrepo store may be clean versus one repo but not versus another
699 a subrepo store may be clean versus one repo but not versus another
700
700
701 $ hg push
701 $ hg push
702 pushing to $TESTTMP/t
702 pushing to $TESTTMP/t
703 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss
703 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss
704 no changes made to subrepo s since last push to $TESTTMP/t/s
704 no changes made to subrepo s since last push to $TESTTMP/t/s
705 no changes made to subrepo t since last push to $TESTTMP/t/t
705 no changes made to subrepo t since last push to $TESTTMP/t/t
706 searching for changes
706 searching for changes
707 no changes found
707 no changes found
708 [1]
708 [1]
709 $ hg push ../tcc
709 $ hg push ../tcc
710 pushing to ../tcc
710 pushing to ../tcc
711 pushing subrepo s/ss to ../tcc/s/ss
711 pushing subrepo s/ss to ../tcc/s/ss
712 searching for changes
712 searching for changes
713 adding changesets
713 adding changesets
714 adding manifests
714 adding manifests
715 adding file changes
715 adding file changes
716 added 1 changesets with 1 changes to 1 files
716 added 1 changesets with 1 changes to 1 files
717 no changes made to subrepo s since last push to ../tcc/s
717 no changes made to subrepo s since last push to ../tcc/s
718 no changes made to subrepo t since last push to ../tcc/t
718 no changes made to subrepo t since last push to ../tcc/t
719 searching for changes
719 searching for changes
720 no changes found
720 no changes found
721 [1]
721 [1]
722
722
723 update
723 update
724
724
725 $ cd ../t
725 $ cd ../t
726 $ hg up -C # discard our earlier merge
726 $ hg up -C # discard our earlier merge
727 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
727 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
728 updated to "c373c8102e68: 12"
728 updated to "c373c8102e68: 12"
729 2 other heads for branch "default"
729 2 other heads for branch "default"
730 $ echo blah > t/t
730 $ echo blah > t/t
731 $ hg ci -m13
731 $ hg ci -m13
732 committing subrepository t
732 committing subrepository t
733
733
734 backout calls revert internally with minimal opts, which should not raise
734 backout calls revert internally with minimal opts, which should not raise
735 KeyError
735 KeyError
736
736
737 $ hg backout ".^" --no-commit
737 $ hg backout ".^" --no-commit
738 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
738 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
739 changeset c373c8102e68 backed out, don't forget to commit.
739 changeset c373c8102e68 backed out, don't forget to commit.
740
740
741 $ hg up -C # discard changes
741 $ hg up -C # discard changes
742 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
742 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
743 updated to "925c17564ef8: 13"
743 updated to "925c17564ef8: 13"
744 2 other heads for branch "default"
744 2 other heads for branch "default"
745
745
746 pull
746 pull
747
747
748 $ cd ../tc
748 $ cd ../tc
749 $ hg pull
749 $ hg pull
750 pulling from $TESTTMP/t
750 pulling from $TESTTMP/t
751 searching for changes
751 searching for changes
752 adding changesets
752 adding changesets
753 adding manifests
753 adding manifests
754 adding file changes
754 adding file changes
755 added 1 changesets with 1 changes to 1 files
755 added 1 changesets with 1 changes to 1 files
756 new changesets 925c17564ef8
756 new changesets 925c17564ef8
757 (run 'hg update' to get a working copy)
757 (run 'hg update' to get a working copy)
758
758
759 should pull t
759 should pull t
760
760
761 $ hg incoming -S -r `hg log -r tip -T "{node|short}"`
761 $ hg incoming -S -r `hg log -r tip -T "{node|short}"`
762 comparing with $TESTTMP/t
762 comparing with $TESTTMP/t
763 no changes found
763 no changes found
764 comparing with $TESTTMP/t/s
764 comparing with $TESTTMP/t/s
765 searching for changes
765 searching for changes
766 no changes found
766 no changes found
767 comparing with $TESTTMP/t/s/ss
767 comparing with $TESTTMP/t/s/ss
768 searching for changes
768 searching for changes
769 no changes found
769 no changes found
770 comparing with $TESTTMP/t/t
770 comparing with $TESTTMP/t/t
771 searching for changes
771 searching for changes
772 changeset: 5:52c0adc0515a
772 changeset: 5:52c0adc0515a
773 tag: tip
773 tag: tip
774 user: test
774 user: test
775 date: Thu Jan 01 00:00:00 1970 +0000
775 date: Thu Jan 01 00:00:00 1970 +0000
776 summary: 13
776 summary: 13
777
777
778
778
779 $ hg up
779 $ hg up
780 pulling subrepo t from $TESTTMP/t/t
780 pulling subrepo t from $TESTTMP/t/t
781 searching for changes
781 searching for changes
782 adding changesets
782 adding changesets
783 adding manifests
783 adding manifests
784 adding file changes
784 adding file changes
785 added 1 changesets with 1 changes to 1 files
785 added 1 changesets with 1 changes to 1 files
786 new changesets 52c0adc0515a
786 new changesets 52c0adc0515a
787 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
787 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
788 updated to "925c17564ef8: 13"
788 updated to "925c17564ef8: 13"
789 2 other heads for branch "default"
789 2 other heads for branch "default"
790 $ cat t/t
790 $ cat t/t
791 blah
791 blah
792
792
793 bogus subrepo path aborts
793 bogus subrepo path aborts
794
794
795 $ echo 'bogus=[boguspath' >> .hgsub
795 $ echo 'bogus=[boguspath' >> .hgsub
796 $ hg ci -m 'bogus subrepo path'
796 $ hg ci -m 'bogus subrepo path'
797 abort: missing ] in subrepository source
797 abort: missing ] in subrepository source
798 [255]
798 [255]
799
799
800 Issue1986: merge aborts when trying to merge a subrepo that
800 Issue1986: merge aborts when trying to merge a subrepo that
801 shouldn't need merging
801 shouldn't need merging
802
802
803 # subrepo layout
803 # subrepo layout
804 #
804 #
805 # o 5 br
805 # o 5 br
806 # /|
806 # /|
807 # o | 4 default
807 # o | 4 default
808 # | |
808 # | |
809 # | o 3 br
809 # | o 3 br
810 # |/|
810 # |/|
811 # o | 2 default
811 # o | 2 default
812 # | |
812 # | |
813 # | o 1 br
813 # | o 1 br
814 # |/
814 # |/
815 # o 0 default
815 # o 0 default
816
816
817 $ cd ..
817 $ cd ..
818 $ rm -rf sub
818 $ rm -rf sub
819 $ hg init main
819 $ hg init main
820 $ cd main
820 $ cd main
821 $ hg init s
821 $ hg init s
822 $ cd s
822 $ cd s
823 $ echo a > a
823 $ echo a > a
824 $ hg ci -Am1
824 $ hg ci -Am1
825 adding a
825 adding a
826 $ hg branch br
826 $ hg branch br
827 marked working directory as branch br
827 marked working directory as branch br
828 (branches are permanent and global, did you want a bookmark?)
828 (branches are permanent and global, did you want a bookmark?)
829 $ echo a >> a
829 $ echo a >> a
830 $ hg ci -m1
830 $ hg ci -m1
831 $ hg up default
831 $ hg up default
832 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
832 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
833 $ echo b > b
833 $ echo b > b
834 $ hg ci -Am1
834 $ hg ci -Am1
835 adding b
835 adding b
836 $ hg up br
836 $ hg up br
837 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
837 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
838 $ hg merge tip
838 $ hg merge tip
839 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
839 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
840 (branch merge, don't forget to commit)
840 (branch merge, don't forget to commit)
841 $ hg ci -m1
841 $ hg ci -m1
842 $ hg up 2
842 $ hg up 2
843 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
843 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
844 $ echo c > c
844 $ echo c > c
845 $ hg ci -Am1
845 $ hg ci -Am1
846 adding c
846 adding c
847 $ hg up 3
847 $ hg up 3
848 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
848 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
849 $ hg merge 4
849 $ hg merge 4
850 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
850 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
851 (branch merge, don't forget to commit)
851 (branch merge, don't forget to commit)
852 $ hg ci -m1
852 $ hg ci -m1
853
853
854 # main repo layout:
854 # main repo layout:
855 #
855 #
856 # * <-- try to merge default into br again
856 # * <-- try to merge default into br again
857 # .`|
857 # .`|
858 # . o 5 br --> substate = 5
858 # . o 5 br --> substate = 5
859 # . |
859 # . |
860 # o | 4 default --> substate = 4
860 # o | 4 default --> substate = 4
861 # | |
861 # | |
862 # | o 3 br --> substate = 2
862 # | o 3 br --> substate = 2
863 # |/|
863 # |/|
864 # o | 2 default --> substate = 2
864 # o | 2 default --> substate = 2
865 # | |
865 # | |
866 # | o 1 br --> substate = 3
866 # | o 1 br --> substate = 3
867 # |/
867 # |/
868 # o 0 default --> substate = 2
868 # o 0 default --> substate = 2
869
869
870 $ cd ..
870 $ cd ..
871 $ echo 's = s' > .hgsub
871 $ echo 's = s' > .hgsub
872 $ hg -R s up 2
872 $ hg -R s up 2
873 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
873 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
874 $ hg ci -Am1
874 $ hg ci -Am1
875 adding .hgsub
875 adding .hgsub
876 $ hg branch br
876 $ hg branch br
877 marked working directory as branch br
877 marked working directory as branch br
878 (branches are permanent and global, did you want a bookmark?)
878 (branches are permanent and global, did you want a bookmark?)
879 $ echo b > b
879 $ echo b > b
880 $ hg -R s up 3
880 $ hg -R s up 3
881 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
881 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
882 $ hg ci -Am1
882 $ hg ci -Am1
883 adding b
883 adding b
884 $ hg up default
884 $ hg up default
885 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
885 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
886 $ echo c > c
886 $ echo c > c
887 $ hg ci -Am1
887 $ hg ci -Am1
888 adding c
888 adding c
889 $ hg up 1
889 $ hg up 1
890 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
890 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
891 $ hg merge 2
891 $ hg merge 2
892 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
892 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
893 (branch merge, don't forget to commit)
893 (branch merge, don't forget to commit)
894 $ hg ci -m1
894 $ hg ci -m1
895 $ hg up 2
895 $ hg up 2
896 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
896 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
897 $ hg -R s up 4
897 $ hg -R s up 4
898 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
898 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
899 $ echo d > d
899 $ echo d > d
900 $ hg ci -Am1
900 $ hg ci -Am1
901 adding d
901 adding d
902 $ hg up 3
902 $ hg up 3
903 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
903 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
904 $ hg -R s up 5
904 $ hg -R s up 5
905 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
905 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
906 $ echo e > e
906 $ echo e > e
907 $ hg ci -Am1
907 $ hg ci -Am1
908 adding e
908 adding e
909
909
910 $ hg up 5
910 $ hg up 5
911 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
911 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
912 $ hg merge 4 # try to merge default into br again
912 $ hg merge 4 # try to merge default into br again
913 subrepository s diverged (local revision: f8f13b33206e, remote revision: a3f9062a4f88)
913 subrepository s diverged (local revision: f8f13b33206e, remote revision: a3f9062a4f88)
914 (M)erge, keep (l)ocal [working copy] or keep (r)emote [merge rev]? m
914 (M)erge, keep (l)ocal [working copy] or keep (r)emote [merge rev]? m
915 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
915 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
916 (branch merge, don't forget to commit)
916 (branch merge, don't forget to commit)
917 $ cd ..
917 $ cd ..
918
918
919 test subrepo delete from .hgsubstate
919 test subrepo delete from .hgsubstate
920
920
921 $ hg init testdelete
921 $ hg init testdelete
922 $ mkdir testdelete/nested testdelete/nested2
922 $ mkdir testdelete/nested testdelete/nested2
923 $ hg init testdelete/nested
923 $ hg init testdelete/nested
924 $ hg init testdelete/nested2
924 $ hg init testdelete/nested2
925 $ echo test > testdelete/nested/foo
925 $ echo test > testdelete/nested/foo
926 $ echo test > testdelete/nested2/foo
926 $ echo test > testdelete/nested2/foo
927 $ hg -R testdelete/nested add
927 $ hg -R testdelete/nested add
928 adding testdelete/nested/foo
928 adding testdelete/nested/foo
929 $ hg -R testdelete/nested2 add
929 $ hg -R testdelete/nested2 add
930 adding testdelete/nested2/foo
930 adding testdelete/nested2/foo
931 $ hg -R testdelete/nested ci -m test
931 $ hg -R testdelete/nested ci -m test
932 $ hg -R testdelete/nested2 ci -m test
932 $ hg -R testdelete/nested2 ci -m test
933 $ echo nested = nested > testdelete/.hgsub
933 $ echo nested = nested > testdelete/.hgsub
934 $ echo nested2 = nested2 >> testdelete/.hgsub
934 $ echo nested2 = nested2 >> testdelete/.hgsub
935 $ hg -R testdelete add
935 $ hg -R testdelete add
936 adding testdelete/.hgsub
936 adding testdelete/.hgsub
937 $ hg -R testdelete ci -m "nested 1 & 2 added"
937 $ hg -R testdelete ci -m "nested 1 & 2 added"
938 $ echo nested = nested > testdelete/.hgsub
938 $ echo nested = nested > testdelete/.hgsub
939 $ hg -R testdelete ci -m "nested 2 deleted"
939 $ hg -R testdelete ci -m "nested 2 deleted"
940 $ cat testdelete/.hgsubstate
940 $ cat testdelete/.hgsubstate
941 bdf5c9a3103743d900b12ae0db3ffdcfd7b0d878 nested
941 bdf5c9a3103743d900b12ae0db3ffdcfd7b0d878 nested
942 $ hg -R testdelete remove testdelete/.hgsub
942 $ hg -R testdelete remove testdelete/.hgsub
943 $ hg -R testdelete ci -m ".hgsub deleted"
943 $ hg -R testdelete ci -m ".hgsub deleted"
944 $ cat testdelete/.hgsubstate
944 $ cat testdelete/.hgsubstate
945 bdf5c9a3103743d900b12ae0db3ffdcfd7b0d878 nested
945 bdf5c9a3103743d900b12ae0db3ffdcfd7b0d878 nested
946
946
947 test repository cloning
947 test repository cloning
948
948
949 $ mkdir mercurial mercurial2
949 $ mkdir mercurial mercurial2
950 $ hg init nested_absolute
950 $ hg init nested_absolute
951 $ echo test > nested_absolute/foo
951 $ echo test > nested_absolute/foo
952 $ hg -R nested_absolute add
952 $ hg -R nested_absolute add
953 adding nested_absolute/foo
953 adding nested_absolute/foo
954 $ hg -R nested_absolute ci -mtest
954 $ hg -R nested_absolute ci -mtest
955 $ cd mercurial
955 $ cd mercurial
956 $ hg init nested_relative
956 $ hg init nested_relative
957 $ echo test2 > nested_relative/foo2
957 $ echo test2 > nested_relative/foo2
958 $ hg -R nested_relative add
958 $ hg -R nested_relative add
959 adding nested_relative/foo2
959 adding nested_relative/foo2
960 $ hg -R nested_relative ci -mtest2
960 $ hg -R nested_relative ci -mtest2
961 $ hg init main
961 $ hg init main
962 $ echo "nested_relative = ../nested_relative" > main/.hgsub
962 $ echo "nested_relative = ../nested_relative" > main/.hgsub
963 $ echo "nested_absolute = `pwd`/nested_absolute" >> main/.hgsub
963 $ echo "nested_absolute = `pwd`/nested_absolute" >> main/.hgsub
964 $ hg -R main add
964 $ hg -R main add
965 adding main/.hgsub
965 adding main/.hgsub
966 $ hg -R main ci -m "add subrepos"
966 $ hg -R main ci -m "add subrepos"
967 $ cd ..
967 $ cd ..
968 $ hg clone mercurial/main mercurial2/main
968 $ hg clone mercurial/main mercurial2/main
969 updating to branch default
969 updating to branch default
970 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
970 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
971 $ cat mercurial2/main/nested_absolute/.hg/hgrc \
971 $ cat mercurial2/main/nested_absolute/.hg/hgrc \
972 > mercurial2/main/nested_relative/.hg/hgrc
972 > mercurial2/main/nested_relative/.hg/hgrc
973 [paths]
973 [paths]
974 default = $TESTTMP/mercurial/nested_absolute
974 default = $TESTTMP/mercurial/nested_absolute
975 [paths]
975 [paths]
976 default = $TESTTMP/mercurial/nested_relative
976 default = $TESTTMP/mercurial/nested_relative
977 $ rm -rf mercurial mercurial2
977 $ rm -rf mercurial mercurial2
978
978
979 Issue1977: multirepo push should fail if subrepo push fails
979 Issue1977: multirepo push should fail if subrepo push fails
980
980
981 $ hg init repo
981 $ hg init repo
982 $ hg init repo/s
982 $ hg init repo/s
983 $ echo a > repo/s/a
983 $ echo a > repo/s/a
984 $ hg -R repo/s ci -Am0
984 $ hg -R repo/s ci -Am0
985 adding a
985 adding a
986 $ echo s = s > repo/.hgsub
986 $ echo s = s > repo/.hgsub
987 $ hg -R repo ci -Am1
987 $ hg -R repo ci -Am1
988 adding .hgsub
988 adding .hgsub
989 $ hg clone repo repo2
989 $ hg clone repo repo2
990 updating to branch default
990 updating to branch default
991 cloning subrepo s from $TESTTMP/repo/s
991 cloning subrepo s from $TESTTMP/repo/s
992 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
992 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
993 $ hg -q -R repo2 pull -u
993 $ hg -q -R repo2 pull -u
994 $ echo 1 > repo2/s/a
994 $ echo 1 > repo2/s/a
995 $ hg -R repo2/s ci -m2
995 $ hg -R repo2/s ci -m2
996 $ hg -q -R repo2/s push
996 $ hg -q -R repo2/s push
997 $ hg -R repo2/s up -C 0
997 $ hg -R repo2/s up -C 0
998 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
998 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
999 $ echo 2 > repo2/s/b
999 $ echo 2 > repo2/s/b
1000 $ hg -R repo2/s ci -m3 -A
1000 $ hg -R repo2/s ci -m3 -A
1001 adding b
1001 adding b
1002 created new head
1002 created new head
1003 $ hg -R repo2 ci -m3
1003 $ hg -R repo2 ci -m3
1004 $ hg -q -R repo2 push
1004 $ hg -q -R repo2 push
1005 abort: push creates new remote head cc505f09a8b2! (in subrepository "s")
1005 abort: push creates new remote head cc505f09a8b2! (in subrepository "s")
1006 (merge or see 'hg help push' for details about pushing new heads)
1006 (merge or see 'hg help push' for details about pushing new heads)
1007 [255]
1007 [255]
1008 $ hg -R repo update
1008 $ hg -R repo update
1009 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1009 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1010
1010
1011 test if untracked file is not overwritten
1011 test if untracked file is not overwritten
1012
1012
1013 (this also tests that updated .hgsubstate is treated as "modified",
1013 (this also tests that updated .hgsubstate is treated as "modified",
1014 when 'merge.update()' is aborted before 'merge.recordupdates()', even
1014 when 'merge.update()' is aborted before 'merge.recordupdates()', even
1015 if none of mode, size and timestamp of it isn't changed on the
1015 if none of mode, size and timestamp of it isn't changed on the
1016 filesystem (see also issue4583))
1016 filesystem (see also issue4583))
1017
1017
1018 $ echo issue3276_ok > repo/s/b
1018 $ echo issue3276_ok > repo/s/b
1019 $ hg -R repo2 push -f -q
1019 $ hg -R repo2 push -f -q
1020 $ touch -t 200001010000 repo/.hgsubstate
1020 $ touch -t 200001010000 repo/.hgsubstate
1021
1021
1022 $ cat >> repo/.hg/hgrc <<EOF
1022 $ cat >> repo/.hg/hgrc <<EOF
1023 > [fakedirstatewritetime]
1023 > [fakedirstatewritetime]
1024 > # emulate invoking dirstate.write() via repo.status()
1024 > # emulate invoking dirstate.write() via repo.status()
1025 > # at 2000-01-01 00:00
1025 > # at 2000-01-01 00:00
1026 > fakenow = 200001010000
1026 > fakenow = 200001010000
1027 >
1027 >
1028 > [extensions]
1028 > [extensions]
1029 > fakedirstatewritetime = $TESTDIR/fakedirstatewritetime.py
1029 > fakedirstatewritetime = $TESTDIR/fakedirstatewritetime.py
1030 > EOF
1030 > EOF
1031 $ hg -R repo update
1031 $ hg -R repo update
1032 b: untracked file differs
1032 b: untracked file differs
1033 abort: untracked files in working directory differ from files in requested revision (in subrepository "s")
1033 abort: untracked files in working directory differ from files in requested revision (in subrepository "s")
1034 [255]
1034 [255]
1035 $ cat >> repo/.hg/hgrc <<EOF
1035 $ cat >> repo/.hg/hgrc <<EOF
1036 > [extensions]
1036 > [extensions]
1037 > fakedirstatewritetime = !
1037 > fakedirstatewritetime = !
1038 > EOF
1038 > EOF
1039
1039
1040 $ cat repo/s/b
1040 $ cat repo/s/b
1041 issue3276_ok
1041 issue3276_ok
1042 $ rm repo/s/b
1042 $ rm repo/s/b
1043 $ touch -t 200001010000 repo/.hgsubstate
1043 $ touch -t 200001010000 repo/.hgsubstate
1044 $ hg -R repo revert --all
1044 $ hg -R repo revert --all
1045 reverting repo/.hgsubstate
1045 reverting repo/.hgsubstate
1046 reverting subrepo s
1046 reverting subrepo s
1047 $ hg -R repo update
1047 $ hg -R repo update
1048 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1048 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1049 $ cat repo/s/b
1049 $ cat repo/s/b
1050 2
1050 2
1051 $ rm -rf repo2 repo
1051 $ rm -rf repo2 repo
1052
1052
1053
1053
1054 Issue1852 subrepos with relative paths always push/pull relative to default
1054 Issue1852 subrepos with relative paths always push/pull relative to default
1055
1055
1056 Prepare a repo with subrepo
1056 Prepare a repo with subrepo
1057
1057
1058 $ hg init issue1852a
1058 $ hg init issue1852a
1059 $ cd issue1852a
1059 $ cd issue1852a
1060 $ hg init sub/repo
1060 $ hg init sub/repo
1061 $ echo test > sub/repo/foo
1061 $ echo test > sub/repo/foo
1062 $ hg -R sub/repo add sub/repo/foo
1062 $ hg -R sub/repo add sub/repo/foo
1063 $ echo sub/repo = sub/repo > .hgsub
1063 $ echo sub/repo = sub/repo > .hgsub
1064 $ hg add .hgsub
1064 $ hg add .hgsub
1065 $ hg ci -mtest
1065 $ hg ci -mtest
1066 committing subrepository sub/repo
1066 committing subrepository sub/repo
1067 $ echo test >> sub/repo/foo
1067 $ echo test >> sub/repo/foo
1068 $ hg ci -mtest
1068 $ hg ci -mtest
1069 committing subrepository sub/repo
1069 committing subrepository sub/repo
1070 $ hg cat sub/repo/foo
1070 $ hg cat sub/repo/foo
1071 test
1071 test
1072 test
1072 test
1073 $ hg cat sub/repo/foo -Tjson | sed 's|\\\\|/|g'
1073 $ hg cat sub/repo/foo -Tjson | sed 's|\\\\|/|g'
1074 [
1074 [
1075 {
1075 {
1076 "data": "test\ntest\n",
1076 "data": "test\ntest\n",
1077 "path": "foo"
1077 "path": "foo"
1078 }
1078 }
1079 ]
1079 ]
1080
1080
1081 non-exact match:
1081 non-exact match:
1082
1082
1083 $ hg cat -T '{path|relpath}\n' 'glob:**'
1083 $ hg cat -T '{path|relpath}\n' 'glob:**'
1084 .hgsub
1084 .hgsub
1085 .hgsubstate
1085 .hgsubstate
1086 sub/repo/foo
1086 sub/repo/foo
1087 $ hg cat -T '{path|relpath}\n' 're:^sub'
1087 $ hg cat -T '{path|relpath}\n' 're:^sub'
1088 sub/repo/foo
1088 sub/repo/foo
1089
1089
1090 missing subrepos in working directory:
1090 missing subrepos in working directory:
1091
1091
1092 $ mkdir -p tmp/sub/repo
1092 $ mkdir -p tmp/sub/repo
1093 $ hg cat -r 0 --output tmp/%p_p sub/repo/foo
1093 $ hg cat -r 0 --output tmp/%p_p sub/repo/foo
1094 $ cat tmp/sub/repo/foo_p
1094 $ cat tmp/sub/repo/foo_p
1095 test
1095 test
1096 $ mv sub/repo sub_
1096 $ mv sub/repo sub_
1097 $ hg cat sub/repo/baz
1097 $ hg cat sub/repo/baz
1098 skipping missing subrepository: sub/repo
1098 skipping missing subrepository: sub/repo
1099 [1]
1099 [1]
1100 $ rm -rf sub/repo
1100 $ rm -rf sub/repo
1101 $ mv sub_ sub/repo
1101 $ mv sub_ sub/repo
1102 $ cd ..
1102 $ cd ..
1103
1103
1104 Create repo without default path, pull top repo, and see what happens on update
1104 Create repo without default path, pull top repo, and see what happens on update
1105
1105
1106 $ hg init issue1852b
1106 $ hg init issue1852b
1107 $ hg -R issue1852b pull issue1852a
1107 $ hg -R issue1852b pull issue1852a
1108 pulling from issue1852a
1108 pulling from issue1852a
1109 requesting all changes
1109 requesting all changes
1110 adding changesets
1110 adding changesets
1111 adding manifests
1111 adding manifests
1112 adding file changes
1112 adding file changes
1113 added 2 changesets with 3 changes to 2 files
1113 added 2 changesets with 3 changes to 2 files
1114 new changesets 19487b456929:be5eb94e7215
1114 new changesets 19487b456929:be5eb94e7215
1115 (run 'hg update' to get a working copy)
1115 (run 'hg update' to get a working copy)
1116 $ hg -R issue1852b update
1116 $ hg -R issue1852b update
1117 abort: default path for subrepository not found (in subrepository "sub/repo")
1117 abort: default path for subrepository not found (in subrepository "sub/repo")
1118 [255]
1118 [255]
1119
1119
1120 Ensure a full traceback, not just the SubrepoAbort part
1120 Ensure a full traceback, not just the SubrepoAbort part
1121
1121
1122 $ hg -R issue1852b update --traceback 2>&1 | grep 'raise error\.Abort'
1122 $ hg -R issue1852b update --traceback 2>&1 | grep 'raise error\.Abort'
1123 raise error.Abort(_("default path for subrepository not found"))
1123 raise error.Abort(_("default path for subrepository not found"))
1124
1124
1125 Pull -u now doesn't help
1125 Pull -u now doesn't help
1126
1126
1127 $ hg -R issue1852b pull -u issue1852a
1127 $ hg -R issue1852b pull -u issue1852a
1128 pulling from issue1852a
1128 pulling from issue1852a
1129 searching for changes
1129 searching for changes
1130 no changes found
1130 no changes found
1131
1131
1132 Try the same, but with pull -u
1132 Try the same, but with pull -u
1133
1133
1134 $ hg init issue1852c
1134 $ hg init issue1852c
1135 $ hg -R issue1852c pull -r0 -u issue1852a
1135 $ hg -R issue1852c pull -r0 -u issue1852a
1136 pulling from issue1852a
1136 pulling from issue1852a
1137 adding changesets
1137 adding changesets
1138 adding manifests
1138 adding manifests
1139 adding file changes
1139 adding file changes
1140 added 1 changesets with 2 changes to 2 files
1140 added 1 changesets with 2 changes to 2 files
1141 new changesets 19487b456929
1141 new changesets 19487b456929
1142 cloning subrepo sub/repo from issue1852a/sub/repo
1142 cloning subrepo sub/repo from issue1852a/sub/repo
1143 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1143 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1144
1144
1145 Try to push from the other side
1145 Try to push from the other side
1146
1146
1147 $ hg -R issue1852a push `pwd`/issue1852c
1147 $ hg -R issue1852a push `pwd`/issue1852c
1148 pushing to $TESTTMP/issue1852c
1148 pushing to $TESTTMP/issue1852c
1149 pushing subrepo sub/repo to $TESTTMP/issue1852c/sub/repo
1149 pushing subrepo sub/repo to $TESTTMP/issue1852c/sub/repo
1150 searching for changes
1150 searching for changes
1151 no changes found
1151 no changes found
1152 searching for changes
1152 searching for changes
1153 adding changesets
1153 adding changesets
1154 adding manifests
1154 adding manifests
1155 adding file changes
1155 adding file changes
1156 added 1 changesets with 1 changes to 1 files
1156 added 1 changesets with 1 changes to 1 files
1157
1157
1158 Incoming and outgoing should not use the default path:
1158 Incoming and outgoing should not use the default path:
1159
1159
1160 $ hg clone -q issue1852a issue1852d
1160 $ hg clone -q issue1852a issue1852d
1161 $ hg -R issue1852d outgoing --subrepos issue1852c
1161 $ hg -R issue1852d outgoing --subrepos issue1852c
1162 comparing with issue1852c
1162 comparing with issue1852c
1163 searching for changes
1163 searching for changes
1164 no changes found
1164 no changes found
1165 comparing with issue1852c/sub/repo
1165 comparing with issue1852c/sub/repo
1166 searching for changes
1166 searching for changes
1167 no changes found
1167 no changes found
1168 [1]
1168 [1]
1169 $ hg -R issue1852d incoming --subrepos issue1852c
1169 $ hg -R issue1852d incoming --subrepos issue1852c
1170 comparing with issue1852c
1170 comparing with issue1852c
1171 searching for changes
1171 searching for changes
1172 no changes found
1172 no changes found
1173 comparing with issue1852c/sub/repo
1173 comparing with issue1852c/sub/repo
1174 searching for changes
1174 searching for changes
1175 no changes found
1175 no changes found
1176 [1]
1176 [1]
1177
1177
1178 Check that merge of a new subrepo doesn't write the uncommitted state to
1178 Check that merge of a new subrepo doesn't write the uncommitted state to
1179 .hgsubstate (issue4622)
1179 .hgsubstate (issue4622)
1180
1180
1181 $ hg init issue1852a/addedsub
1181 $ hg init issue1852a/addedsub
1182 $ echo zzz > issue1852a/addedsub/zz.txt
1182 $ echo zzz > issue1852a/addedsub/zz.txt
1183 $ hg -R issue1852a/addedsub ci -Aqm "initial ZZ"
1183 $ hg -R issue1852a/addedsub ci -Aqm "initial ZZ"
1184
1184
1185 $ hg clone issue1852a/addedsub issue1852d/addedsub
1185 $ hg clone issue1852a/addedsub issue1852d/addedsub
1186 updating to branch default
1186 updating to branch default
1187 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1187 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1188
1188
1189 $ echo def > issue1852a/sub/repo/foo
1189 $ echo def > issue1852a/sub/repo/foo
1190 $ hg -R issue1852a ci -SAm 'tweaked subrepo'
1190 $ hg -R issue1852a ci -SAm 'tweaked subrepo'
1191 adding tmp/sub/repo/foo_p
1191 adding tmp/sub/repo/foo_p
1192 committing subrepository sub/repo
1192 committing subrepository sub/repo
1193
1193
1194 $ echo 'addedsub = addedsub' >> issue1852d/.hgsub
1194 $ echo 'addedsub = addedsub' >> issue1852d/.hgsub
1195 $ echo xyz > issue1852d/sub/repo/foo
1195 $ echo xyz > issue1852d/sub/repo/foo
1196 $ hg -R issue1852d pull -u
1196 $ hg -R issue1852d pull -u
1197 pulling from $TESTTMP/issue1852a
1197 pulling from $TESTTMP/issue1852a
1198 searching for changes
1198 searching for changes
1199 adding changesets
1199 adding changesets
1200 adding manifests
1200 adding manifests
1201 adding file changes
1201 adding file changes
1202 added 1 changesets with 2 changes to 2 files
1202 added 1 changesets with 2 changes to 2 files
1203 new changesets c82b79fdcc5b
1203 new changesets c82b79fdcc5b
1204 subrepository sub/repo diverged (local revision: f42d5c7504a8, remote revision: 46cd4aac504c)
1204 subrepository sub/repo diverged (local revision: f42d5c7504a8, remote revision: 46cd4aac504c)
1205 (M)erge, keep (l)ocal [working copy] or keep (r)emote [destination]? m
1205 (M)erge, keep (l)ocal [working copy] or keep (r)emote [destination]? m
1206 pulling subrepo sub/repo from $TESTTMP/issue1852a/sub/repo
1206 pulling subrepo sub/repo from $TESTTMP/issue1852a/sub/repo
1207 searching for changes
1207 searching for changes
1208 adding changesets
1208 adding changesets
1209 adding manifests
1209 adding manifests
1210 adding file changes
1210 adding file changes
1211 added 1 changesets with 1 changes to 1 files
1211 added 1 changesets with 1 changes to 1 files
1212 new changesets 46cd4aac504c
1212 new changesets 46cd4aac504c
1213 subrepository sources for sub/repo differ
1213 subrepository sources for sub/repo differ
1214 use (l)ocal source (f42d5c7504a8) or (r)emote source (46cd4aac504c)? l
1214 use (l)ocal source (f42d5c7504a8) or (r)emote source (46cd4aac504c)? l
1215 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1215 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1216 $ cat issue1852d/.hgsubstate
1216 $ cat issue1852d/.hgsubstate
1217 f42d5c7504a811dda50f5cf3e5e16c3330b87172 sub/repo
1217 f42d5c7504a811dda50f5cf3e5e16c3330b87172 sub/repo
1218
1218
1219 Check status of files when none of them belong to the first
1219 Check status of files when none of them belong to the first
1220 subrepository:
1220 subrepository:
1221
1221
1222 $ hg init subrepo-status
1222 $ hg init subrepo-status
1223 $ cd subrepo-status
1223 $ cd subrepo-status
1224 $ hg init subrepo-1
1224 $ hg init subrepo-1
1225 $ hg init subrepo-2
1225 $ hg init subrepo-2
1226 $ cd subrepo-2
1226 $ cd subrepo-2
1227 $ touch file
1227 $ touch file
1228 $ hg add file
1228 $ hg add file
1229 $ cd ..
1229 $ cd ..
1230 $ echo subrepo-1 = subrepo-1 > .hgsub
1230 $ echo subrepo-1 = subrepo-1 > .hgsub
1231 $ echo subrepo-2 = subrepo-2 >> .hgsub
1231 $ echo subrepo-2 = subrepo-2 >> .hgsub
1232 $ hg add .hgsub
1232 $ hg add .hgsub
1233 $ hg ci -m 'Added subrepos'
1233 $ hg ci -m 'Added subrepos'
1234 committing subrepository subrepo-2
1234 committing subrepository subrepo-2
1235 $ hg st subrepo-2/file
1235 $ hg st subrepo-2/file
1236
1236
1237 Check that share works with subrepo
1237 Check that share works with subrepo
1238 $ hg --config extensions.share= share . ../shared
1238 $ hg --config extensions.share= share . ../shared
1239 updating working directory
1239 updating working directory
1240 sharing subrepo subrepo-1 from $TESTTMP/subrepo-status/subrepo-1
1240 sharing subrepo subrepo-1 from $TESTTMP/subrepo-status/subrepo-1
1241 sharing subrepo subrepo-2 from $TESTTMP/subrepo-status/subrepo-2
1241 sharing subrepo subrepo-2 from $TESTTMP/subrepo-status/subrepo-2
1242 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1242 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1243 $ find ../shared/* | sort
1243 $ find ../shared/* | sort
1244 ../shared/subrepo-1
1244 ../shared/subrepo-1
1245 ../shared/subrepo-1/.hg
1245 ../shared/subrepo-1/.hg
1246 ../shared/subrepo-1/.hg/cache
1246 ../shared/subrepo-1/.hg/cache
1247 ../shared/subrepo-1/.hg/cache/storehash
1247 ../shared/subrepo-1/.hg/cache/storehash
1248 ../shared/subrepo-1/.hg/cache/storehash/* (glob)
1248 ../shared/subrepo-1/.hg/cache/storehash/* (glob)
1249 ../shared/subrepo-1/.hg/hgrc
1249 ../shared/subrepo-1/.hg/hgrc
1250 ../shared/subrepo-1/.hg/requires
1250 ../shared/subrepo-1/.hg/requires
1251 ../shared/subrepo-1/.hg/sharedpath
1251 ../shared/subrepo-1/.hg/sharedpath
1252 ../shared/subrepo-1/.hg/wcache
1252 ../shared/subrepo-1/.hg/wcache
1253 ../shared/subrepo-2
1253 ../shared/subrepo-2
1254 ../shared/subrepo-2/.hg
1254 ../shared/subrepo-2/.hg
1255 ../shared/subrepo-2/.hg/branch
1255 ../shared/subrepo-2/.hg/branch
1256 ../shared/subrepo-2/.hg/cache
1256 ../shared/subrepo-2/.hg/cache
1257 ../shared/subrepo-2/.hg/cache/storehash
1257 ../shared/subrepo-2/.hg/cache/storehash
1258 ../shared/subrepo-2/.hg/cache/storehash/* (glob)
1258 ../shared/subrepo-2/.hg/cache/storehash/* (glob)
1259 ../shared/subrepo-2/.hg/dirstate
1259 ../shared/subrepo-2/.hg/dirstate
1260 ../shared/subrepo-2/.hg/hgrc
1260 ../shared/subrepo-2/.hg/hgrc
1261 ../shared/subrepo-2/.hg/requires
1261 ../shared/subrepo-2/.hg/requires
1262 ../shared/subrepo-2/.hg/sharedpath
1262 ../shared/subrepo-2/.hg/sharedpath
1263 ../shared/subrepo-2/.hg/wcache
1263 ../shared/subrepo-2/.hg/wcache
1264 ../shared/subrepo-2/.hg/wcache/checkisexec (execbit !)
1264 ../shared/subrepo-2/.hg/wcache/checkisexec (execbit !)
1265 ../shared/subrepo-2/.hg/wcache/checklink (symlink !)
1265 ../shared/subrepo-2/.hg/wcache/checklink (symlink !)
1266 ../shared/subrepo-2/.hg/wcache/checklink-target (symlink !)
1266 ../shared/subrepo-2/.hg/wcache/checklink-target (symlink !)
1267 ../shared/subrepo-2/.hg/wcache/manifestfulltextcache (reporevlogstore !)
1267 ../shared/subrepo-2/.hg/wcache/manifestfulltextcache (reporevlogstore !)
1268 ../shared/subrepo-2/file
1268 ../shared/subrepo-2/file
1269 $ hg -R ../shared in
1269 $ hg -R ../shared in
1270 abort: repository default not found!
1270 abort: repository default not found!
1271 [255]
1271 [255]
1272 $ hg -R ../shared/subrepo-2 showconfig paths
1272 $ hg -R ../shared/subrepo-2 showconfig paths
1273 paths.default=$TESTTMP/subrepo-status/subrepo-2
1273 paths.default=$TESTTMP/subrepo-status/subrepo-2
1274 $ hg -R ../shared/subrepo-1 sum --remote
1274 $ hg -R ../shared/subrepo-1 sum --remote
1275 parent: -1:000000000000 tip (empty repository)
1275 parent: -1:000000000000 tip (empty repository)
1276 branch: default
1276 branch: default
1277 commit: (clean)
1277 commit: (clean)
1278 update: (current)
1278 update: (current)
1279 remote: (synced)
1279 remote: (synced)
1280
1280
1281 Check hg update --clean
1281 Check hg update --clean
1282 $ cd $TESTTMP/t
1282 $ cd $TESTTMP/t
1283 $ rm -r t/t.orig
1283 $ rm -r t/t.orig
1284 $ hg status -S --all
1284 $ hg status -S --all
1285 C .hgsub
1285 C .hgsub
1286 C .hgsubstate
1286 C .hgsubstate
1287 C a
1287 C a
1288 C s/.hgsub
1288 C s/.hgsub
1289 C s/.hgsubstate
1289 C s/.hgsubstate
1290 C s/a
1290 C s/a
1291 C s/ss/a
1291 C s/ss/a
1292 C t/t
1292 C t/t
1293 $ echo c1 > s/a
1293 $ echo c1 > s/a
1294 $ cd s
1294 $ cd s
1295 $ echo c1 > b
1295 $ echo c1 > b
1296 $ echo c1 > c
1296 $ echo c1 > c
1297 $ hg add b
1297 $ hg add b
1298 $ cd ..
1298 $ cd ..
1299 $ hg status -S
1299 $ hg status -S
1300 M s/a
1300 M s/a
1301 A s/b
1301 A s/b
1302 ? s/c
1302 ? s/c
1303 $ hg update -C
1303 $ hg update -C
1304 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1304 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1305 updated to "925c17564ef8: 13"
1305 updated to "925c17564ef8: 13"
1306 2 other heads for branch "default"
1306 2 other heads for branch "default"
1307 $ hg status -S
1307 $ hg status -S
1308 ? s/b
1308 ? s/b
1309 ? s/c
1309 ? s/c
1310
1310
1311 Sticky subrepositories, no changes
1311 Sticky subrepositories, no changes
1312 $ cd $TESTTMP/t
1312 $ cd $TESTTMP/t
1313 $ hg id
1313 $ hg id
1314 925c17564ef8 tip
1314 925c17564ef8 tip
1315 $ hg -R s id
1315 $ hg -R s id
1316 12a213df6fa9 tip
1316 12a213df6fa9 tip
1317 $ hg -R t id
1317 $ hg -R t id
1318 52c0adc0515a tip
1318 52c0adc0515a tip
1319 $ hg update 11
1319 $ hg update 11
1320 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1320 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1321 $ hg id
1321 $ hg id
1322 365661e5936a
1322 365661e5936a
1323 $ hg -R s id
1323 $ hg -R s id
1324 fc627a69481f
1324 fc627a69481f
1325 $ hg -R t id
1325 $ hg -R t id
1326 e95bcfa18a35
1326 e95bcfa18a35
1327
1327
1328 Sticky subrepositories, file changes
1328 Sticky subrepositories, file changes
1329 $ touch s/f1
1329 $ touch s/f1
1330 $ touch t/f1
1330 $ touch t/f1
1331 $ hg add -S s/f1
1331 $ hg add -S s/f1
1332 $ hg add -S t/f1
1332 $ hg add -S t/f1
1333 $ hg id
1333 $ hg id
1334 365661e5936a+
1334 365661e5936a+
1335 $ hg -R s id
1335 $ hg -R s id
1336 fc627a69481f+
1336 fc627a69481f+
1337 $ hg -R t id
1337 $ hg -R t id
1338 e95bcfa18a35+
1338 e95bcfa18a35+
1339 $ hg update tip
1339 $ hg update tip
1340 subrepository s diverged (local revision: fc627a69481f, remote revision: 12a213df6fa9)
1340 subrepository s diverged (local revision: fc627a69481f, remote revision: 12a213df6fa9)
1341 (M)erge, keep (l)ocal [working copy] or keep (r)emote [destination]? m
1341 (M)erge, keep (l)ocal [working copy] or keep (r)emote [destination]? m
1342 subrepository sources for s differ
1342 subrepository sources for s differ
1343 use (l)ocal source (fc627a69481f) or (r)emote source (12a213df6fa9)? l
1343 use (l)ocal source (fc627a69481f) or (r)emote source (12a213df6fa9)? l
1344 subrepository t diverged (local revision: e95bcfa18a35, remote revision: 52c0adc0515a)
1344 subrepository t diverged (local revision: e95bcfa18a35, remote revision: 52c0adc0515a)
1345 (M)erge, keep (l)ocal [working copy] or keep (r)emote [destination]? m
1345 (M)erge, keep (l)ocal [working copy] or keep (r)emote [destination]? m
1346 subrepository sources for t differ
1346 subrepository sources for t differ
1347 use (l)ocal source (e95bcfa18a35) or (r)emote source (52c0adc0515a)? l
1347 use (l)ocal source (e95bcfa18a35) or (r)emote source (52c0adc0515a)? l
1348 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1348 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1349 $ hg id
1349 $ hg id
1350 925c17564ef8+ tip
1350 925c17564ef8+ tip
1351 $ hg -R s id
1351 $ hg -R s id
1352 fc627a69481f+
1352 fc627a69481f+
1353 $ hg -R t id
1353 $ hg -R t id
1354 e95bcfa18a35+
1354 e95bcfa18a35+
1355 $ hg update --clean tip
1355 $ hg update --clean tip
1356 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1356 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1357
1357
1358 Sticky subrepository, revision updates
1358 Sticky subrepository, revision updates
1359 $ hg id
1359 $ hg id
1360 925c17564ef8 tip
1360 925c17564ef8 tip
1361 $ hg -R s id
1361 $ hg -R s id
1362 12a213df6fa9 tip
1362 12a213df6fa9 tip
1363 $ hg -R t id
1363 $ hg -R t id
1364 52c0adc0515a tip
1364 52c0adc0515a tip
1365 $ cd s
1365 $ cd s
1366 $ hg update -r -2
1366 $ hg update -r -2
1367 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1367 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1368 $ cd ../t
1368 $ cd ../t
1369 $ hg update -r 2
1369 $ hg update -r 2
1370 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1370 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1371 $ cd ..
1371 $ cd ..
1372 $ hg update 10
1372 $ hg update 10
1373 subrepository s diverged (local revision: 12a213df6fa9, remote revision: fc627a69481f)
1373 subrepository s diverged (local revision: 12a213df6fa9, remote revision: fc627a69481f)
1374 (M)erge, keep (l)ocal [working copy] or keep (r)emote [destination]? m
1374 (M)erge, keep (l)ocal [working copy] or keep (r)emote [destination]? m
1375 subrepository t diverged (local revision: 52c0adc0515a, remote revision: 20a0db6fbf6c)
1375 subrepository t diverged (local revision: 52c0adc0515a, remote revision: 20a0db6fbf6c)
1376 (M)erge, keep (l)ocal [working copy] or keep (r)emote [destination]? m
1376 (M)erge, keep (l)ocal [working copy] or keep (r)emote [destination]? m
1377 subrepository sources for t differ (in checked out version)
1377 subrepository sources for t differ (in checked out version)
1378 use (l)ocal source (7af322bc1198) or (r)emote source (20a0db6fbf6c)? l
1378 use (l)ocal source (7af322bc1198) or (r)emote source (20a0db6fbf6c)? l
1379 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1379 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1380 $ hg id
1380 $ hg id
1381 e45c8b14af55+
1381 e45c8b14af55+
1382 $ hg -R s id
1382 $ hg -R s id
1383 02dcf1d70411
1383 02dcf1d70411
1384 $ hg -R t id
1384 $ hg -R t id
1385 7af322bc1198
1385 7af322bc1198
1386
1386
1387 Sticky subrepository, file changes and revision updates
1387 Sticky subrepository, file changes and revision updates
1388 $ touch s/f1
1388 $ touch s/f1
1389 $ touch t/f1
1389 $ touch t/f1
1390 $ hg add -S s/f1
1390 $ hg add -S s/f1
1391 $ hg add -S t/f1
1391 $ hg add -S t/f1
1392 $ hg id
1392 $ hg id
1393 e45c8b14af55+
1393 e45c8b14af55+
1394 $ hg -R s id
1394 $ hg -R s id
1395 02dcf1d70411+
1395 02dcf1d70411+
1396 $ hg -R t id
1396 $ hg -R t id
1397 7af322bc1198+
1397 7af322bc1198+
1398 $ hg update tip
1398 $ hg update tip
1399 subrepository s diverged (local revision: 12a213df6fa9, remote revision: 12a213df6fa9)
1399 subrepository s diverged (local revision: 12a213df6fa9, remote revision: 12a213df6fa9)
1400 (M)erge, keep (l)ocal [working copy] or keep (r)emote [destination]? m
1400 (M)erge, keep (l)ocal [working copy] or keep (r)emote [destination]? m
1401 subrepository sources for s differ
1401 subrepository sources for s differ
1402 use (l)ocal source (02dcf1d70411) or (r)emote source (12a213df6fa9)? l
1402 use (l)ocal source (02dcf1d70411) or (r)emote source (12a213df6fa9)? l
1403 subrepository t diverged (local revision: 52c0adc0515a, remote revision: 52c0adc0515a)
1403 subrepository t diverged (local revision: 52c0adc0515a, remote revision: 52c0adc0515a)
1404 (M)erge, keep (l)ocal [working copy] or keep (r)emote [destination]? m
1404 (M)erge, keep (l)ocal [working copy] or keep (r)emote [destination]? m
1405 subrepository sources for t differ
1405 subrepository sources for t differ
1406 use (l)ocal source (7af322bc1198) or (r)emote source (52c0adc0515a)? l
1406 use (l)ocal source (7af322bc1198) or (r)emote source (52c0adc0515a)? l
1407 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1407 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1408 $ hg id
1408 $ hg id
1409 925c17564ef8+ tip
1409 925c17564ef8+ tip
1410 $ hg -R s id
1410 $ hg -R s id
1411 02dcf1d70411+
1411 02dcf1d70411+
1412 $ hg -R t id
1412 $ hg -R t id
1413 7af322bc1198+
1413 7af322bc1198+
1414
1414
1415 Sticky repository, update --clean
1415 Sticky repository, update --clean
1416 $ hg update --clean tip
1416 $ hg update --clean tip
1417 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1417 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1418 $ hg id
1418 $ hg id
1419 925c17564ef8 tip
1419 925c17564ef8 tip
1420 $ hg -R s id
1420 $ hg -R s id
1421 12a213df6fa9 tip
1421 12a213df6fa9 tip
1422 $ hg -R t id
1422 $ hg -R t id
1423 52c0adc0515a tip
1423 52c0adc0515a tip
1424
1424
1425 Test subrepo already at intended revision:
1425 Test subrepo already at intended revision:
1426 $ cd s
1426 $ cd s
1427 $ hg update fc627a69481f
1427 $ hg update fc627a69481f
1428 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1428 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1429 $ cd ..
1429 $ cd ..
1430 $ hg update 11
1430 $ hg update 11
1431 subrepository s diverged (local revision: 12a213df6fa9, remote revision: fc627a69481f)
1431 subrepository s diverged (local revision: 12a213df6fa9, remote revision: fc627a69481f)
1432 (M)erge, keep (l)ocal [working copy] or keep (r)emote [destination]? m
1432 (M)erge, keep (l)ocal [working copy] or keep (r)emote [destination]? m
1433 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1433 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1434 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1434 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1435 $ hg id -n
1435 $ hg id -n
1436 11+
1436 11+
1437 $ hg -R s id
1437 $ hg -R s id
1438 fc627a69481f
1438 fc627a69481f
1439 $ hg -R t id
1439 $ hg -R t id
1440 e95bcfa18a35
1440 e95bcfa18a35
1441
1441
1442 Test that removing .hgsubstate doesn't break anything:
1442 Test that removing .hgsubstate doesn't break anything:
1443
1443
1444 $ hg rm -f .hgsubstate
1444 $ hg rm -f .hgsubstate
1445 $ hg ci -mrm
1445 $ hg ci -mrm
1446 nothing changed
1446 nothing changed
1447 [1]
1447 [1]
1448 $ hg log -vr tip
1448 $ hg log -vr tip
1449 changeset: 13:925c17564ef8
1449 changeset: 13:925c17564ef8
1450 tag: tip
1450 tag: tip
1451 user: test
1451 user: test
1452 date: Thu Jan 01 00:00:00 1970 +0000
1452 date: Thu Jan 01 00:00:00 1970 +0000
1453 files: .hgsubstate
1453 files: .hgsubstate
1454 description:
1454 description:
1455 13
1455 13
1456
1456
1457
1457
1458
1458
1459 Test that removing .hgsub removes .hgsubstate:
1459 Test that removing .hgsub removes .hgsubstate:
1460
1460
1461 $ hg rm .hgsub
1461 $ hg rm .hgsub
1462 $ hg ci -mrm2
1462 $ hg ci -mrm2
1463 created new head
1463 created new head
1464 $ hg log -vr tip
1464 $ hg log -vr tip
1465 changeset: 14:2400bccd50af
1465 changeset: 14:2400bccd50af
1466 tag: tip
1466 tag: tip
1467 parent: 11:365661e5936a
1467 parent: 11:365661e5936a
1468 user: test
1468 user: test
1469 date: Thu Jan 01 00:00:00 1970 +0000
1469 date: Thu Jan 01 00:00:00 1970 +0000
1470 files: .hgsub .hgsubstate
1470 files: .hgsub .hgsubstate
1471 description:
1471 description:
1472 rm2
1472 rm2
1473
1473
1474
1474
1475 Test issue3153: diff -S with deleted subrepos
1475 Test issue3153: diff -S with deleted subrepos
1476
1476
1477 $ hg diff --nodates -S -c .
1477 $ hg diff --nodates -S -c .
1478 diff -r 365661e5936a -r 2400bccd50af .hgsub
1478 diff -r 365661e5936a -r 2400bccd50af .hgsub
1479 --- a/.hgsub
1479 --- a/.hgsub
1480 +++ /dev/null
1480 +++ /dev/null
1481 @@ -1,2 +0,0 @@
1481 @@ -1,2 +0,0 @@
1482 -s = s
1482 -s = s
1483 -t = t
1483 -t = t
1484 diff -r 365661e5936a -r 2400bccd50af .hgsubstate
1484 diff -r 365661e5936a -r 2400bccd50af .hgsubstate
1485 --- a/.hgsubstate
1485 --- a/.hgsubstate
1486 +++ /dev/null
1486 +++ /dev/null
1487 @@ -1,2 +0,0 @@
1487 @@ -1,2 +0,0 @@
1488 -fc627a69481fcbe5f1135069e8a3881c023e4cf5 s
1488 -fc627a69481fcbe5f1135069e8a3881c023e4cf5 s
1489 -e95bcfa18a358dc4936da981ebf4147b4cad1362 t
1489 -e95bcfa18a358dc4936da981ebf4147b4cad1362 t
1490
1490
1491 Test behavior of add for explicit path in subrepo:
1491 Test behavior of add for explicit path in subrepo:
1492 $ cd ..
1492 $ cd ..
1493 $ hg init explicit
1493 $ hg init explicit
1494 $ cd explicit
1494 $ cd explicit
1495 $ echo s = s > .hgsub
1495 $ echo s = s > .hgsub
1496 $ hg add .hgsub
1496 $ hg add .hgsub
1497 $ hg init s
1497 $ hg init s
1498 $ hg ci -m0
1498 $ hg ci -m0
1499 Adding with an explicit path in a subrepo adds the file
1499 Adding with an explicit path in a subrepo adds the file
1500 $ echo c1 > f1
1500 $ echo c1 > f1
1501 $ echo c2 > s/f2
1501 $ echo c2 > s/f2
1502 $ hg st -S
1502 $ hg st -S
1503 ? f1
1503 ? f1
1504 ? s/f2
1504 ? s/f2
1505 $ hg add s/f2
1505 $ hg add s/f2
1506 $ hg st -S
1506 $ hg st -S
1507 A s/f2
1507 A s/f2
1508 ? f1
1508 ? f1
1509 $ hg ci -R s -m0
1509 $ hg ci -R s -m0
1510 $ hg ci -Am1
1510 $ hg ci -Am1
1511 adding f1
1511 adding f1
1512 Adding with an explicit path in a subrepo with -S has the same behavior
1512 Adding with an explicit path in a subrepo with -S has the same behavior
1513 $ echo c3 > f3
1513 $ echo c3 > f3
1514 $ echo c4 > s/f4
1514 $ echo c4 > s/f4
1515 $ hg st -S
1515 $ hg st -S
1516 ? f3
1516 ? f3
1517 ? s/f4
1517 ? s/f4
1518 $ hg add -S s/f4
1518 $ hg add -S s/f4
1519 $ hg st -S
1519 $ hg st -S
1520 A s/f4
1520 A s/f4
1521 ? f3
1521 ? f3
1522 $ hg ci -R s -m1
1522 $ hg ci -R s -m1
1523 $ hg ci -Ama2
1523 $ hg ci -Ama2
1524 adding f3
1524 adding f3
1525 Adding without a path or pattern silently ignores subrepos
1525 Adding without a path or pattern silently ignores subrepos
1526 $ echo c5 > f5
1526 $ echo c5 > f5
1527 $ echo c6 > s/f6
1527 $ echo c6 > s/f6
1528 $ echo c7 > s/f7
1528 $ echo c7 > s/f7
1529 $ hg st -S
1529 $ hg st -S
1530 ? f5
1530 ? f5
1531 ? s/f6
1531 ? s/f6
1532 ? s/f7
1532 ? s/f7
1533 $ hg add
1533 $ hg add
1534 adding f5
1534 adding f5
1535 $ hg st -S
1535 $ hg st -S
1536 A f5
1536 A f5
1537 ? s/f6
1537 ? s/f6
1538 ? s/f7
1538 ? s/f7
1539 $ hg ci -R s -Am2
1539 $ hg ci -R s -Am2
1540 adding f6
1540 adding f6
1541 adding f7
1541 adding f7
1542 $ hg ci -m3
1542 $ hg ci -m3
1543 Adding without a path or pattern with -S also adds files in subrepos
1543 Adding without a path or pattern with -S also adds files in subrepos
1544 $ echo c8 > f8
1544 $ echo c8 > f8
1545 $ echo c9 > s/f9
1545 $ echo c9 > s/f9
1546 $ echo c10 > s/f10
1546 $ echo c10 > s/f10
1547 $ hg st -S
1547 $ hg st -S
1548 ? f8
1548 ? f8
1549 ? s/f10
1549 ? s/f10
1550 ? s/f9
1550 ? s/f9
1551 $ hg add -S
1551 $ hg add -S
1552 adding f8
1552 adding f8
1553 adding s/f10
1553 adding s/f10
1554 adding s/f9
1554 adding s/f9
1555 $ hg st -S
1555 $ hg st -S
1556 A f8
1556 A f8
1557 A s/f10
1557 A s/f10
1558 A s/f9
1558 A s/f9
1559 $ hg ci -R s -m3
1559 $ hg ci -R s -m3
1560 $ hg ci -m4
1560 $ hg ci -m4
1561 Adding with a pattern silently ignores subrepos
1561 Adding with a pattern silently ignores subrepos
1562 $ echo c11 > fm11
1562 $ echo c11 > fm11
1563 $ echo c12 > fn12
1563 $ echo c12 > fn12
1564 $ echo c13 > s/fm13
1564 $ echo c13 > s/fm13
1565 $ echo c14 > s/fn14
1565 $ echo c14 > s/fn14
1566 $ hg st -S
1566 $ hg st -S
1567 ? fm11
1567 ? fm11
1568 ? fn12
1568 ? fn12
1569 ? s/fm13
1569 ? s/fm13
1570 ? s/fn14
1570 ? s/fn14
1571 $ hg add 'glob:**fm*'
1571 $ hg add 'glob:**fm*'
1572 adding fm11
1572 adding fm11
1573 $ hg st -S
1573 $ hg st -S
1574 A fm11
1574 A fm11
1575 ? fn12
1575 ? fn12
1576 ? s/fm13
1576 ? s/fm13
1577 ? s/fn14
1577 ? s/fn14
1578 $ hg ci -R s -Am4
1578 $ hg ci -R s -Am4
1579 adding fm13
1579 adding fm13
1580 adding fn14
1580 adding fn14
1581 $ hg ci -Am5
1581 $ hg ci -Am5
1582 adding fn12
1582 adding fn12
1583 Adding with a pattern with -S also adds matches in subrepos
1583 Adding with a pattern with -S also adds matches in subrepos
1584 $ echo c15 > fm15
1584 $ echo c15 > fm15
1585 $ echo c16 > fn16
1585 $ echo c16 > fn16
1586 $ echo c17 > s/fm17
1586 $ echo c17 > s/fm17
1587 $ echo c18 > s/fn18
1587 $ echo c18 > s/fn18
1588 $ hg st -S
1588 $ hg st -S
1589 ? fm15
1589 ? fm15
1590 ? fn16
1590 ? fn16
1591 ? s/fm17
1591 ? s/fm17
1592 ? s/fn18
1592 ? s/fn18
1593 $ hg add -S 'glob:**fm*'
1593 $ hg add -S 'glob:**fm*'
1594 adding fm15
1594 adding fm15
1595 adding s/fm17
1595 adding s/fm17
1596 $ hg st -S
1596 $ hg st -S
1597 A fm15
1597 A fm15
1598 A s/fm17
1598 A s/fm17
1599 ? fn16
1599 ? fn16
1600 ? s/fn18
1600 ? s/fn18
1601 $ hg ci -R s -Am5
1601 $ hg ci -R s -Am5
1602 adding fn18
1602 adding fn18
1603 $ hg ci -Am6
1603 $ hg ci -Am6
1604 adding fn16
1604 adding fn16
1605
1605
1606 Test behavior of forget for explicit path in subrepo:
1606 Test behavior of forget for explicit path in subrepo:
1607 Forgetting an explicit path in a subrepo untracks the file
1607 Forgetting an explicit path in a subrepo untracks the file
1608 $ echo c19 > s/f19
1608 $ echo c19 > s/f19
1609 $ hg add s/f19
1609 $ hg add s/f19
1610 $ hg st -S
1610 $ hg st -S
1611 A s/f19
1611 A s/f19
1612 $ hg forget s/f19
1612 $ hg forget s/f19
1613 $ hg st -S
1613 $ hg st -S
1614 ? s/f19
1614 ? s/f19
1615 $ rm s/f19
1615 $ rm s/f19
1616 $ cd ..
1616 $ cd ..
1617
1617
1618 Courtesy phases synchronisation to publishing server does not block the push
1618 Courtesy phases synchronisation to publishing server does not block the push
1619 (issue3781)
1619 (issue3781)
1620
1620
1621 $ cp -R main issue3781
1621 $ cp -R main issue3781
1622 $ cp -R main issue3781-dest
1622 $ cp -R main issue3781-dest
1623 $ cd issue3781-dest/s
1623 $ cd issue3781-dest/s
1624 $ hg phase tip # show we have draft changeset
1624 $ hg phase tip # show we have draft changeset
1625 5: draft
1625 5: draft
1626 $ chmod a-w .hg/store/phaseroots # prevent phase push
1626 $ chmod a-w .hg/store/phaseroots # prevent phase push
1627 $ cd ../../issue3781
1627 $ cd ../../issue3781
1628 $ cat >> .hg/hgrc << EOF
1628 $ cat >> .hg/hgrc << EOF
1629 > [paths]
1629 > [paths]
1630 > default=../issue3781-dest/
1630 > default=../issue3781-dest/
1631 > EOF
1631 > EOF
1632 $ hg push --config devel.legacy.exchange=bundle1
1632 $ hg push --config devel.legacy.exchange=bundle1
1633 pushing to $TESTTMP/issue3781-dest
1633 pushing to $TESTTMP/issue3781-dest
1634 pushing subrepo s to $TESTTMP/issue3781-dest/s
1634 pushing subrepo s to $TESTTMP/issue3781-dest/s
1635 searching for changes
1635 searching for changes
1636 no changes found
1636 no changes found
1637 searching for changes
1637 searching for changes
1638 no changes found
1638 no changes found
1639 [1]
1639 [1]
1640 # clean the push cache
1640 # clean the push cache
1641 $ rm s/.hg/cache/storehash/*
1641 $ rm s/.hg/cache/storehash/*
1642 $ hg push # bundle2+
1642 $ hg push # bundle2+
1643 pushing to $TESTTMP/issue3781-dest
1643 pushing to $TESTTMP/issue3781-dest
1644 pushing subrepo s to $TESTTMP/issue3781-dest/s
1644 pushing subrepo s to $TESTTMP/issue3781-dest/s
1645 searching for changes
1645 searching for changes
1646 no changes found
1646 no changes found
1647 searching for changes
1647 searching for changes
1648 no changes found
1648 no changes found
1649 [1]
1649 [1]
1650 $ cd ..
1650 $ cd ..
1651
1651
1652 Test phase choice for newly created commit with "phases.subrepochecks"
1652 Test phase choice for newly created commit with "phases.subrepochecks"
1653 configuration
1653 configuration
1654
1654
1655 $ cd t
1655 $ cd t
1656 $ hg update -q -r 12
1656 $ hg update -q -r 12
1657
1657
1658 $ cat >> s/ss/.hg/hgrc <<EOF
1658 $ cat >> s/ss/.hg/hgrc <<EOF
1659 > [phases]
1659 > [phases]
1660 > new-commit = secret
1660 > new-commit = secret
1661 > EOF
1661 > EOF
1662 $ cat >> s/.hg/hgrc <<EOF
1662 $ cat >> s/.hg/hgrc <<EOF
1663 > [phases]
1663 > [phases]
1664 > new-commit = draft
1664 > new-commit = draft
1665 > EOF
1665 > EOF
1666 $ echo phasecheck1 >> s/ss/a
1666 $ echo phasecheck1 >> s/ss/a
1667 $ hg -R s commit -S --config phases.checksubrepos=abort -m phasecheck1
1667 $ hg -R s commit -S --config phases.checksubrepos=abort -m phasecheck1
1668 committing subrepository ss
1668 committing subrepository ss
1669 transaction abort!
1669 transaction abort!
1670 rollback completed
1670 rollback completed
1671 abort: can't commit in draft phase conflicting secret from subrepository ss
1671 abort: can't commit in draft phase conflicting secret from subrepository ss
1672 [255]
1672 [255]
1673 $ echo phasecheck2 >> s/ss/a
1673 $ echo phasecheck2 >> s/ss/a
1674 $ hg -R s commit -S --config phases.checksubrepos=ignore -m phasecheck2
1674 $ hg -R s commit -S --config phases.checksubrepos=ignore -m phasecheck2
1675 committing subrepository ss
1675 committing subrepository ss
1676 $ hg -R s/ss phase tip
1676 $ hg -R s/ss phase tip
1677 3: secret
1677 3: secret
1678 $ hg -R s phase tip
1678 $ hg -R s phase tip
1679 6: draft
1679 6: draft
1680 $ echo phasecheck3 >> s/ss/a
1680 $ echo phasecheck3 >> s/ss/a
1681 $ hg -R s commit -S -m phasecheck3
1681 $ hg -R s commit -S -m phasecheck3
1682 committing subrepository ss
1682 committing subrepository ss
1683 warning: changes are committed in secret phase from subrepository ss
1683 warning: changes are committed in secret phase from subrepository ss
1684 $ hg -R s/ss phase tip
1684 $ hg -R s/ss phase tip
1685 4: secret
1685 4: secret
1686 $ hg -R s phase tip
1686 $ hg -R s phase tip
1687 7: secret
1687 7: secret
1688
1688
1689 $ cat >> t/.hg/hgrc <<EOF
1689 $ cat >> t/.hg/hgrc <<EOF
1690 > [phases]
1690 > [phases]
1691 > new-commit = draft
1691 > new-commit = draft
1692 > EOF
1692 > EOF
1693 $ cat >> .hg/hgrc <<EOF
1693 $ cat >> .hg/hgrc <<EOF
1694 > [phases]
1694 > [phases]
1695 > new-commit = public
1695 > new-commit = public
1696 > EOF
1696 > EOF
1697 $ echo phasecheck4 >> s/ss/a
1697 $ echo phasecheck4 >> s/ss/a
1698 $ echo phasecheck4 >> t/t
1698 $ echo phasecheck4 >> t/t
1699 $ hg commit -S -m phasecheck4
1699 $ hg commit -S -m phasecheck4
1700 committing subrepository s
1700 committing subrepository s
1701 committing subrepository s/ss
1701 committing subrepository s/ss
1702 warning: changes are committed in secret phase from subrepository ss
1702 warning: changes are committed in secret phase from subrepository ss
1703 committing subrepository t
1703 committing subrepository t
1704 warning: changes are committed in secret phase from subrepository s
1704 warning: changes are committed in secret phase from subrepository s
1705 created new head
1705 created new head
1706 $ hg -R s/ss phase tip
1706 $ hg -R s/ss phase tip
1707 5: secret
1707 5: secret
1708 $ hg -R s phase tip
1708 $ hg -R s phase tip
1709 8: secret
1709 8: secret
1710 $ hg -R t phase tip
1710 $ hg -R t phase tip
1711 6: draft
1711 6: draft
1712 $ hg phase tip
1712 $ hg phase tip
1713 15: secret
1713 15: secret
1714
1714
1715 $ cd ..
1715 $ cd ..
1716
1716
1717
1717
1718 Test that commit --secret works on both repo and subrepo (issue4182)
1718 Test that commit --secret works on both repo and subrepo (issue4182)
1719
1719
1720 $ cd main
1720 $ cd main
1721 $ echo secret >> b
1721 $ echo secret >> b
1722 $ echo secret >> s/b
1722 $ echo secret >> s/b
1723 $ hg commit --secret --subrepo -m "secret"
1723 $ hg commit --secret --subrepo -m "secret"
1724 committing subrepository s
1724 committing subrepository s
1725 $ hg phase -r .
1725 $ hg phase -r .
1726 6: secret
1726 6: secret
1727 $ cd s
1727 $ cd s
1728 $ hg phase -r .
1728 $ hg phase -r .
1729 6: secret
1729 6: secret
1730 $ cd ../../
1730 $ cd ../../
1731
1731
1732 Test "subrepos" template keyword
1732 Test "subrepos" template keyword
1733
1733
1734 $ cd t
1734 $ cd t
1735 $ hg update -q 15
1735 $ hg update -q 15
1736 $ cat > .hgsub <<EOF
1736 $ cat > .hgsub <<EOF
1737 > s = s
1737 > s = s
1738 > EOF
1738 > EOF
1739 $ hg commit -m "16"
1739 $ hg commit -m "16"
1740 warning: changes are committed in secret phase from subrepository s
1740 warning: changes are committed in secret phase from subrepository s
1741
1741
1742 (addition of ".hgsub" itself)
1742 (addition of ".hgsub" itself)
1743
1743
1744 $ hg diff --nodates -c 1 .hgsubstate
1744 $ hg diff --nodates -c 1 .hgsubstate
1745 diff -r f7b1eb17ad24 -r 7cf8cfea66e4 .hgsubstate
1745 diff -r f7b1eb17ad24 -r 7cf8cfea66e4 .hgsubstate
1746 --- /dev/null
1746 --- /dev/null
1747 +++ b/.hgsubstate
1747 +++ b/.hgsubstate
1748 @@ -0,0 +1,1 @@
1748 @@ -0,0 +1,1 @@
1749 +e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
1749 +e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
1750 $ hg log -r 1 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1750 $ hg log -r 1 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1751 f7b1eb17ad24 000000000000
1751 f7b1eb17ad24 000000000000
1752 s
1752 s
1753
1753
1754 (modification of existing entry)
1754 (modification of existing entry)
1755
1755
1756 $ hg diff --nodates -c 2 .hgsubstate
1756 $ hg diff --nodates -c 2 .hgsubstate
1757 diff -r 7cf8cfea66e4 -r df30734270ae .hgsubstate
1757 diff -r 7cf8cfea66e4 -r df30734270ae .hgsubstate
1758 --- a/.hgsubstate
1758 --- a/.hgsubstate
1759 +++ b/.hgsubstate
1759 +++ b/.hgsubstate
1760 @@ -1,1 +1,1 @@
1760 @@ -1,1 +1,1 @@
1761 -e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
1761 -e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
1762 +dc73e2e6d2675eb2e41e33c205f4bdab4ea5111d s
1762 +dc73e2e6d2675eb2e41e33c205f4bdab4ea5111d s
1763 $ hg log -r 2 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1763 $ hg log -r 2 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1764 7cf8cfea66e4 000000000000
1764 7cf8cfea66e4 000000000000
1765 s
1765 s
1766
1766
1767 (addition of entry)
1767 (addition of entry)
1768
1768
1769 $ hg diff --nodates -c 5 .hgsubstate
1769 $ hg diff --nodates -c 5 .hgsubstate
1770 diff -r 7cf8cfea66e4 -r 1f14a2e2d3ec .hgsubstate
1770 diff -r 7cf8cfea66e4 -r 1f14a2e2d3ec .hgsubstate
1771 --- a/.hgsubstate
1771 --- a/.hgsubstate
1772 +++ b/.hgsubstate
1772 +++ b/.hgsubstate
1773 @@ -1,1 +1,2 @@
1773 @@ -1,1 +1,2 @@
1774 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
1774 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
1775 +60ca1237c19474e7a3978b0dc1ca4e6f36d51382 t
1775 +60ca1237c19474e7a3978b0dc1ca4e6f36d51382 t
1776 $ hg log -r 5 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1776 $ hg log -r 5 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1777 7cf8cfea66e4 000000000000
1777 7cf8cfea66e4 000000000000
1778 t
1778 t
1779
1779
1780 (removal of existing entry)
1780 (removal of existing entry)
1781
1781
1782 $ hg diff --nodates -c 16 .hgsubstate
1782 $ hg diff --nodates -c 16 .hgsubstate
1783 diff -r 8bec38d2bd0b -r f2f70bc3d3c9 .hgsubstate
1783 diff -r 8bec38d2bd0b -r f2f70bc3d3c9 .hgsubstate
1784 --- a/.hgsubstate
1784 --- a/.hgsubstate
1785 +++ b/.hgsubstate
1785 +++ b/.hgsubstate
1786 @@ -1,2 +1,1 @@
1786 @@ -1,2 +1,1 @@
1787 0731af8ca9423976d3743119d0865097c07bdc1b s
1787 0731af8ca9423976d3743119d0865097c07bdc1b s
1788 -e202dc79b04c88a636ea8913d9182a1346d9b3dc t
1788 -e202dc79b04c88a636ea8913d9182a1346d9b3dc t
1789 $ hg log -r 16 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1789 $ hg log -r 16 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1790 8bec38d2bd0b 000000000000
1790 8bec38d2bd0b 000000000000
1791 t
1791 t
1792
1792
1793 (merging)
1793 (merging)
1794
1794
1795 $ hg diff --nodates -c 9 .hgsubstate
1795 $ hg diff --nodates -c 9 .hgsubstate
1796 diff -r f6affe3fbfaa -r f0d2028bf86d .hgsubstate
1796 diff -r f6affe3fbfaa -r f0d2028bf86d .hgsubstate
1797 --- a/.hgsubstate
1797 --- a/.hgsubstate
1798 +++ b/.hgsubstate
1798 +++ b/.hgsubstate
1799 @@ -1,1 +1,2 @@
1799 @@ -1,1 +1,2 @@
1800 fc627a69481fcbe5f1135069e8a3881c023e4cf5 s
1800 fc627a69481fcbe5f1135069e8a3881c023e4cf5 s
1801 +60ca1237c19474e7a3978b0dc1ca4e6f36d51382 t
1801 +60ca1237c19474e7a3978b0dc1ca4e6f36d51382 t
1802 $ hg log -r 9 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1802 $ hg log -r 9 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1803 f6affe3fbfaa 1f14a2e2d3ec
1803 f6affe3fbfaa 1f14a2e2d3ec
1804 t
1804 t
1805
1805
1806 (removal of ".hgsub" itself)
1806 (removal of ".hgsub" itself)
1807
1807
1808 $ hg diff --nodates -c 8 .hgsubstate
1808 $ hg diff --nodates -c 8 .hgsubstate
1809 diff -r f94576341bcf -r 96615c1dad2d .hgsubstate
1809 diff -r f94576341bcf -r 96615c1dad2d .hgsubstate
1810 --- a/.hgsubstate
1810 --- a/.hgsubstate
1811 +++ /dev/null
1811 +++ /dev/null
1812 @@ -1,2 +0,0 @@
1812 @@ -1,2 +0,0 @@
1813 -e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
1813 -e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
1814 -7af322bc1198a32402fe903e0b7ebcfc5c9bf8f4 t
1814 -7af322bc1198a32402fe903e0b7ebcfc5c9bf8f4 t
1815 $ hg log -r 8 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1815 $ hg log -r 8 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1816 f94576341bcf 000000000000
1816 f94576341bcf 000000000000
1817
1817
1818 Test that '[paths]' is configured correctly at subrepo creation
1818 Test that '[paths]' is configured correctly at subrepo creation
1819
1819
1820 $ cd $TESTTMP/tc
1820 $ cd $TESTTMP/tc
1821 $ cat > .hgsub <<EOF
1821 $ cat > .hgsub <<EOF
1822 > # to clear bogus subrepo path 'bogus=[boguspath'
1822 > # to clear bogus subrepo path 'bogus=[boguspath'
1823 > s = s
1823 > s = s
1824 > t = t
1824 > t = t
1825 > EOF
1825 > EOF
1826 $ hg update -q --clean null
1826 $ hg update -q --clean null
1827 $ rm -rf s t
1827 $ rm -rf s t
1828 $ cat >> .hg/hgrc <<EOF
1828 $ cat >> .hg/hgrc <<EOF
1829 > [paths]
1829 > [paths]
1830 > default-push = /foo/bar
1830 > default-push = /foo/bar
1831 > EOF
1831 > EOF
1832 $ hg update -q
1832 $ hg update -q
1833 $ cat s/.hg/hgrc
1833 $ cat s/.hg/hgrc
1834 [paths]
1834 [paths]
1835 default = $TESTTMP/t/s
1835 default = $TESTTMP/t/s
1836 default-push = /foo/bar/s
1836 default-push = /foo/bar/s
1837 $ cat s/ss/.hg/hgrc
1837 $ cat s/ss/.hg/hgrc
1838 [paths]
1838 [paths]
1839 default = $TESTTMP/t/s/ss
1839 default = $TESTTMP/t/s/ss
1840 default-push = /foo/bar/s/ss
1840 default-push = /foo/bar/s/ss
1841 $ cat t/.hg/hgrc
1841 $ cat t/.hg/hgrc
1842 [paths]
1842 [paths]
1843 default = $TESTTMP/t/t
1843 default = $TESTTMP/t/t
1844 default-push = /foo/bar/t
1844 default-push = /foo/bar/t
1845
1845
1846 $ cd $TESTTMP/t
1846 $ cd $TESTTMP/t
1847 $ hg up -qC 0
1847 $ hg up -qC 0
1848 $ echo 'bar' > bar.txt
1848 $ echo 'bar' > bar.txt
1849 $ hg ci -Am 'branch before subrepo add'
1849 $ hg ci -Am 'branch before subrepo add'
1850 adding bar.txt
1850 adding bar.txt
1851 created new head
1851 created new head
1852 $ hg merge -r "first(subrepo('s'))"
1852 $ hg merge -r "first(subrepo('s'))"
1853 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1853 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1854 (branch merge, don't forget to commit)
1854 (branch merge, don't forget to commit)
1855 $ hg status -S -X '.hgsub*'
1855 $ hg status -S -X '.hgsub*'
1856 A s/a
1856 A s/a
1857 ? s/b
1857 ? s/b
1858 ? s/c
1858 ? s/c
1859 ? s/f1
1859 ? s/f1
1860 $ hg status -S --rev 'p2()'
1860 $ hg status -S --rev 'p2()'
1861 A bar.txt
1861 A bar.txt
1862 ? s/b
1862 ? s/b
1863 ? s/c
1863 ? s/c
1864 ? s/f1
1864 ? s/f1
1865 $ hg diff -S -X '.hgsub*' --nodates
1865 $ hg diff -S -X '.hgsub*' --nodates
1866 diff -r 000000000000 s/a
1866 diff -r 000000000000 s/a
1867 --- /dev/null
1867 --- /dev/null
1868 +++ b/s/a
1868 +++ b/s/a
1869 @@ -0,0 +1,1 @@
1869 @@ -0,0 +1,1 @@
1870 +a
1870 +a
1871 $ hg diff -S --rev 'p2()' --nodates
1871 $ hg diff -S --rev 'p2()' --nodates
1872 diff -r 7cf8cfea66e4 bar.txt
1872 diff -r 7cf8cfea66e4 bar.txt
1873 --- /dev/null
1873 --- /dev/null
1874 +++ b/bar.txt
1874 +++ b/bar.txt
1875 @@ -0,0 +1,1 @@
1875 @@ -0,0 +1,1 @@
1876 +bar
1876 +bar
1877
1877
1878 $ hg diff -X '.hgsub*' --nodates s
1879 diff -r 000000000000 s/a
1880 --- /dev/null
1881 +++ b/s/a
1882 @@ -0,0 +1,1 @@
1883 +a
1884 $ hg diff -X '.hgsub*' --nodates s/a
1885 diff -r 000000000000 s/a
1886 --- /dev/null
1887 +++ b/s/a
1888 @@ -0,0 +1,1 @@
1889 +a
1890
1878 $ cd ..
1891 $ cd ..
1879
1892
1880 test for ssh exploit 2017-07-25
1893 test for ssh exploit 2017-07-25
1881
1894
1882 $ cat >> $HGRCPATH << EOF
1895 $ cat >> $HGRCPATH << EOF
1883 > [ui]
1896 > [ui]
1884 > ssh = sh -c "read l; read l; read l"
1897 > ssh = sh -c "read l; read l; read l"
1885 > EOF
1898 > EOF
1886
1899
1887 $ hg init malicious-proxycommand
1900 $ hg init malicious-proxycommand
1888 $ cd malicious-proxycommand
1901 $ cd malicious-proxycommand
1889 $ echo 's = [hg]ssh://-oProxyCommand=touch${IFS}owned/path' > .hgsub
1902 $ echo 's = [hg]ssh://-oProxyCommand=touch${IFS}owned/path' > .hgsub
1890 $ hg init s
1903 $ hg init s
1891 $ cd s
1904 $ cd s
1892 $ echo init > init
1905 $ echo init > init
1893 $ hg add
1906 $ hg add
1894 adding init
1907 adding init
1895 $ hg commit -m init
1908 $ hg commit -m init
1896 $ cd ..
1909 $ cd ..
1897 $ hg add .hgsub
1910 $ hg add .hgsub
1898 $ hg ci -m 'add subrepo'
1911 $ hg ci -m 'add subrepo'
1899 $ cd ..
1912 $ cd ..
1900 $ hg clone malicious-proxycommand malicious-proxycommand-clone
1913 $ hg clone malicious-proxycommand malicious-proxycommand-clone
1901 updating to branch default
1914 updating to branch default
1902 cloning subrepo s from ssh://-oProxyCommand%3Dtouch%24%7BIFS%7Downed/path
1915 cloning subrepo s from ssh://-oProxyCommand%3Dtouch%24%7BIFS%7Downed/path
1903 abort: potentially unsafe url: 'ssh://-oProxyCommand=touch${IFS}owned/path' (in subrepository "s")
1916 abort: potentially unsafe url: 'ssh://-oProxyCommand=touch${IFS}owned/path' (in subrepository "s")
1904 [255]
1917 [255]
1905
1918
1906 also check that a percent encoded '-' (%2D) doesn't work
1919 also check that a percent encoded '-' (%2D) doesn't work
1907
1920
1908 $ cd malicious-proxycommand
1921 $ cd malicious-proxycommand
1909 $ echo 's = [hg]ssh://%2DoProxyCommand=touch${IFS}owned/path' > .hgsub
1922 $ echo 's = [hg]ssh://%2DoProxyCommand=touch${IFS}owned/path' > .hgsub
1910 $ hg ci -m 'change url to percent encoded'
1923 $ hg ci -m 'change url to percent encoded'
1911 $ cd ..
1924 $ cd ..
1912 $ rm -r malicious-proxycommand-clone
1925 $ rm -r malicious-proxycommand-clone
1913 $ hg clone malicious-proxycommand malicious-proxycommand-clone
1926 $ hg clone malicious-proxycommand malicious-proxycommand-clone
1914 updating to branch default
1927 updating to branch default
1915 cloning subrepo s from ssh://-oProxyCommand%3Dtouch%24%7BIFS%7Downed/path
1928 cloning subrepo s from ssh://-oProxyCommand%3Dtouch%24%7BIFS%7Downed/path
1916 abort: potentially unsafe url: 'ssh://-oProxyCommand=touch${IFS}owned/path' (in subrepository "s")
1929 abort: potentially unsafe url: 'ssh://-oProxyCommand=touch${IFS}owned/path' (in subrepository "s")
1917 [255]
1930 [255]
1918
1931
1919 also check for a pipe
1932 also check for a pipe
1920
1933
1921 $ cd malicious-proxycommand
1934 $ cd malicious-proxycommand
1922 $ echo 's = [hg]ssh://fakehost|touch${IFS}owned/path' > .hgsub
1935 $ echo 's = [hg]ssh://fakehost|touch${IFS}owned/path' > .hgsub
1923 $ hg ci -m 'change url to pipe'
1936 $ hg ci -m 'change url to pipe'
1924 $ cd ..
1937 $ cd ..
1925 $ rm -r malicious-proxycommand-clone
1938 $ rm -r malicious-proxycommand-clone
1926 $ hg clone malicious-proxycommand malicious-proxycommand-clone
1939 $ hg clone malicious-proxycommand malicious-proxycommand-clone
1927 updating to branch default
1940 updating to branch default
1928 cloning subrepo s from ssh://fakehost%7Ctouch%24%7BIFS%7Downed/path
1941 cloning subrepo s from ssh://fakehost%7Ctouch%24%7BIFS%7Downed/path
1929 abort: no suitable response from remote hg!
1942 abort: no suitable response from remote hg!
1930 [255]
1943 [255]
1931 $ [ ! -f owned ] || echo 'you got owned'
1944 $ [ ! -f owned ] || echo 'you got owned'
1932
1945
1933 also check that a percent encoded '|' (%7C) doesn't work
1946 also check that a percent encoded '|' (%7C) doesn't work
1934
1947
1935 $ cd malicious-proxycommand
1948 $ cd malicious-proxycommand
1936 $ echo 's = [hg]ssh://fakehost%7Ctouch%20owned/path' > .hgsub
1949 $ echo 's = [hg]ssh://fakehost%7Ctouch%20owned/path' > .hgsub
1937 $ hg ci -m 'change url to percent encoded pipe'
1950 $ hg ci -m 'change url to percent encoded pipe'
1938 $ cd ..
1951 $ cd ..
1939 $ rm -r malicious-proxycommand-clone
1952 $ rm -r malicious-proxycommand-clone
1940 $ hg clone malicious-proxycommand malicious-proxycommand-clone
1953 $ hg clone malicious-proxycommand malicious-proxycommand-clone
1941 updating to branch default
1954 updating to branch default
1942 cloning subrepo s from ssh://fakehost%7Ctouch%20owned/path
1955 cloning subrepo s from ssh://fakehost%7Ctouch%20owned/path
1943 abort: no suitable response from remote hg!
1956 abort: no suitable response from remote hg!
1944 [255]
1957 [255]
1945 $ [ ! -f owned ] || echo 'you got owned'
1958 $ [ ! -f owned ] || echo 'you got owned'
1946
1959
1947 and bad usernames:
1960 and bad usernames:
1948 $ cd malicious-proxycommand
1961 $ cd malicious-proxycommand
1949 $ echo 's = [hg]ssh://-oProxyCommand=touch owned@example.com/path' > .hgsub
1962 $ echo 's = [hg]ssh://-oProxyCommand=touch owned@example.com/path' > .hgsub
1950 $ hg ci -m 'owned username'
1963 $ hg ci -m 'owned username'
1951 $ cd ..
1964 $ cd ..
1952 $ rm -r malicious-proxycommand-clone
1965 $ rm -r malicious-proxycommand-clone
1953 $ hg clone malicious-proxycommand malicious-proxycommand-clone
1966 $ hg clone malicious-proxycommand malicious-proxycommand-clone
1954 updating to branch default
1967 updating to branch default
1955 cloning subrepo s from ssh://-oProxyCommand%3Dtouch%20owned@example.com/path
1968 cloning subrepo s from ssh://-oProxyCommand%3Dtouch%20owned@example.com/path
1956 abort: potentially unsafe url: 'ssh://-oProxyCommand=touch owned@example.com/path' (in subrepository "s")
1969 abort: potentially unsafe url: 'ssh://-oProxyCommand=touch owned@example.com/path' (in subrepository "s")
1957 [255]
1970 [255]
1958
1971
1959 Test convert subrepositories including merge (issue5526):
1972 Test convert subrepositories including merge (issue5526):
1960
1973
1961 $ hg init tconv
1974 $ hg init tconv
1962 $ hg convert --config extensions.convert= -q t/s tconv/s
1975 $ hg convert --config extensions.convert= -q t/s tconv/s
1963 $ hg convert --config extensions.convert= -q t/s/ss tconv/s/ss
1976 $ hg convert --config extensions.convert= -q t/s/ss tconv/s/ss
1964 $ hg convert --config extensions.convert= -q t/t tconv/t
1977 $ hg convert --config extensions.convert= -q t/t tconv/t
1965
1978
1966 convert shouldn't fail because of pseudo filenode:
1979 convert shouldn't fail because of pseudo filenode:
1967
1980
1968 $ hg convert --config extensions.convert= t tconv
1981 $ hg convert --config extensions.convert= t tconv
1969 scanning source...
1982 scanning source...
1970 sorting...
1983 sorting...
1971 converting...
1984 converting...
1972 17 0
1985 17 0
1973 16 1
1986 16 1
1974 15 2
1987 15 2
1975 14 3
1988 14 3
1976 13 4
1989 13 4
1977 12 5
1990 12 5
1978 11 6
1991 11 6
1979 10 7
1992 10 7
1980 9 8
1993 9 8
1981 8 9
1994 8 9
1982 7 10
1995 7 10
1983 6 11
1996 6 11
1984 5 12
1997 5 12
1985 4 13
1998 4 13
1986 3 rm2
1999 3 rm2
1987 2 phasecheck4
2000 2 phasecheck4
1988 1 16
2001 1 16
1989 0 branch before subrepo add
2002 0 branch before subrepo add
1990
2003
1991 converted .hgsubstate should point to valid nodes:
2004 converted .hgsubstate should point to valid nodes:
1992
2005
1993 $ hg up -R tconv 9
2006 $ hg up -R tconv 9
1994 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
2007 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1995 $ cat tconv/.hgsubstate
2008 $ cat tconv/.hgsubstate
1996 fc627a69481fcbe5f1135069e8a3881c023e4cf5 s
2009 fc627a69481fcbe5f1135069e8a3881c023e4cf5 s
1997 60ca1237c19474e7a3978b0dc1ca4e6f36d51382 t
2010 60ca1237c19474e7a3978b0dc1ca4e6f36d51382 t
General Comments 0
You need to be logged in to leave comments. Login now