##// END OF EJS Templates
merge: don't call copies.mergecopies unless we need to...
Bryan O'Sullivan -
r18612:0b6e6eac default
parent child Browse files
Show More
@@ -1,665 +1,667 b''
1 # merge.py - directory-level update/merge handling for Mercurial
1 # merge.py - directory-level update/merge handling for Mercurial
2 #
2 #
3 # Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2006, 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 node import nullid, nullrev, hex, bin
8 from node import nullid, nullrev, hex, bin
9 from i18n import _
9 from i18n import _
10 import error, util, filemerge, copies, subrepo
10 import error, util, filemerge, copies, subrepo
11 import errno, os, shutil
11 import errno, os, shutil
12
12
13 class mergestate(object):
13 class mergestate(object):
14 '''track 3-way merge state of individual files'''
14 '''track 3-way merge state of individual files'''
15 def __init__(self, repo):
15 def __init__(self, repo):
16 self._repo = repo
16 self._repo = repo
17 self._dirty = False
17 self._dirty = False
18 self._read()
18 self._read()
19 def reset(self, node=None):
19 def reset(self, node=None):
20 self._state = {}
20 self._state = {}
21 if node:
21 if node:
22 self._local = node
22 self._local = node
23 shutil.rmtree(self._repo.join("merge"), True)
23 shutil.rmtree(self._repo.join("merge"), True)
24 self._dirty = False
24 self._dirty = False
25 def _read(self):
25 def _read(self):
26 self._state = {}
26 self._state = {}
27 try:
27 try:
28 f = self._repo.opener("merge/state")
28 f = self._repo.opener("merge/state")
29 for i, l in enumerate(f):
29 for i, l in enumerate(f):
30 if i == 0:
30 if i == 0:
31 self._local = bin(l[:-1])
31 self._local = bin(l[:-1])
32 else:
32 else:
33 bits = l[:-1].split("\0")
33 bits = l[:-1].split("\0")
34 self._state[bits[0]] = bits[1:]
34 self._state[bits[0]] = bits[1:]
35 f.close()
35 f.close()
36 except IOError, err:
36 except IOError, err:
37 if err.errno != errno.ENOENT:
37 if err.errno != errno.ENOENT:
38 raise
38 raise
39 self._dirty = False
39 self._dirty = False
40 def commit(self):
40 def commit(self):
41 if self._dirty:
41 if self._dirty:
42 f = self._repo.opener("merge/state", "w")
42 f = self._repo.opener("merge/state", "w")
43 f.write(hex(self._local) + "\n")
43 f.write(hex(self._local) + "\n")
44 for d, v in self._state.iteritems():
44 for d, v in self._state.iteritems():
45 f.write("\0".join([d] + v) + "\n")
45 f.write("\0".join([d] + v) + "\n")
46 f.close()
46 f.close()
47 self._dirty = False
47 self._dirty = False
48 def add(self, fcl, fco, fca, fd):
48 def add(self, fcl, fco, fca, fd):
49 hash = util.sha1(fcl.path()).hexdigest()
49 hash = util.sha1(fcl.path()).hexdigest()
50 self._repo.opener.write("merge/" + hash, fcl.data())
50 self._repo.opener.write("merge/" + hash, fcl.data())
51 self._state[fd] = ['u', hash, fcl.path(), fca.path(),
51 self._state[fd] = ['u', hash, fcl.path(), fca.path(),
52 hex(fca.filenode()), fco.path(), fcl.flags()]
52 hex(fca.filenode()), fco.path(), fcl.flags()]
53 self._dirty = True
53 self._dirty = True
54 def __contains__(self, dfile):
54 def __contains__(self, dfile):
55 return dfile in self._state
55 return dfile in self._state
56 def __getitem__(self, dfile):
56 def __getitem__(self, dfile):
57 return self._state[dfile][0]
57 return self._state[dfile][0]
58 def __iter__(self):
58 def __iter__(self):
59 l = self._state.keys()
59 l = self._state.keys()
60 l.sort()
60 l.sort()
61 for f in l:
61 for f in l:
62 yield f
62 yield f
63 def mark(self, dfile, state):
63 def mark(self, dfile, state):
64 self._state[dfile][0] = state
64 self._state[dfile][0] = state
65 self._dirty = True
65 self._dirty = True
66 def resolve(self, dfile, wctx, octx):
66 def resolve(self, dfile, wctx, octx):
67 if self[dfile] == 'r':
67 if self[dfile] == 'r':
68 return 0
68 return 0
69 state, hash, lfile, afile, anode, ofile, flags = self._state[dfile]
69 state, hash, lfile, afile, anode, ofile, flags = self._state[dfile]
70 fcd = wctx[dfile]
70 fcd = wctx[dfile]
71 fco = octx[ofile]
71 fco = octx[ofile]
72 fca = self._repo.filectx(afile, fileid=anode)
72 fca = self._repo.filectx(afile, fileid=anode)
73 # "premerge" x flags
73 # "premerge" x flags
74 flo = fco.flags()
74 flo = fco.flags()
75 fla = fca.flags()
75 fla = fca.flags()
76 if 'x' in flags + flo + fla and 'l' not in flags + flo + fla:
76 if 'x' in flags + flo + fla and 'l' not in flags + flo + fla:
77 if fca.node() == nullid:
77 if fca.node() == nullid:
78 self._repo.ui.warn(_('warning: cannot merge flags for %s\n') %
78 self._repo.ui.warn(_('warning: cannot merge flags for %s\n') %
79 afile)
79 afile)
80 elif flags == fla:
80 elif flags == fla:
81 flags = flo
81 flags = flo
82 # restore local
82 # restore local
83 f = self._repo.opener("merge/" + hash)
83 f = self._repo.opener("merge/" + hash)
84 self._repo.wwrite(dfile, f.read(), flags)
84 self._repo.wwrite(dfile, f.read(), flags)
85 f.close()
85 f.close()
86 r = filemerge.filemerge(self._repo, self._local, lfile, fcd, fco, fca)
86 r = filemerge.filemerge(self._repo, self._local, lfile, fcd, fco, fca)
87 if r is None:
87 if r is None:
88 # no real conflict
88 # no real conflict
89 del self._state[dfile]
89 del self._state[dfile]
90 elif not r:
90 elif not r:
91 self.mark(dfile, 'r')
91 self.mark(dfile, 'r')
92 return r
92 return r
93
93
94 def _checkunknownfile(repo, wctx, mctx, f):
94 def _checkunknownfile(repo, wctx, mctx, f):
95 return (not repo.dirstate._ignore(f)
95 return (not repo.dirstate._ignore(f)
96 and os.path.isfile(repo.wjoin(f))
96 and os.path.isfile(repo.wjoin(f))
97 and repo.dirstate.normalize(f) not in repo.dirstate
97 and repo.dirstate.normalize(f) not in repo.dirstate
98 and mctx[f].cmp(wctx[f]))
98 and mctx[f].cmp(wctx[f]))
99
99
100 def _checkunknown(repo, wctx, mctx):
100 def _checkunknown(repo, wctx, mctx):
101 "check for collisions between unknown files and files in mctx"
101 "check for collisions between unknown files and files in mctx"
102
102
103 error = False
103 error = False
104 for f in mctx:
104 for f in mctx:
105 if f not in wctx and _checkunknownfile(repo, wctx, mctx, f):
105 if f not in wctx and _checkunknownfile(repo, wctx, mctx, f):
106 error = True
106 error = True
107 wctx._repo.ui.warn(_("%s: untracked file differs\n") % f)
107 wctx._repo.ui.warn(_("%s: untracked file differs\n") % f)
108 if error:
108 if error:
109 raise util.Abort(_("untracked files in working directory differ "
109 raise util.Abort(_("untracked files in working directory differ "
110 "from files in requested revision"))
110 "from files in requested revision"))
111
111
112 def _remains(f, m, ma, workingctx=False):
112 def _remains(f, m, ma, workingctx=False):
113 """check whether specified file remains after merge.
113 """check whether specified file remains after merge.
114
114
115 It is assumed that specified file is not contained in the manifest
115 It is assumed that specified file is not contained in the manifest
116 of the other context.
116 of the other context.
117 """
117 """
118 if f in ma:
118 if f in ma:
119 n = m[f]
119 n = m[f]
120 if n != ma[f]:
120 if n != ma[f]:
121 return True # because it is changed locally
121 return True # because it is changed locally
122 # even though it doesn't remain, if "remote deleted" is
122 # even though it doesn't remain, if "remote deleted" is
123 # chosen in manifestmerge()
123 # chosen in manifestmerge()
124 elif workingctx and n[20:] == "a":
124 elif workingctx and n[20:] == "a":
125 return True # because it is added locally (linear merge specific)
125 return True # because it is added locally (linear merge specific)
126 else:
126 else:
127 return False # because it is removed remotely
127 return False # because it is removed remotely
128 else:
128 else:
129 return True # because it is added locally
129 return True # because it is added locally
130
130
131 def _checkcollision(mctx, extractxs):
131 def _checkcollision(mctx, extractxs):
132 "check for case folding collisions in the destination context"
132 "check for case folding collisions in the destination context"
133 folded = {}
133 folded = {}
134 for fn in mctx:
134 for fn in mctx:
135 fold = util.normcase(fn)
135 fold = util.normcase(fn)
136 if fold in folded:
136 if fold in folded:
137 raise util.Abort(_("case-folding collision between %s and %s")
137 raise util.Abort(_("case-folding collision between %s and %s")
138 % (fn, folded[fold]))
138 % (fn, folded[fold]))
139 folded[fold] = fn
139 folded[fold] = fn
140
140
141 if extractxs:
141 if extractxs:
142 wctx, actx = extractxs
142 wctx, actx = extractxs
143 # class to delay looking up copy mapping
143 # class to delay looking up copy mapping
144 class pathcopies(object):
144 class pathcopies(object):
145 @util.propertycache
145 @util.propertycache
146 def map(self):
146 def map(self):
147 # {dst@mctx: src@wctx} copy mapping
147 # {dst@mctx: src@wctx} copy mapping
148 return copies.pathcopies(wctx, mctx)
148 return copies.pathcopies(wctx, mctx)
149 pc = pathcopies()
149 pc = pathcopies()
150
150
151 for fn in wctx:
151 for fn in wctx:
152 fold = util.normcase(fn)
152 fold = util.normcase(fn)
153 mfn = folded.get(fold, None)
153 mfn = folded.get(fold, None)
154 if (mfn and mfn != fn and pc.map.get(mfn) != fn and
154 if (mfn and mfn != fn and pc.map.get(mfn) != fn and
155 _remains(fn, wctx.manifest(), actx.manifest(), True) and
155 _remains(fn, wctx.manifest(), actx.manifest(), True) and
156 _remains(mfn, mctx.manifest(), actx.manifest())):
156 _remains(mfn, mctx.manifest(), actx.manifest())):
157 raise util.Abort(_("case-folding collision between %s and %s")
157 raise util.Abort(_("case-folding collision between %s and %s")
158 % (mfn, fn))
158 % (mfn, fn))
159
159
160 def _forgetremoved(wctx, mctx, branchmerge):
160 def _forgetremoved(wctx, mctx, branchmerge):
161 """
161 """
162 Forget removed files
162 Forget removed files
163
163
164 If we're jumping between revisions (as opposed to merging), and if
164 If we're jumping between revisions (as opposed to merging), and if
165 neither the working directory nor the target rev has the file,
165 neither the working directory nor the target rev has the file,
166 then we need to remove it from the dirstate, to prevent the
166 then we need to remove it from the dirstate, to prevent the
167 dirstate from listing the file when it is no longer in the
167 dirstate from listing the file when it is no longer in the
168 manifest.
168 manifest.
169
169
170 If we're merging, and the other revision has removed a file
170 If we're merging, and the other revision has removed a file
171 that is not present in the working directory, we need to mark it
171 that is not present in the working directory, we need to mark it
172 as removed.
172 as removed.
173 """
173 """
174
174
175 actions = []
175 actions = []
176 state = branchmerge and 'r' or 'f'
176 state = branchmerge and 'r' or 'f'
177 for f in wctx.deleted():
177 for f in wctx.deleted():
178 if f not in mctx:
178 if f not in mctx:
179 actions.append((f, state, None, "forget deleted"))
179 actions.append((f, state, None, "forget deleted"))
180
180
181 if not branchmerge:
181 if not branchmerge:
182 for f in wctx.removed():
182 for f in wctx.removed():
183 if f not in mctx:
183 if f not in mctx:
184 actions.append((f, "f", None, "forget removed"))
184 actions.append((f, "f", None, "forget removed"))
185
185
186 return actions
186 return actions
187
187
188 def manifestmerge(repo, wctx, p2, pa, branchmerge, force, partial):
188 def manifestmerge(repo, wctx, p2, pa, branchmerge, force, partial):
189 """
189 """
190 Merge p1 and p2 with ancestor pa and generate merge action list
190 Merge p1 and p2 with ancestor pa and generate merge action list
191
191
192 branchmerge and force are as passed in to update
192 branchmerge and force are as passed in to update
193 partial = function to filter file lists
193 partial = function to filter file lists
194 """
194 """
195
195
196 overwrite = force and not branchmerge
196 overwrite = force and not branchmerge
197 actions, copy, movewithdir = [], {}, {}
197 actions, copy, movewithdir = [], {}, {}
198
198
199 if overwrite:
199 if overwrite:
200 pa = wctx
200 pa = wctx
201 elif pa == p2: # backwards
201 elif pa == p2: # backwards
202 pa = wctx.p1()
202 pa = wctx.p1()
203 elif not branchmerge and not wctx.dirty(missing=True):
204 pass
203 elif pa and repo.ui.configbool("merge", "followcopies", True):
205 elif pa and repo.ui.configbool("merge", "followcopies", True):
204 ret = copies.mergecopies(repo, wctx, p2, pa)
206 ret = copies.mergecopies(repo, wctx, p2, pa)
205 copy, movewithdir, diverge, renamedelete = ret
207 copy, movewithdir, diverge, renamedelete = ret
206 for of, fl in diverge.iteritems():
208 for of, fl in diverge.iteritems():
207 actions.append((of, "dr", (fl,), "divergent renames"))
209 actions.append((of, "dr", (fl,), "divergent renames"))
208 for of, fl in renamedelete.iteritems():
210 for of, fl in renamedelete.iteritems():
209 actions.append((of, "rd", (fl,), "rename and delete"))
211 actions.append((of, "rd", (fl,), "rename and delete"))
210
212
211 repo.ui.note(_("resolving manifests\n"))
213 repo.ui.note(_("resolving manifests\n"))
212 repo.ui.debug(" branchmerge: %s, force: %s, partial: %s\n"
214 repo.ui.debug(" branchmerge: %s, force: %s, partial: %s\n"
213 % (bool(branchmerge), bool(force), bool(partial)))
215 % (bool(branchmerge), bool(force), bool(partial)))
214 repo.ui.debug(" ancestor: %s, local: %s, remote: %s\n" % (pa, wctx, p2))
216 repo.ui.debug(" ancestor: %s, local: %s, remote: %s\n" % (pa, wctx, p2))
215
217
216 m1, m2, ma = wctx.manifest(), p2.manifest(), pa.manifest()
218 m1, m2, ma = wctx.manifest(), p2.manifest(), pa.manifest()
217 copied = set(copy.values())
219 copied = set(copy.values())
218 copied.update(movewithdir.values())
220 copied.update(movewithdir.values())
219
221
220 if '.hgsubstate' in m1:
222 if '.hgsubstate' in m1:
221 # check whether sub state is modified
223 # check whether sub state is modified
222 for s in sorted(wctx.substate):
224 for s in sorted(wctx.substate):
223 if wctx.sub(s).dirty():
225 if wctx.sub(s).dirty():
224 m1['.hgsubstate'] += "+"
226 m1['.hgsubstate'] += "+"
225 break
227 break
226
228
227 aborts, prompts = [], []
229 aborts, prompts = [], []
228 # Compare manifests
230 # Compare manifests
229 for f, n in m1.iteritems():
231 for f, n in m1.iteritems():
230 if partial and not partial(f):
232 if partial and not partial(f):
231 continue
233 continue
232 if f in m2:
234 if f in m2:
233 n2 = m2[f]
235 n2 = m2[f]
234 fl1, fl2, fla = m1.flags(f), m2.flags(f), ma.flags(f)
236 fl1, fl2, fla = m1.flags(f), m2.flags(f), ma.flags(f)
235 nol = 'l' not in fl1 + fl2 + fla
237 nol = 'l' not in fl1 + fl2 + fla
236 a = ma.get(f, nullid)
238 a = ma.get(f, nullid)
237 if n == n2 and fl1 == fl2:
239 if n == n2 and fl1 == fl2:
238 pass # same - keep local
240 pass # same - keep local
239 elif n2 == a and fl2 == fla:
241 elif n2 == a and fl2 == fla:
240 pass # remote unchanged - keep local
242 pass # remote unchanged - keep local
241 elif n == a and fl1 == fla: # local unchanged - use remote
243 elif n == a and fl1 == fla: # local unchanged - use remote
242 if n == n2: # optimization: keep local content
244 if n == n2: # optimization: keep local content
243 actions.append((f, "e", (fl2,), "update permissions"))
245 actions.append((f, "e", (fl2,), "update permissions"))
244 else:
246 else:
245 actions.append((f, "g", (fl2,), "remote is newer"))
247 actions.append((f, "g", (fl2,), "remote is newer"))
246 elif nol and n2 == a: # remote only changed 'x'
248 elif nol and n2 == a: # remote only changed 'x'
247 actions.append((f, "e", (fl2,), "update permissions"))
249 actions.append((f, "e", (fl2,), "update permissions"))
248 elif nol and n == a: # local only changed 'x'
250 elif nol and n == a: # local only changed 'x'
249 actions.append((f, "g", (fl1,), "remote is newer"))
251 actions.append((f, "g", (fl1,), "remote is newer"))
250 else: # both changed something
252 else: # both changed something
251 actions.append((f, "m", (f, f, False), "versions differ"))
253 actions.append((f, "m", (f, f, False), "versions differ"))
252 elif f in copied: # files we'll deal with on m2 side
254 elif f in copied: # files we'll deal with on m2 side
253 pass
255 pass
254 elif f in movewithdir: # directory rename
256 elif f in movewithdir: # directory rename
255 f2 = movewithdir[f]
257 f2 = movewithdir[f]
256 actions.append((f, "d", (None, f2, m1.flags(f)),
258 actions.append((f, "d", (None, f2, m1.flags(f)),
257 "remote renamed directory to " + f2))
259 "remote renamed directory to " + f2))
258 elif f in copy:
260 elif f in copy:
259 f2 = copy[f]
261 f2 = copy[f]
260 actions.append((f, "m", (f2, f, False),
262 actions.append((f, "m", (f2, f, False),
261 "local copied/moved to " + f2))
263 "local copied/moved to " + f2))
262 elif f in ma: # clean, a different, no remote
264 elif f in ma: # clean, a different, no remote
263 if n != ma[f]:
265 if n != ma[f]:
264 prompts.append((f, "cd")) # prompt changed/deleted
266 prompts.append((f, "cd")) # prompt changed/deleted
265 elif n[20:] == "a": # added, no remote
267 elif n[20:] == "a": # added, no remote
266 actions.append((f, "f", None, "remote deleted"))
268 actions.append((f, "f", None, "remote deleted"))
267 else:
269 else:
268 actions.append((f, "r", None, "other deleted"))
270 actions.append((f, "r", None, "other deleted"))
269
271
270 for f, n in m2.iteritems():
272 for f, n in m2.iteritems():
271 if partial and not partial(f):
273 if partial and not partial(f):
272 continue
274 continue
273 if f in m1 or f in copied: # files already visited
275 if f in m1 or f in copied: # files already visited
274 continue
276 continue
275 if f in movewithdir:
277 if f in movewithdir:
276 f2 = movewithdir[f]
278 f2 = movewithdir[f]
277 actions.append((None, "d", (f, f2, m2.flags(f)),
279 actions.append((None, "d", (f, f2, m2.flags(f)),
278 "local renamed directory to " + f2))
280 "local renamed directory to " + f2))
279 elif f in copy:
281 elif f in copy:
280 f2 = copy[f]
282 f2 = copy[f]
281 if f2 in m2:
283 if f2 in m2:
282 actions.append((f2, "m", (f, f, False),
284 actions.append((f2, "m", (f, f, False),
283 "remote copied to " + f))
285 "remote copied to " + f))
284 else:
286 else:
285 actions.append((f2, "m", (f, f, True),
287 actions.append((f2, "m", (f, f, True),
286 "remote moved to " + f))
288 "remote moved to " + f))
287 elif f not in ma:
289 elif f not in ma:
288 # local unknown, remote created: the logic is described by the
290 # local unknown, remote created: the logic is described by the
289 # following table:
291 # following table:
290 #
292 #
291 # force branchmerge different | action
293 # force branchmerge different | action
292 # n * n | get
294 # n * n | get
293 # n * y | abort
295 # n * y | abort
294 # y n * | get
296 # y n * | get
295 # y y n | get
297 # y y n | get
296 # y y y | merge
298 # y y y | merge
297 #
299 #
298 # Checking whether the files are different is expensive, so we
300 # Checking whether the files are different is expensive, so we
299 # don't do that when we can avoid it.
301 # don't do that when we can avoid it.
300 if force and not branchmerge:
302 if force and not branchmerge:
301 actions.append((f, "g", (m2.flags(f),), "remote created"))
303 actions.append((f, "g", (m2.flags(f),), "remote created"))
302 else:
304 else:
303 different = _checkunknownfile(repo, wctx, p2, f)
305 different = _checkunknownfile(repo, wctx, p2, f)
304 if force and branchmerge and different:
306 if force and branchmerge and different:
305 actions.append((f, "m", (f, f, False),
307 actions.append((f, "m", (f, f, False),
306 "remote differs from untracked local"))
308 "remote differs from untracked local"))
307 elif not force and different:
309 elif not force and different:
308 aborts.append((f, "ud"))
310 aborts.append((f, "ud"))
309 else:
311 else:
310 actions.append((f, "g", (m2.flags(f),), "remote created"))
312 actions.append((f, "g", (m2.flags(f),), "remote created"))
311 elif n != ma[f]:
313 elif n != ma[f]:
312 prompts.append((f, "dc")) # prompt deleted/changed
314 prompts.append((f, "dc")) # prompt deleted/changed
313
315
314 for f, m in sorted(aborts):
316 for f, m in sorted(aborts):
315 if m == "ud":
317 if m == "ud":
316 repo.ui.warn(_("%s: untracked file differs\n") % f)
318 repo.ui.warn(_("%s: untracked file differs\n") % f)
317 else: assert False, m
319 else: assert False, m
318 if aborts:
320 if aborts:
319 raise util.Abort(_("untracked files in working directory differ "
321 raise util.Abort(_("untracked files in working directory differ "
320 "from files in requested revision"))
322 "from files in requested revision"))
321
323
322 for f, m in sorted(prompts):
324 for f, m in sorted(prompts):
323 if m == "cd":
325 if m == "cd":
324 if repo.ui.promptchoice(
326 if repo.ui.promptchoice(
325 _("local changed %s which remote deleted\n"
327 _("local changed %s which remote deleted\n"
326 "use (c)hanged version or (d)elete?") % f,
328 "use (c)hanged version or (d)elete?") % f,
327 (_("&Changed"), _("&Delete")), 0):
329 (_("&Changed"), _("&Delete")), 0):
328 actions.append((f, "r", None, "prompt delete"))
330 actions.append((f, "r", None, "prompt delete"))
329 else:
331 else:
330 actions.append((f, "a", None, "prompt keep"))
332 actions.append((f, "a", None, "prompt keep"))
331 elif m == "dc":
333 elif m == "dc":
332 if repo.ui.promptchoice(
334 if repo.ui.promptchoice(
333 _("remote changed %s which local deleted\n"
335 _("remote changed %s which local deleted\n"
334 "use (c)hanged version or leave (d)eleted?") % f,
336 "use (c)hanged version or leave (d)eleted?") % f,
335 (_("&Changed"), _("&Deleted")), 0) == 0:
337 (_("&Changed"), _("&Deleted")), 0) == 0:
336 actions.append((f, "g", (m2.flags(f),), "prompt recreating"))
338 actions.append((f, "g", (m2.flags(f),), "prompt recreating"))
337 else: assert False, m
339 else: assert False, m
338 return actions
340 return actions
339
341
340 def actionkey(a):
342 def actionkey(a):
341 return a[1] == "r" and -1 or 0, a
343 return a[1] == "r" and -1 or 0, a
342
344
343 def applyupdates(repo, actions, wctx, mctx, actx, overwrite):
345 def applyupdates(repo, actions, wctx, mctx, actx, overwrite):
344 """apply the merge action list to the working directory
346 """apply the merge action list to the working directory
345
347
346 wctx is the working copy context
348 wctx is the working copy context
347 mctx is the context to be merged into the working copy
349 mctx is the context to be merged into the working copy
348 actx is the context of the common ancestor
350 actx is the context of the common ancestor
349
351
350 Return a tuple of counts (updated, merged, removed, unresolved) that
352 Return a tuple of counts (updated, merged, removed, unresolved) that
351 describes how many files were affected by the update.
353 describes how many files were affected by the update.
352 """
354 """
353
355
354 updated, merged, removed, unresolved = 0, 0, 0, 0
356 updated, merged, removed, unresolved = 0, 0, 0, 0
355 ms = mergestate(repo)
357 ms = mergestate(repo)
356 ms.reset(wctx.p1().node())
358 ms.reset(wctx.p1().node())
357 moves = []
359 moves = []
358 actions.sort(key=actionkey)
360 actions.sort(key=actionkey)
359
361
360 # prescan for merges
362 # prescan for merges
361 for a in actions:
363 for a in actions:
362 f, m, args, msg = a
364 f, m, args, msg = a
363 repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
365 repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
364 if m == "m": # merge
366 if m == "m": # merge
365 f2, fd, move = args
367 f2, fd, move = args
366 if fd == '.hgsubstate': # merged internally
368 if fd == '.hgsubstate': # merged internally
367 continue
369 continue
368 repo.ui.debug(" preserving %s for resolve of %s\n" % (f, fd))
370 repo.ui.debug(" preserving %s for resolve of %s\n" % (f, fd))
369 fcl = wctx[f]
371 fcl = wctx[f]
370 fco = mctx[f2]
372 fco = mctx[f2]
371 if mctx == actx: # backwards, use working dir parent as ancestor
373 if mctx == actx: # backwards, use working dir parent as ancestor
372 if fcl.parents():
374 if fcl.parents():
373 fca = fcl.p1()
375 fca = fcl.p1()
374 else:
376 else:
375 fca = repo.filectx(f, fileid=nullrev)
377 fca = repo.filectx(f, fileid=nullrev)
376 else:
378 else:
377 fca = fcl.ancestor(fco, actx)
379 fca = fcl.ancestor(fco, actx)
378 if not fca:
380 if not fca:
379 fca = repo.filectx(f, fileid=nullrev)
381 fca = repo.filectx(f, fileid=nullrev)
380 ms.add(fcl, fco, fca, fd)
382 ms.add(fcl, fco, fca, fd)
381 if f != fd and move:
383 if f != fd and move:
382 moves.append(f)
384 moves.append(f)
383
385
384 audit = repo.wopener.audit
386 audit = repo.wopener.audit
385
387
386 # remove renamed files after safely stored
388 # remove renamed files after safely stored
387 for f in moves:
389 for f in moves:
388 if os.path.lexists(repo.wjoin(f)):
390 if os.path.lexists(repo.wjoin(f)):
389 repo.ui.debug("removing %s\n" % f)
391 repo.ui.debug("removing %s\n" % f)
390 audit(f)
392 audit(f)
391 util.unlinkpath(repo.wjoin(f))
393 util.unlinkpath(repo.wjoin(f))
392
394
393 numupdates = len(actions)
395 numupdates = len(actions)
394 for i, a in enumerate(actions):
396 for i, a in enumerate(actions):
395 f, m, args, msg = a
397 f, m, args, msg = a
396 repo.ui.progress(_('updating'), i + 1, item=f, total=numupdates,
398 repo.ui.progress(_('updating'), i + 1, item=f, total=numupdates,
397 unit=_('files'))
399 unit=_('files'))
398 if m == "r": # remove
400 if m == "r": # remove
399 repo.ui.note(_("removing %s\n") % f)
401 repo.ui.note(_("removing %s\n") % f)
400 audit(f)
402 audit(f)
401 if f == '.hgsubstate': # subrepo states need updating
403 if f == '.hgsubstate': # subrepo states need updating
402 subrepo.submerge(repo, wctx, mctx, wctx, overwrite)
404 subrepo.submerge(repo, wctx, mctx, wctx, overwrite)
403 try:
405 try:
404 util.unlinkpath(repo.wjoin(f), ignoremissing=True)
406 util.unlinkpath(repo.wjoin(f), ignoremissing=True)
405 except OSError, inst:
407 except OSError, inst:
406 repo.ui.warn(_("update failed to remove %s: %s!\n") %
408 repo.ui.warn(_("update failed to remove %s: %s!\n") %
407 (f, inst.strerror))
409 (f, inst.strerror))
408 removed += 1
410 removed += 1
409 elif m == "m": # merge
411 elif m == "m": # merge
410 if fd == '.hgsubstate': # subrepo states need updating
412 if fd == '.hgsubstate': # subrepo states need updating
411 subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx),
413 subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx),
412 overwrite)
414 overwrite)
413 continue
415 continue
414 f2, fd, move = args
416 f2, fd, move = args
415 audit(fd)
417 audit(fd)
416 r = ms.resolve(fd, wctx, mctx)
418 r = ms.resolve(fd, wctx, mctx)
417 if r is not None and r > 0:
419 if r is not None and r > 0:
418 unresolved += 1
420 unresolved += 1
419 else:
421 else:
420 if r is None:
422 if r is None:
421 updated += 1
423 updated += 1
422 else:
424 else:
423 merged += 1
425 merged += 1
424 elif m == "g": # get
426 elif m == "g": # get
425 flags, = args
427 flags, = args
426 repo.ui.note(_("getting %s\n") % f)
428 repo.ui.note(_("getting %s\n") % f)
427 repo.wwrite(f, mctx.filectx(f).data(), flags)
429 repo.wwrite(f, mctx.filectx(f).data(), flags)
428 updated += 1
430 updated += 1
429 if f == '.hgsubstate': # subrepo states need updating
431 if f == '.hgsubstate': # subrepo states need updating
430 subrepo.submerge(repo, wctx, mctx, wctx, overwrite)
432 subrepo.submerge(repo, wctx, mctx, wctx, overwrite)
431 elif m == "d": # directory rename
433 elif m == "d": # directory rename
432 f2, fd, flags = args
434 f2, fd, flags = args
433 if f:
435 if f:
434 repo.ui.note(_("moving %s to %s\n") % (f, fd))
436 repo.ui.note(_("moving %s to %s\n") % (f, fd))
435 audit(f)
437 audit(f)
436 repo.wwrite(fd, wctx.filectx(f).data(), flags)
438 repo.wwrite(fd, wctx.filectx(f).data(), flags)
437 util.unlinkpath(repo.wjoin(f))
439 util.unlinkpath(repo.wjoin(f))
438 if f2:
440 if f2:
439 repo.ui.note(_("getting %s to %s\n") % (f2, fd))
441 repo.ui.note(_("getting %s to %s\n") % (f2, fd))
440 repo.wwrite(fd, mctx.filectx(f2).data(), flags)
442 repo.wwrite(fd, mctx.filectx(f2).data(), flags)
441 updated += 1
443 updated += 1
442 elif m == "dr": # divergent renames
444 elif m == "dr": # divergent renames
443 fl, = args
445 fl, = args
444 repo.ui.warn(_("note: possible conflict - %s was renamed "
446 repo.ui.warn(_("note: possible conflict - %s was renamed "
445 "multiple times to:\n") % f)
447 "multiple times to:\n") % f)
446 for nf in fl:
448 for nf in fl:
447 repo.ui.warn(" %s\n" % nf)
449 repo.ui.warn(" %s\n" % nf)
448 elif m == "rd": # rename and delete
450 elif m == "rd": # rename and delete
449 fl, = args
451 fl, = args
450 repo.ui.warn(_("note: possible conflict - %s was deleted "
452 repo.ui.warn(_("note: possible conflict - %s was deleted "
451 "and renamed to:\n") % f)
453 "and renamed to:\n") % f)
452 for nf in fl:
454 for nf in fl:
453 repo.ui.warn(" %s\n" % nf)
455 repo.ui.warn(" %s\n" % nf)
454 elif m == "e": # exec
456 elif m == "e": # exec
455 flags, = args
457 flags, = args
456 audit(f)
458 audit(f)
457 util.setflags(repo.wjoin(f), 'l' in flags, 'x' in flags)
459 util.setflags(repo.wjoin(f), 'l' in flags, 'x' in flags)
458 updated += 1
460 updated += 1
459 ms.commit()
461 ms.commit()
460 repo.ui.progress(_('updating'), None, total=numupdates, unit=_('files'))
462 repo.ui.progress(_('updating'), None, total=numupdates, unit=_('files'))
461
463
462 return updated, merged, removed, unresolved
464 return updated, merged, removed, unresolved
463
465
464 def calculateupdates(repo, tctx, mctx, ancestor, branchmerge, force, partial):
466 def calculateupdates(repo, tctx, mctx, ancestor, branchmerge, force, partial):
465 "Calculate the actions needed to merge mctx into tctx"
467 "Calculate the actions needed to merge mctx into tctx"
466 actions = []
468 actions = []
467 folding = not util.checkcase(repo.path)
469 folding = not util.checkcase(repo.path)
468 if folding:
470 if folding:
469 # collision check is not needed for clean update
471 # collision check is not needed for clean update
470 if (not branchmerge and
472 if (not branchmerge and
471 (force or not tctx.dirty(missing=True, branch=False))):
473 (force or not tctx.dirty(missing=True, branch=False))):
472 _checkcollision(mctx, None)
474 _checkcollision(mctx, None)
473 else:
475 else:
474 _checkcollision(mctx, (tctx, ancestor))
476 _checkcollision(mctx, (tctx, ancestor))
475 if tctx.rev() is None:
477 if tctx.rev() is None:
476 actions += _forgetremoved(tctx, mctx, branchmerge)
478 actions += _forgetremoved(tctx, mctx, branchmerge)
477 actions += manifestmerge(repo, tctx, mctx,
479 actions += manifestmerge(repo, tctx, mctx,
478 ancestor,
480 ancestor,
479 branchmerge, force,
481 branchmerge, force,
480 partial)
482 partial)
481 return actions
483 return actions
482
484
483 def recordupdates(repo, actions, branchmerge):
485 def recordupdates(repo, actions, branchmerge):
484 "record merge actions to the dirstate"
486 "record merge actions to the dirstate"
485
487
486 for a in actions:
488 for a in actions:
487 f, m, args, msg = a
489 f, m, args, msg = a
488 if m == "r": # remove
490 if m == "r": # remove
489 if branchmerge:
491 if branchmerge:
490 repo.dirstate.remove(f)
492 repo.dirstate.remove(f)
491 else:
493 else:
492 repo.dirstate.drop(f)
494 repo.dirstate.drop(f)
493 elif m == "a": # re-add
495 elif m == "a": # re-add
494 if not branchmerge:
496 if not branchmerge:
495 repo.dirstate.add(f)
497 repo.dirstate.add(f)
496 elif m == "f": # forget
498 elif m == "f": # forget
497 repo.dirstate.drop(f)
499 repo.dirstate.drop(f)
498 elif m == "e": # exec change
500 elif m == "e": # exec change
499 repo.dirstate.normallookup(f)
501 repo.dirstate.normallookup(f)
500 elif m == "g": # get
502 elif m == "g": # get
501 if branchmerge:
503 if branchmerge:
502 repo.dirstate.otherparent(f)
504 repo.dirstate.otherparent(f)
503 else:
505 else:
504 repo.dirstate.normal(f)
506 repo.dirstate.normal(f)
505 elif m == "m": # merge
507 elif m == "m": # merge
506 f2, fd, move = args
508 f2, fd, move = args
507 if branchmerge:
509 if branchmerge:
508 # We've done a branch merge, mark this file as merged
510 # We've done a branch merge, mark this file as merged
509 # so that we properly record the merger later
511 # so that we properly record the merger later
510 repo.dirstate.merge(fd)
512 repo.dirstate.merge(fd)
511 if f != f2: # copy/rename
513 if f != f2: # copy/rename
512 if move:
514 if move:
513 repo.dirstate.remove(f)
515 repo.dirstate.remove(f)
514 if f != fd:
516 if f != fd:
515 repo.dirstate.copy(f, fd)
517 repo.dirstate.copy(f, fd)
516 else:
518 else:
517 repo.dirstate.copy(f2, fd)
519 repo.dirstate.copy(f2, fd)
518 else:
520 else:
519 # We've update-merged a locally modified file, so
521 # We've update-merged a locally modified file, so
520 # we set the dirstate to emulate a normal checkout
522 # we set the dirstate to emulate a normal checkout
521 # of that file some time in the past. Thus our
523 # of that file some time in the past. Thus our
522 # merge will appear as a normal local file
524 # merge will appear as a normal local file
523 # modification.
525 # modification.
524 if f2 == fd: # file not locally copied/moved
526 if f2 == fd: # file not locally copied/moved
525 repo.dirstate.normallookup(fd)
527 repo.dirstate.normallookup(fd)
526 if move:
528 if move:
527 repo.dirstate.drop(f)
529 repo.dirstate.drop(f)
528 elif m == "d": # directory rename
530 elif m == "d": # directory rename
529 f2, fd, flag = args
531 f2, fd, flag = args
530 if not f2 and f not in repo.dirstate:
532 if not f2 and f not in repo.dirstate:
531 # untracked file moved
533 # untracked file moved
532 continue
534 continue
533 if branchmerge:
535 if branchmerge:
534 repo.dirstate.add(fd)
536 repo.dirstate.add(fd)
535 if f:
537 if f:
536 repo.dirstate.remove(f)
538 repo.dirstate.remove(f)
537 repo.dirstate.copy(f, fd)
539 repo.dirstate.copy(f, fd)
538 if f2:
540 if f2:
539 repo.dirstate.copy(f2, fd)
541 repo.dirstate.copy(f2, fd)
540 else:
542 else:
541 repo.dirstate.normal(fd)
543 repo.dirstate.normal(fd)
542 if f:
544 if f:
543 repo.dirstate.drop(f)
545 repo.dirstate.drop(f)
544
546
545 def update(repo, node, branchmerge, force, partial, ancestor=None,
547 def update(repo, node, branchmerge, force, partial, ancestor=None,
546 mergeancestor=False):
548 mergeancestor=False):
547 """
549 """
548 Perform a merge between the working directory and the given node
550 Perform a merge between the working directory and the given node
549
551
550 node = the node to update to, or None if unspecified
552 node = the node to update to, or None if unspecified
551 branchmerge = whether to merge between branches
553 branchmerge = whether to merge between branches
552 force = whether to force branch merging or file overwriting
554 force = whether to force branch merging or file overwriting
553 partial = a function to filter file lists (dirstate not updated)
555 partial = a function to filter file lists (dirstate not updated)
554 mergeancestor = if false, merging with an ancestor (fast-forward)
556 mergeancestor = if false, merging with an ancestor (fast-forward)
555 is only allowed between different named branches. This flag
557 is only allowed between different named branches. This flag
556 is used by rebase extension as a temporary fix and should be
558 is used by rebase extension as a temporary fix and should be
557 avoided in general.
559 avoided in general.
558
560
559 The table below shows all the behaviors of the update command
561 The table below shows all the behaviors of the update command
560 given the -c and -C or no options, whether the working directory
562 given the -c and -C or no options, whether the working directory
561 is dirty, whether a revision is specified, and the relationship of
563 is dirty, whether a revision is specified, and the relationship of
562 the parent rev to the target rev (linear, on the same named
564 the parent rev to the target rev (linear, on the same named
563 branch, or on another named branch).
565 branch, or on another named branch).
564
566
565 This logic is tested by test-update-branches.t.
567 This logic is tested by test-update-branches.t.
566
568
567 -c -C dirty rev | linear same cross
569 -c -C dirty rev | linear same cross
568 n n n n | ok (1) x
570 n n n n | ok (1) x
569 n n n y | ok ok ok
571 n n n y | ok ok ok
570 n n y * | merge (2) (2)
572 n n y * | merge (2) (2)
571 n y * * | --- discard ---
573 n y * * | --- discard ---
572 y n y * | --- (3) ---
574 y n y * | --- (3) ---
573 y n n * | --- ok ---
575 y n n * | --- ok ---
574 y y * * | --- (4) ---
576 y y * * | --- (4) ---
575
577
576 x = can't happen
578 x = can't happen
577 * = don't-care
579 * = don't-care
578 1 = abort: crosses branches (use 'hg merge' or 'hg update -c')
580 1 = abort: crosses branches (use 'hg merge' or 'hg update -c')
579 2 = abort: crosses branches (use 'hg merge' to merge or
581 2 = abort: crosses branches (use 'hg merge' to merge or
580 use 'hg update -C' to discard changes)
582 use 'hg update -C' to discard changes)
581 3 = abort: uncommitted local changes
583 3 = abort: uncommitted local changes
582 4 = incompatible options (checked in commands.py)
584 4 = incompatible options (checked in commands.py)
583
585
584 Return the same tuple as applyupdates().
586 Return the same tuple as applyupdates().
585 """
587 """
586
588
587 onode = node
589 onode = node
588 wlock = repo.wlock()
590 wlock = repo.wlock()
589 try:
591 try:
590 wc = repo[None]
592 wc = repo[None]
591 if node is None:
593 if node is None:
592 # tip of current branch
594 # tip of current branch
593 try:
595 try:
594 node = repo.branchtip(wc.branch())
596 node = repo.branchtip(wc.branch())
595 except error.RepoLookupError:
597 except error.RepoLookupError:
596 if wc.branch() == "default": # no default branch!
598 if wc.branch() == "default": # no default branch!
597 node = repo.lookup("tip") # update to tip
599 node = repo.lookup("tip") # update to tip
598 else:
600 else:
599 raise util.Abort(_("branch %s not found") % wc.branch())
601 raise util.Abort(_("branch %s not found") % wc.branch())
600 overwrite = force and not branchmerge
602 overwrite = force and not branchmerge
601 pl = wc.parents()
603 pl = wc.parents()
602 p1, p2 = pl[0], repo[node]
604 p1, p2 = pl[0], repo[node]
603 if ancestor:
605 if ancestor:
604 pa = repo[ancestor]
606 pa = repo[ancestor]
605 else:
607 else:
606 pa = p1.ancestor(p2)
608 pa = p1.ancestor(p2)
607
609
608 fp1, fp2, xp1, xp2 = p1.node(), p2.node(), str(p1), str(p2)
610 fp1, fp2, xp1, xp2 = p1.node(), p2.node(), str(p1), str(p2)
609
611
610 ### check phase
612 ### check phase
611 if not overwrite and len(pl) > 1:
613 if not overwrite and len(pl) > 1:
612 raise util.Abort(_("outstanding uncommitted merges"))
614 raise util.Abort(_("outstanding uncommitted merges"))
613 if branchmerge:
615 if branchmerge:
614 if pa == p2:
616 if pa == p2:
615 raise util.Abort(_("merging with a working directory ancestor"
617 raise util.Abort(_("merging with a working directory ancestor"
616 " has no effect"))
618 " has no effect"))
617 elif pa == p1:
619 elif pa == p1:
618 if not mergeancestor and p1.branch() == p2.branch():
620 if not mergeancestor and p1.branch() == p2.branch():
619 raise util.Abort(_("nothing to merge"),
621 raise util.Abort(_("nothing to merge"),
620 hint=_("use 'hg update' "
622 hint=_("use 'hg update' "
621 "or check 'hg heads'"))
623 "or check 'hg heads'"))
622 if not force and (wc.files() or wc.deleted()):
624 if not force and (wc.files() or wc.deleted()):
623 raise util.Abort(_("outstanding uncommitted changes"),
625 raise util.Abort(_("outstanding uncommitted changes"),
624 hint=_("use 'hg status' to list changes"))
626 hint=_("use 'hg status' to list changes"))
625 for s in sorted(wc.substate):
627 for s in sorted(wc.substate):
626 if wc.sub(s).dirty():
628 if wc.sub(s).dirty():
627 raise util.Abort(_("outstanding uncommitted changes in "
629 raise util.Abort(_("outstanding uncommitted changes in "
628 "subrepository '%s'") % s)
630 "subrepository '%s'") % s)
629
631
630 elif not overwrite:
632 elif not overwrite:
631 if pa == p1 or pa == p2: # linear
633 if pa == p1 or pa == p2: # linear
632 pass # all good
634 pass # all good
633 elif wc.dirty(missing=True):
635 elif wc.dirty(missing=True):
634 raise util.Abort(_("crosses branches (merge branches or use"
636 raise util.Abort(_("crosses branches (merge branches or use"
635 " --clean to discard changes)"))
637 " --clean to discard changes)"))
636 elif onode is None:
638 elif onode is None:
637 raise util.Abort(_("crosses branches (merge branches or update"
639 raise util.Abort(_("crosses branches (merge branches or update"
638 " --check to force update)"))
640 " --check to force update)"))
639 else:
641 else:
640 # Allow jumping branches if clean and specific rev given
642 # Allow jumping branches if clean and specific rev given
641 pa = p1
643 pa = p1
642
644
643 ### calculate phase
645 ### calculate phase
644 actions = calculateupdates(repo, wc, p2, pa,
646 actions = calculateupdates(repo, wc, p2, pa,
645 branchmerge, force, partial)
647 branchmerge, force, partial)
646
648
647 ### apply phase
649 ### apply phase
648 if not branchmerge: # just jump to the new rev
650 if not branchmerge: # just jump to the new rev
649 fp1, fp2, xp1, xp2 = fp2, nullid, xp2, ''
651 fp1, fp2, xp1, xp2 = fp2, nullid, xp2, ''
650 if not partial:
652 if not partial:
651 repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
653 repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
652
654
653 stats = applyupdates(repo, actions, wc, p2, pa, overwrite)
655 stats = applyupdates(repo, actions, wc, p2, pa, overwrite)
654
656
655 if not partial:
657 if not partial:
656 repo.setparents(fp1, fp2)
658 repo.setparents(fp1, fp2)
657 recordupdates(repo, actions, branchmerge)
659 recordupdates(repo, actions, branchmerge)
658 if not branchmerge:
660 if not branchmerge:
659 repo.dirstate.setbranch(p2.branch())
661 repo.dirstate.setbranch(p2.branch())
660 finally:
662 finally:
661 wlock.release()
663 wlock.release()
662
664
663 if not partial:
665 if not partial:
664 repo.hook('update', parent1=xp1, parent2=xp2, error=stats[3])
666 repo.hook('update', parent1=xp1, parent2=xp2, error=stats[3])
665 return stats
667 return stats
@@ -1,1088 +1,1087 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 ci -Ams0
28 $ hg -R s ci -Ams0
29 adding a
29 adding a
30 $ hg sum
30 $ hg sum
31 parent: 0:f7b1eb17ad24 tip
31 parent: 0:f7b1eb17ad24 tip
32 0
32 0
33 branch: default
33 branch: default
34 commit: 1 added, 1 subrepos
34 commit: 1 added, 1 subrepos
35 update: (current)
35 update: (current)
36 $ hg ci -m1
36 $ hg ci -m1
37
37
38 Revert subrepo and test subrepo fileset keyword:
38 Revert subrepo and test subrepo fileset keyword:
39
39
40 $ echo b > s/a
40 $ echo b > s/a
41 $ hg revert "set:subrepo('glob:s*')"
41 $ hg revert "set:subrepo('glob:s*')"
42 reverting subrepo s
42 reverting subrepo s
43 reverting s/a (glob)
43 reverting s/a (glob)
44 $ rm s/a.orig
44 $ rm s/a.orig
45
45
46 Revert subrepo with no backup. The "reverting s/a" line is gone since
46 Revert subrepo with no backup. The "reverting s/a" line is gone since
47 we're really running 'hg update' in the subrepo:
47 we're really running 'hg update' in the subrepo:
48
48
49 $ echo b > s/a
49 $ echo b > s/a
50 $ hg revert --no-backup s
50 $ hg revert --no-backup s
51 reverting subrepo s
51 reverting subrepo s
52
52
53 Issue2022: update -C
53 Issue2022: update -C
54
54
55 $ echo b > s/a
55 $ echo b > s/a
56 $ hg sum
56 $ hg sum
57 parent: 1:7cf8cfea66e4 tip
57 parent: 1:7cf8cfea66e4 tip
58 1
58 1
59 branch: default
59 branch: default
60 commit: 1 subrepos
60 commit: 1 subrepos
61 update: (current)
61 update: (current)
62 $ hg co -C 1
62 $ hg co -C 1
63 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
63 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
64 $ hg sum
64 $ hg sum
65 parent: 1:7cf8cfea66e4 tip
65 parent: 1:7cf8cfea66e4 tip
66 1
66 1
67 branch: default
67 branch: default
68 commit: (clean)
68 commit: (clean)
69 update: (current)
69 update: (current)
70
70
71 commands that require a clean repo should respect subrepos
71 commands that require a clean repo should respect subrepos
72
72
73 $ echo b >> s/a
73 $ echo b >> s/a
74 $ hg backout tip
74 $ hg backout tip
75 abort: uncommitted changes in subrepo s
75 abort: uncommitted changes in subrepo s
76 [255]
76 [255]
77 $ hg revert -C -R s s/a
77 $ hg revert -C -R s s/a
78
78
79 add sub sub
79 add sub sub
80
80
81 $ echo ss = ss > s/.hgsub
81 $ echo ss = ss > s/.hgsub
82 $ hg init s/ss
82 $ hg init s/ss
83 $ echo a > s/ss/a
83 $ echo a > s/ss/a
84 $ hg -R s add s/.hgsub
84 $ hg -R s add s/.hgsub
85 $ hg -R s/ss add s/ss/a
85 $ hg -R s/ss add s/ss/a
86 $ hg sum
86 $ hg sum
87 parent: 1:7cf8cfea66e4 tip
87 parent: 1:7cf8cfea66e4 tip
88 1
88 1
89 branch: default
89 branch: default
90 commit: 1 subrepos
90 commit: 1 subrepos
91 update: (current)
91 update: (current)
92 $ hg ci -m2
92 $ hg ci -m2
93 committing subrepository s
93 committing subrepository s
94 committing subrepository s/ss (glob)
94 committing subrepository s/ss (glob)
95 $ hg sum
95 $ hg sum
96 parent: 2:df30734270ae tip
96 parent: 2:df30734270ae tip
97 2
97 2
98 branch: default
98 branch: default
99 commit: (clean)
99 commit: (clean)
100 update: (current)
100 update: (current)
101
101
102 bump sub rev (and check it is ignored by ui.commitsubrepos)
102 bump sub rev (and check it is ignored by ui.commitsubrepos)
103
103
104 $ echo b > s/a
104 $ echo b > s/a
105 $ hg -R s ci -ms1
105 $ hg -R s ci -ms1
106 $ hg --config ui.commitsubrepos=no ci -m3
106 $ hg --config ui.commitsubrepos=no ci -m3
107
107
108 leave sub dirty (and check ui.commitsubrepos=no aborts the commit)
108 leave sub dirty (and check ui.commitsubrepos=no aborts the commit)
109
109
110 $ echo c > s/a
110 $ echo c > s/a
111 $ hg --config ui.commitsubrepos=no ci -m4
111 $ hg --config ui.commitsubrepos=no ci -m4
112 abort: uncommitted changes in subrepo s
112 abort: uncommitted changes in subrepo s
113 (use --subrepos for recursive commit)
113 (use --subrepos for recursive commit)
114 [255]
114 [255]
115 $ hg id
115 $ hg id
116 f6affe3fbfaa+ tip
116 f6affe3fbfaa+ tip
117 $ hg -R s ci -mc
117 $ hg -R s ci -mc
118 $ hg id
118 $ hg id
119 f6affe3fbfaa+ tip
119 f6affe3fbfaa+ tip
120 $ echo d > s/a
120 $ echo d > s/a
121 $ hg ci -m4
121 $ hg ci -m4
122 committing subrepository s
122 committing subrepository s
123 $ hg tip -R s
123 $ hg tip -R s
124 changeset: 4:02dcf1d70411
124 changeset: 4:02dcf1d70411
125 tag: tip
125 tag: tip
126 user: test
126 user: test
127 date: Thu Jan 01 00:00:00 1970 +0000
127 date: Thu Jan 01 00:00:00 1970 +0000
128 summary: 4
128 summary: 4
129
129
130
130
131 check caching
131 check caching
132
132
133 $ hg co 0
133 $ hg co 0
134 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
134 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
135 $ hg debugsub
135 $ hg debugsub
136
136
137 restore
137 restore
138
138
139 $ hg co
139 $ hg co
140 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
140 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
141 $ hg debugsub
141 $ hg debugsub
142 path s
142 path s
143 source s
143 source s
144 revision 02dcf1d704118aee3ee306ccfa1910850d5b05ef
144 revision 02dcf1d704118aee3ee306ccfa1910850d5b05ef
145
145
146 new branch for merge tests
146 new branch for merge tests
147
147
148 $ hg co 1
148 $ hg co 1
149 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
149 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
150 $ echo t = t >> .hgsub
150 $ echo t = t >> .hgsub
151 $ hg init t
151 $ hg init t
152 $ echo t > t/t
152 $ echo t > t/t
153 $ hg -R t add t
153 $ hg -R t add t
154 adding t/t (glob)
154 adding t/t (glob)
155
155
156 5
156 5
157
157
158 $ hg ci -m5 # add sub
158 $ hg ci -m5 # add sub
159 committing subrepository t
159 committing subrepository t
160 created new head
160 created new head
161 $ echo t2 > t/t
161 $ echo t2 > t/t
162
162
163 6
163 6
164
164
165 $ hg st -R s
165 $ hg st -R s
166 $ hg ci -m6 # change sub
166 $ hg ci -m6 # change sub
167 committing subrepository t
167 committing subrepository t
168 $ hg debugsub
168 $ hg debugsub
169 path s
169 path s
170 source s
170 source s
171 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
171 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
172 path t
172 path t
173 source t
173 source t
174 revision 6747d179aa9a688023c4b0cad32e4c92bb7f34ad
174 revision 6747d179aa9a688023c4b0cad32e4c92bb7f34ad
175 $ echo t3 > t/t
175 $ echo t3 > t/t
176
176
177 7
177 7
178
178
179 $ hg ci -m7 # change sub again for conflict test
179 $ hg ci -m7 # change sub again for conflict test
180 committing subrepository t
180 committing subrepository t
181 $ hg rm .hgsub
181 $ hg rm .hgsub
182
182
183 8
183 8
184
184
185 $ hg ci -m8 # remove sub
185 $ hg ci -m8 # remove sub
186
186
187 merge tests
187 merge tests
188
188
189 $ hg co -C 3
189 $ hg co -C 3
190 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
190 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
191 $ hg merge 5 # test adding
191 $ hg merge 5 # test adding
192 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
192 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
193 (branch merge, don't forget to commit)
193 (branch merge, don't forget to commit)
194 $ hg debugsub
194 $ hg debugsub
195 path s
195 path s
196 source s
196 source s
197 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
197 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
198 path t
198 path t
199 source t
199 source t
200 revision 60ca1237c19474e7a3978b0dc1ca4e6f36d51382
200 revision 60ca1237c19474e7a3978b0dc1ca4e6f36d51382
201 $ hg ci -m9
201 $ hg ci -m9
202 created new head
202 created new head
203 $ hg merge 6 --debug # test change
203 $ hg merge 6 --debug # test change
204 searching for copies back to rev 2
204 searching for copies back to rev 2
205 resolving manifests
205 resolving manifests
206 branchmerge: True, force: False, partial: False
206 branchmerge: True, force: False, partial: False
207 ancestor: 1f14a2e2d3ec, local: f0d2028bf86d+, remote: 1831e14459c4
207 ancestor: 1f14a2e2d3ec, local: f0d2028bf86d+, remote: 1831e14459c4
208 .hgsubstate: versions differ -> m
208 .hgsubstate: versions differ -> m
209 updating: .hgsubstate 1/1 files (100.00%)
209 updating: .hgsubstate 1/1 files (100.00%)
210 subrepo merge f0d2028bf86d+ 1831e14459c4 1f14a2e2d3ec
210 subrepo merge f0d2028bf86d+ 1831e14459c4 1f14a2e2d3ec
211 subrepo t: other changed, get t:6747d179aa9a688023c4b0cad32e4c92bb7f34ad:hg
211 subrepo t: other changed, get t:6747d179aa9a688023c4b0cad32e4c92bb7f34ad:hg
212 getting subrepo t
212 getting subrepo t
213 searching for copies back to rev 1
214 resolving manifests
213 resolving manifests
215 branchmerge: False, force: False, partial: False
214 branchmerge: False, force: False, partial: False
216 ancestor: 60ca1237c194, local: 60ca1237c194+, remote: 6747d179aa9a
215 ancestor: 60ca1237c194, local: 60ca1237c194+, remote: 6747d179aa9a
217 t: remote is newer -> g
216 t: remote is newer -> g
218 updating: t 1/1 files (100.00%)
217 updating: t 1/1 files (100.00%)
219 getting t
218 getting t
220 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
219 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
221 (branch merge, don't forget to commit)
220 (branch merge, don't forget to commit)
222 $ hg debugsub
221 $ hg debugsub
223 path s
222 path s
224 source s
223 source s
225 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
224 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
226 path t
225 path t
227 source t
226 source t
228 revision 6747d179aa9a688023c4b0cad32e4c92bb7f34ad
227 revision 6747d179aa9a688023c4b0cad32e4c92bb7f34ad
229 $ echo conflict > t/t
228 $ echo conflict > t/t
230 $ hg ci -m10
229 $ hg ci -m10
231 committing subrepository t
230 committing subrepository t
232 $ HGMERGE=internal:merge hg merge --debug 7 # test conflict
231 $ HGMERGE=internal:merge hg merge --debug 7 # test conflict
233 searching for copies back to rev 2
232 searching for copies back to rev 2
234 resolving manifests
233 resolving manifests
235 branchmerge: True, force: False, partial: False
234 branchmerge: True, force: False, partial: False
236 ancestor: 1831e14459c4, local: e45c8b14af55+, remote: f94576341bcf
235 ancestor: 1831e14459c4, local: e45c8b14af55+, remote: f94576341bcf
237 .hgsubstate: versions differ -> m
236 .hgsubstate: versions differ -> m
238 updating: .hgsubstate 1/1 files (100.00%)
237 updating: .hgsubstate 1/1 files (100.00%)
239 subrepo merge e45c8b14af55+ f94576341bcf 1831e14459c4
238 subrepo merge e45c8b14af55+ f94576341bcf 1831e14459c4
240 subrepo t: both sides changed, merge with t:7af322bc1198a32402fe903e0b7ebcfc5c9bf8f4:hg
239 subrepo t: both sides changed, merge with t:7af322bc1198a32402fe903e0b7ebcfc5c9bf8f4:hg
241 merging subrepo t
240 merging subrepo t
242 searching for copies back to rev 2
241 searching for copies back to rev 2
243 resolving manifests
242 resolving manifests
244 branchmerge: True, force: False, partial: False
243 branchmerge: True, force: False, partial: False
245 ancestor: 6747d179aa9a, local: 20a0db6fbf6c+, remote: 7af322bc1198
244 ancestor: 6747d179aa9a, local: 20a0db6fbf6c+, remote: 7af322bc1198
246 t: versions differ -> m
245 t: versions differ -> m
247 preserving t for resolve of t
246 preserving t for resolve of t
248 updating: t 1/1 files (100.00%)
247 updating: t 1/1 files (100.00%)
249 picked tool 'internal:merge' for t (binary False symlink False)
248 picked tool 'internal:merge' for t (binary False symlink False)
250 merging t
249 merging t
251 my t@20a0db6fbf6c+ other t@7af322bc1198 ancestor t@6747d179aa9a
250 my t@20a0db6fbf6c+ other t@7af322bc1198 ancestor t@6747d179aa9a
252 warning: conflicts during merge.
251 warning: conflicts during merge.
253 merging t incomplete! (edit conflicts, then use 'hg resolve --mark')
252 merging t incomplete! (edit conflicts, then use 'hg resolve --mark')
254 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
253 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
255 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
254 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
256 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
255 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
257 (branch merge, don't forget to commit)
256 (branch merge, don't forget to commit)
258
257
259 should conflict
258 should conflict
260
259
261 $ cat t/t
260 $ cat t/t
262 <<<<<<< local
261 <<<<<<< local
263 conflict
262 conflict
264 =======
263 =======
265 t3
264 t3
266 >>>>>>> other
265 >>>>>>> other
267
266
268 clone
267 clone
269
268
270 $ cd ..
269 $ cd ..
271 $ hg clone t tc
270 $ hg clone t tc
272 updating to branch default
271 updating to branch default
273 cloning subrepo s from $TESTTMP/t/s (glob)
272 cloning subrepo s from $TESTTMP/t/s (glob)
274 cloning subrepo s/ss from $TESTTMP/t/s/ss (glob)
273 cloning subrepo s/ss from $TESTTMP/t/s/ss (glob)
275 cloning subrepo t from $TESTTMP/t/t (glob)
274 cloning subrepo t from $TESTTMP/t/t (glob)
276 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
275 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
277 $ cd tc
276 $ cd tc
278 $ hg debugsub
277 $ hg debugsub
279 path s
278 path s
280 source s
279 source s
281 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
280 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
282 path t
281 path t
283 source t
282 source t
284 revision 20a0db6fbf6c3d2836e6519a642ae929bfc67c0e
283 revision 20a0db6fbf6c3d2836e6519a642ae929bfc67c0e
285
284
286 push
285 push
287
286
288 $ echo bah > t/t
287 $ echo bah > t/t
289 $ hg ci -m11
288 $ hg ci -m11
290 committing subrepository t
289 committing subrepository t
291 $ hg push
290 $ hg push
292 pushing to $TESTTMP/t (glob)
291 pushing to $TESTTMP/t (glob)
293 pushing subrepo s/ss to $TESTTMP/t/s/ss (glob)
292 pushing subrepo s/ss to $TESTTMP/t/s/ss (glob)
294 searching for changes
293 searching for changes
295 no changes found
294 no changes found
296 pushing subrepo s to $TESTTMP/t/s (glob)
295 pushing subrepo s to $TESTTMP/t/s (glob)
297 searching for changes
296 searching for changes
298 no changes found
297 no changes found
299 pushing subrepo t to $TESTTMP/t/t (glob)
298 pushing subrepo t to $TESTTMP/t/t (glob)
300 searching for changes
299 searching for changes
301 adding changesets
300 adding changesets
302 adding manifests
301 adding manifests
303 adding file changes
302 adding file changes
304 added 1 changesets with 1 changes to 1 files
303 added 1 changesets with 1 changes to 1 files
305 searching for changes
304 searching for changes
306 adding changesets
305 adding changesets
307 adding manifests
306 adding manifests
308 adding file changes
307 adding file changes
309 added 1 changesets with 1 changes to 1 files
308 added 1 changesets with 1 changes to 1 files
310
309
311 push -f
310 push -f
312
311
313 $ echo bah > s/a
312 $ echo bah > s/a
314 $ hg ci -m12
313 $ hg ci -m12
315 committing subrepository s
314 committing subrepository s
316 $ hg push
315 $ hg push
317 pushing to $TESTTMP/t (glob)
316 pushing to $TESTTMP/t (glob)
318 pushing subrepo s/ss to $TESTTMP/t/s/ss (glob)
317 pushing subrepo s/ss to $TESTTMP/t/s/ss (glob)
319 searching for changes
318 searching for changes
320 no changes found
319 no changes found
321 pushing subrepo s to $TESTTMP/t/s (glob)
320 pushing subrepo s to $TESTTMP/t/s (glob)
322 searching for changes
321 searching for changes
323 abort: push creates new remote head 12a213df6fa9! (in subrepo s)
322 abort: push creates new remote head 12a213df6fa9! (in subrepo s)
324 (did you forget to merge? use push -f to force)
323 (did you forget to merge? use push -f to force)
325 [255]
324 [255]
326 $ hg push -f
325 $ hg push -f
327 pushing to $TESTTMP/t (glob)
326 pushing to $TESTTMP/t (glob)
328 pushing subrepo s/ss to $TESTTMP/t/s/ss (glob)
327 pushing subrepo s/ss to $TESTTMP/t/s/ss (glob)
329 searching for changes
328 searching for changes
330 no changes found
329 no changes found
331 pushing subrepo s to $TESTTMP/t/s (glob)
330 pushing subrepo s to $TESTTMP/t/s (glob)
332 searching for changes
331 searching for changes
333 adding changesets
332 adding changesets
334 adding manifests
333 adding manifests
335 adding file changes
334 adding file changes
336 added 1 changesets with 1 changes to 1 files (+1 heads)
335 added 1 changesets with 1 changes to 1 files (+1 heads)
337 pushing subrepo t to $TESTTMP/t/t (glob)
336 pushing subrepo t to $TESTTMP/t/t (glob)
338 searching for changes
337 searching for changes
339 no changes found
338 no changes found
340 searching for changes
339 searching for changes
341 adding changesets
340 adding changesets
342 adding manifests
341 adding manifests
343 adding file changes
342 adding file changes
344 added 1 changesets with 1 changes to 1 files
343 added 1 changesets with 1 changes to 1 files
345
344
346 update
345 update
347
346
348 $ cd ../t
347 $ cd ../t
349 $ hg up -C # discard our earlier merge
348 $ hg up -C # discard our earlier merge
350 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
349 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
351 $ echo blah > t/t
350 $ echo blah > t/t
352 $ hg ci -m13
351 $ hg ci -m13
353 committing subrepository t
352 committing subrepository t
354
353
355 pull
354 pull
356
355
357 $ cd ../tc
356 $ cd ../tc
358 $ hg pull
357 $ hg pull
359 pulling from $TESTTMP/t (glob)
358 pulling from $TESTTMP/t (glob)
360 searching for changes
359 searching for changes
361 adding changesets
360 adding changesets
362 adding manifests
361 adding manifests
363 adding file changes
362 adding file changes
364 added 1 changesets with 1 changes to 1 files
363 added 1 changesets with 1 changes to 1 files
365 (run 'hg update' to get a working copy)
364 (run 'hg update' to get a working copy)
366
365
367 should pull t
366 should pull t
368
367
369 $ hg up
368 $ hg up
370 pulling subrepo t from $TESTTMP/t/t (glob)
369 pulling subrepo t from $TESTTMP/t/t (glob)
371 searching for changes
370 searching for changes
372 adding changesets
371 adding changesets
373 adding manifests
372 adding manifests
374 adding file changes
373 adding file changes
375 added 1 changesets with 1 changes to 1 files
374 added 1 changesets with 1 changes to 1 files
376 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
375 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
377 $ cat t/t
376 $ cat t/t
378 blah
377 blah
379
378
380 bogus subrepo path aborts
379 bogus subrepo path aborts
381
380
382 $ echo 'bogus=[boguspath' >> .hgsub
381 $ echo 'bogus=[boguspath' >> .hgsub
383 $ hg ci -m 'bogus subrepo path'
382 $ hg ci -m 'bogus subrepo path'
384 abort: missing ] in subrepo source
383 abort: missing ] in subrepo source
385 [255]
384 [255]
386
385
387 Issue1986: merge aborts when trying to merge a subrepo that
386 Issue1986: merge aborts when trying to merge a subrepo that
388 shouldn't need merging
387 shouldn't need merging
389
388
390 # subrepo layout
389 # subrepo layout
391 #
390 #
392 # o 5 br
391 # o 5 br
393 # /|
392 # /|
394 # o | 4 default
393 # o | 4 default
395 # | |
394 # | |
396 # | o 3 br
395 # | o 3 br
397 # |/|
396 # |/|
398 # o | 2 default
397 # o | 2 default
399 # | |
398 # | |
400 # | o 1 br
399 # | o 1 br
401 # |/
400 # |/
402 # o 0 default
401 # o 0 default
403
402
404 $ cd ..
403 $ cd ..
405 $ rm -rf sub
404 $ rm -rf sub
406 $ hg init main
405 $ hg init main
407 $ cd main
406 $ cd main
408 $ hg init s
407 $ hg init s
409 $ cd s
408 $ cd s
410 $ echo a > a
409 $ echo a > a
411 $ hg ci -Am1
410 $ hg ci -Am1
412 adding a
411 adding a
413 $ hg branch br
412 $ hg branch br
414 marked working directory as branch br
413 marked working directory as branch br
415 (branches are permanent and global, did you want a bookmark?)
414 (branches are permanent and global, did you want a bookmark?)
416 $ echo a >> a
415 $ echo a >> a
417 $ hg ci -m1
416 $ hg ci -m1
418 $ hg up default
417 $ hg up default
419 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
418 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
420 $ echo b > b
419 $ echo b > b
421 $ hg ci -Am1
420 $ hg ci -Am1
422 adding b
421 adding b
423 $ hg up br
422 $ hg up br
424 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
423 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
425 $ hg merge tip
424 $ hg merge tip
426 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
425 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
427 (branch merge, don't forget to commit)
426 (branch merge, don't forget to commit)
428 $ hg ci -m1
427 $ hg ci -m1
429 $ hg up 2
428 $ hg up 2
430 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
429 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
431 $ echo c > c
430 $ echo c > c
432 $ hg ci -Am1
431 $ hg ci -Am1
433 adding c
432 adding c
434 $ hg up 3
433 $ hg up 3
435 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
434 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
436 $ hg merge 4
435 $ hg merge 4
437 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
436 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
438 (branch merge, don't forget to commit)
437 (branch merge, don't forget to commit)
439 $ hg ci -m1
438 $ hg ci -m1
440
439
441 # main repo layout:
440 # main repo layout:
442 #
441 #
443 # * <-- try to merge default into br again
442 # * <-- try to merge default into br again
444 # .`|
443 # .`|
445 # . o 5 br --> substate = 5
444 # . o 5 br --> substate = 5
446 # . |
445 # . |
447 # o | 4 default --> substate = 4
446 # o | 4 default --> substate = 4
448 # | |
447 # | |
449 # | o 3 br --> substate = 2
448 # | o 3 br --> substate = 2
450 # |/|
449 # |/|
451 # o | 2 default --> substate = 2
450 # o | 2 default --> substate = 2
452 # | |
451 # | |
453 # | o 1 br --> substate = 3
452 # | o 1 br --> substate = 3
454 # |/
453 # |/
455 # o 0 default --> substate = 2
454 # o 0 default --> substate = 2
456
455
457 $ cd ..
456 $ cd ..
458 $ echo 's = s' > .hgsub
457 $ echo 's = s' > .hgsub
459 $ hg -R s up 2
458 $ hg -R s up 2
460 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
459 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
461 $ hg ci -Am1
460 $ hg ci -Am1
462 adding .hgsub
461 adding .hgsub
463 $ hg branch br
462 $ hg branch br
464 marked working directory as branch br
463 marked working directory as branch br
465 (branches are permanent and global, did you want a bookmark?)
464 (branches are permanent and global, did you want a bookmark?)
466 $ echo b > b
465 $ echo b > b
467 $ hg -R s up 3
466 $ hg -R s up 3
468 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
467 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
469 $ hg ci -Am1
468 $ hg ci -Am1
470 adding b
469 adding b
471 $ hg up default
470 $ hg up default
472 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
471 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
473 $ echo c > c
472 $ echo c > c
474 $ hg ci -Am1
473 $ hg ci -Am1
475 adding c
474 adding c
476 $ hg up 1
475 $ hg up 1
477 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
476 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
478 $ hg merge 2
477 $ hg merge 2
479 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
478 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
480 (branch merge, don't forget to commit)
479 (branch merge, don't forget to commit)
481 $ hg ci -m1
480 $ hg ci -m1
482 $ hg up 2
481 $ hg up 2
483 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
482 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
484 $ hg -R s up 4
483 $ hg -R s up 4
485 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
484 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
486 $ echo d > d
485 $ echo d > d
487 $ hg ci -Am1
486 $ hg ci -Am1
488 adding d
487 adding d
489 $ hg up 3
488 $ hg up 3
490 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
489 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
491 $ hg -R s up 5
490 $ hg -R s up 5
492 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
491 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
493 $ echo e > e
492 $ echo e > e
494 $ hg ci -Am1
493 $ hg ci -Am1
495 adding e
494 adding e
496
495
497 $ hg up 5
496 $ hg up 5
498 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
497 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
499 $ hg merge 4 # try to merge default into br again
498 $ hg merge 4 # try to merge default into br again
500 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
499 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
501 (branch merge, don't forget to commit)
500 (branch merge, don't forget to commit)
502 $ cd ..
501 $ cd ..
503
502
504 test subrepo delete from .hgsubstate
503 test subrepo delete from .hgsubstate
505
504
506 $ hg init testdelete
505 $ hg init testdelete
507 $ mkdir testdelete/nested testdelete/nested2
506 $ mkdir testdelete/nested testdelete/nested2
508 $ hg init testdelete/nested
507 $ hg init testdelete/nested
509 $ hg init testdelete/nested2
508 $ hg init testdelete/nested2
510 $ echo test > testdelete/nested/foo
509 $ echo test > testdelete/nested/foo
511 $ echo test > testdelete/nested2/foo
510 $ echo test > testdelete/nested2/foo
512 $ hg -R testdelete/nested add
511 $ hg -R testdelete/nested add
513 adding testdelete/nested/foo (glob)
512 adding testdelete/nested/foo (glob)
514 $ hg -R testdelete/nested2 add
513 $ hg -R testdelete/nested2 add
515 adding testdelete/nested2/foo (glob)
514 adding testdelete/nested2/foo (glob)
516 $ hg -R testdelete/nested ci -m test
515 $ hg -R testdelete/nested ci -m test
517 $ hg -R testdelete/nested2 ci -m test
516 $ hg -R testdelete/nested2 ci -m test
518 $ echo nested = nested > testdelete/.hgsub
517 $ echo nested = nested > testdelete/.hgsub
519 $ echo nested2 = nested2 >> testdelete/.hgsub
518 $ echo nested2 = nested2 >> testdelete/.hgsub
520 $ hg -R testdelete add
519 $ hg -R testdelete add
521 adding testdelete/.hgsub (glob)
520 adding testdelete/.hgsub (glob)
522 $ hg -R testdelete ci -m "nested 1 & 2 added"
521 $ hg -R testdelete ci -m "nested 1 & 2 added"
523 $ echo nested = nested > testdelete/.hgsub
522 $ echo nested = nested > testdelete/.hgsub
524 $ hg -R testdelete ci -m "nested 2 deleted"
523 $ hg -R testdelete ci -m "nested 2 deleted"
525 $ cat testdelete/.hgsubstate
524 $ cat testdelete/.hgsubstate
526 bdf5c9a3103743d900b12ae0db3ffdcfd7b0d878 nested
525 bdf5c9a3103743d900b12ae0db3ffdcfd7b0d878 nested
527 $ hg -R testdelete remove testdelete/.hgsub
526 $ hg -R testdelete remove testdelete/.hgsub
528 $ hg -R testdelete ci -m ".hgsub deleted"
527 $ hg -R testdelete ci -m ".hgsub deleted"
529 $ cat testdelete/.hgsubstate
528 $ cat testdelete/.hgsubstate
530 bdf5c9a3103743d900b12ae0db3ffdcfd7b0d878 nested
529 bdf5c9a3103743d900b12ae0db3ffdcfd7b0d878 nested
531
530
532 test repository cloning
531 test repository cloning
533
532
534 $ mkdir mercurial mercurial2
533 $ mkdir mercurial mercurial2
535 $ hg init nested_absolute
534 $ hg init nested_absolute
536 $ echo test > nested_absolute/foo
535 $ echo test > nested_absolute/foo
537 $ hg -R nested_absolute add
536 $ hg -R nested_absolute add
538 adding nested_absolute/foo (glob)
537 adding nested_absolute/foo (glob)
539 $ hg -R nested_absolute ci -mtest
538 $ hg -R nested_absolute ci -mtest
540 $ cd mercurial
539 $ cd mercurial
541 $ hg init nested_relative
540 $ hg init nested_relative
542 $ echo test2 > nested_relative/foo2
541 $ echo test2 > nested_relative/foo2
543 $ hg -R nested_relative add
542 $ hg -R nested_relative add
544 adding nested_relative/foo2 (glob)
543 adding nested_relative/foo2 (glob)
545 $ hg -R nested_relative ci -mtest2
544 $ hg -R nested_relative ci -mtest2
546 $ hg init main
545 $ hg init main
547 $ echo "nested_relative = ../nested_relative" > main/.hgsub
546 $ echo "nested_relative = ../nested_relative" > main/.hgsub
548 $ echo "nested_absolute = `pwd`/nested_absolute" >> main/.hgsub
547 $ echo "nested_absolute = `pwd`/nested_absolute" >> main/.hgsub
549 $ hg -R main add
548 $ hg -R main add
550 adding main/.hgsub (glob)
549 adding main/.hgsub (glob)
551 $ hg -R main ci -m "add subrepos"
550 $ hg -R main ci -m "add subrepos"
552 $ cd ..
551 $ cd ..
553 $ hg clone mercurial/main mercurial2/main
552 $ hg clone mercurial/main mercurial2/main
554 updating to branch default
553 updating to branch default
555 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
554 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
556 $ cat mercurial2/main/nested_absolute/.hg/hgrc \
555 $ cat mercurial2/main/nested_absolute/.hg/hgrc \
557 > mercurial2/main/nested_relative/.hg/hgrc
556 > mercurial2/main/nested_relative/.hg/hgrc
558 [paths]
557 [paths]
559 default = $TESTTMP/mercurial/nested_absolute
558 default = $TESTTMP/mercurial/nested_absolute
560 [paths]
559 [paths]
561 default = $TESTTMP/mercurial/nested_relative
560 default = $TESTTMP/mercurial/nested_relative
562 $ rm -rf mercurial mercurial2
561 $ rm -rf mercurial mercurial2
563
562
564 Issue1977: multirepo push should fail if subrepo push fails
563 Issue1977: multirepo push should fail if subrepo push fails
565
564
566 $ hg init repo
565 $ hg init repo
567 $ hg init repo/s
566 $ hg init repo/s
568 $ echo a > repo/s/a
567 $ echo a > repo/s/a
569 $ hg -R repo/s ci -Am0
568 $ hg -R repo/s ci -Am0
570 adding a
569 adding a
571 $ echo s = s > repo/.hgsub
570 $ echo s = s > repo/.hgsub
572 $ hg -R repo ci -Am1
571 $ hg -R repo ci -Am1
573 adding .hgsub
572 adding .hgsub
574 $ hg clone repo repo2
573 $ hg clone repo repo2
575 updating to branch default
574 updating to branch default
576 cloning subrepo s from $TESTTMP/repo/s (glob)
575 cloning subrepo s from $TESTTMP/repo/s (glob)
577 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
576 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
578 $ hg -q -R repo2 pull -u
577 $ hg -q -R repo2 pull -u
579 $ echo 1 > repo2/s/a
578 $ echo 1 > repo2/s/a
580 $ hg -R repo2/s ci -m2
579 $ hg -R repo2/s ci -m2
581 $ hg -q -R repo2/s push
580 $ hg -q -R repo2/s push
582 $ hg -R repo2/s up -C 0
581 $ hg -R repo2/s up -C 0
583 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
582 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
584 $ echo 2 > repo2/s/b
583 $ echo 2 > repo2/s/b
585 $ hg -R repo2/s ci -m3 -A
584 $ hg -R repo2/s ci -m3 -A
586 adding b
585 adding b
587 created new head
586 created new head
588 $ hg -R repo2 ci -m3
587 $ hg -R repo2 ci -m3
589 $ hg -q -R repo2 push
588 $ hg -q -R repo2 push
590 abort: push creates new remote head cc505f09a8b2! (in subrepo s)
589 abort: push creates new remote head cc505f09a8b2! (in subrepo s)
591 (did you forget to merge? use push -f to force)
590 (did you forget to merge? use push -f to force)
592 [255]
591 [255]
593 $ hg -R repo update
592 $ hg -R repo update
594 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
593 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
595
594
596 test if untracked file is not overwritten
595 test if untracked file is not overwritten
597
596
598 $ echo issue3276_ok > repo/s/b
597 $ echo issue3276_ok > repo/s/b
599 $ hg -R repo2 push -f -q
598 $ hg -R repo2 push -f -q
600 $ hg -R repo update
599 $ hg -R repo update
601 b: untracked file differs
600 b: untracked file differs
602 abort: untracked files in working directory differ from files in requested revision (in subrepo s)
601 abort: untracked files in working directory differ from files in requested revision (in subrepo s)
603 [255]
602 [255]
604
603
605 $ cat repo/s/b
604 $ cat repo/s/b
606 issue3276_ok
605 issue3276_ok
607 $ rm repo/s/b
606 $ rm repo/s/b
608 $ hg -R repo revert --all
607 $ hg -R repo revert --all
609 reverting repo/.hgsubstate (glob)
608 reverting repo/.hgsubstate (glob)
610 reverting subrepo s
609 reverting subrepo s
611 $ hg -R repo update
610 $ hg -R repo update
612 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
611 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
613 $ cat repo/s/b
612 $ cat repo/s/b
614 2
613 2
615 $ rm -rf repo2 repo
614 $ rm -rf repo2 repo
616
615
617
616
618 Issue1852 subrepos with relative paths always push/pull relative to default
617 Issue1852 subrepos with relative paths always push/pull relative to default
619
618
620 Prepare a repo with subrepo
619 Prepare a repo with subrepo
621
620
622 $ hg init issue1852a
621 $ hg init issue1852a
623 $ cd issue1852a
622 $ cd issue1852a
624 $ hg init sub/repo
623 $ hg init sub/repo
625 $ echo test > sub/repo/foo
624 $ echo test > sub/repo/foo
626 $ hg -R sub/repo add sub/repo/foo
625 $ hg -R sub/repo add sub/repo/foo
627 $ echo sub/repo = sub/repo > .hgsub
626 $ echo sub/repo = sub/repo > .hgsub
628 $ hg add .hgsub
627 $ hg add .hgsub
629 $ hg ci -mtest
628 $ hg ci -mtest
630 committing subrepository sub/repo (glob)
629 committing subrepository sub/repo (glob)
631 $ echo test >> sub/repo/foo
630 $ echo test >> sub/repo/foo
632 $ hg ci -mtest
631 $ hg ci -mtest
633 committing subrepository sub/repo (glob)
632 committing subrepository sub/repo (glob)
634 $ cd ..
633 $ cd ..
635
634
636 Create repo without default path, pull top repo, and see what happens on update
635 Create repo without default path, pull top repo, and see what happens on update
637
636
638 $ hg init issue1852b
637 $ hg init issue1852b
639 $ hg -R issue1852b pull issue1852a
638 $ hg -R issue1852b pull issue1852a
640 pulling from issue1852a
639 pulling from issue1852a
641 requesting all changes
640 requesting all changes
642 adding changesets
641 adding changesets
643 adding manifests
642 adding manifests
644 adding file changes
643 adding file changes
645 added 2 changesets with 3 changes to 2 files
644 added 2 changesets with 3 changes to 2 files
646 (run 'hg update' to get a working copy)
645 (run 'hg update' to get a working copy)
647 $ hg -R issue1852b update
646 $ hg -R issue1852b update
648 abort: default path for subrepository not found (in subrepo sub/repo) (glob)
647 abort: default path for subrepository not found (in subrepo sub/repo) (glob)
649 [255]
648 [255]
650
649
651 Pull -u now doesn't help
650 Pull -u now doesn't help
652
651
653 $ hg -R issue1852b pull -u issue1852a
652 $ hg -R issue1852b pull -u issue1852a
654 pulling from issue1852a
653 pulling from issue1852a
655 searching for changes
654 searching for changes
656 no changes found
655 no changes found
657
656
658 Try the same, but with pull -u
657 Try the same, but with pull -u
659
658
660 $ hg init issue1852c
659 $ hg init issue1852c
661 $ hg -R issue1852c pull -r0 -u issue1852a
660 $ hg -R issue1852c pull -r0 -u issue1852a
662 pulling from issue1852a
661 pulling from issue1852a
663 adding changesets
662 adding changesets
664 adding manifests
663 adding manifests
665 adding file changes
664 adding file changes
666 added 1 changesets with 2 changes to 2 files
665 added 1 changesets with 2 changes to 2 files
667 cloning subrepo sub/repo from issue1852a/sub/repo (glob)
666 cloning subrepo sub/repo from issue1852a/sub/repo (glob)
668 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
667 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
669
668
670 Try to push from the other side
669 Try to push from the other side
671
670
672 $ hg -R issue1852a push `pwd`/issue1852c
671 $ hg -R issue1852a push `pwd`/issue1852c
673 pushing to $TESTTMP/issue1852c
672 pushing to $TESTTMP/issue1852c
674 pushing subrepo sub/repo to $TESTTMP/issue1852c/sub/repo (glob)
673 pushing subrepo sub/repo to $TESTTMP/issue1852c/sub/repo (glob)
675 searching for changes
674 searching for changes
676 no changes found
675 no changes found
677 searching for changes
676 searching for changes
678 adding changesets
677 adding changesets
679 adding manifests
678 adding manifests
680 adding file changes
679 adding file changes
681 added 1 changesets with 1 changes to 1 files
680 added 1 changesets with 1 changes to 1 files
682
681
683 Incoming and outgoing should not use the default path:
682 Incoming and outgoing should not use the default path:
684
683
685 $ hg clone -q issue1852a issue1852d
684 $ hg clone -q issue1852a issue1852d
686 $ hg -R issue1852d outgoing --subrepos issue1852c
685 $ hg -R issue1852d outgoing --subrepos issue1852c
687 comparing with issue1852c
686 comparing with issue1852c
688 searching for changes
687 searching for changes
689 no changes found
688 no changes found
690 comparing with issue1852c/sub/repo
689 comparing with issue1852c/sub/repo
691 searching for changes
690 searching for changes
692 no changes found
691 no changes found
693 [1]
692 [1]
694 $ hg -R issue1852d incoming --subrepos issue1852c
693 $ hg -R issue1852d incoming --subrepos issue1852c
695 comparing with issue1852c
694 comparing with issue1852c
696 searching for changes
695 searching for changes
697 no changes found
696 no changes found
698 comparing with issue1852c/sub/repo
697 comparing with issue1852c/sub/repo
699 searching for changes
698 searching for changes
700 no changes found
699 no changes found
701 [1]
700 [1]
702
701
703 Check status of files when none of them belong to the first
702 Check status of files when none of them belong to the first
704 subrepository:
703 subrepository:
705
704
706 $ hg init subrepo-status
705 $ hg init subrepo-status
707 $ cd subrepo-status
706 $ cd subrepo-status
708 $ hg init subrepo-1
707 $ hg init subrepo-1
709 $ hg init subrepo-2
708 $ hg init subrepo-2
710 $ cd subrepo-2
709 $ cd subrepo-2
711 $ touch file
710 $ touch file
712 $ hg add file
711 $ hg add file
713 $ cd ..
712 $ cd ..
714 $ echo subrepo-1 = subrepo-1 > .hgsub
713 $ echo subrepo-1 = subrepo-1 > .hgsub
715 $ echo subrepo-2 = subrepo-2 >> .hgsub
714 $ echo subrepo-2 = subrepo-2 >> .hgsub
716 $ hg add .hgsub
715 $ hg add .hgsub
717 $ hg ci -m 'Added subrepos'
716 $ hg ci -m 'Added subrepos'
718 committing subrepository subrepo-2
717 committing subrepository subrepo-2
719 $ hg st subrepo-2/file
718 $ hg st subrepo-2/file
720
719
721 Check that share works with subrepo
720 Check that share works with subrepo
722 $ hg --config extensions.share= share . ../shared
721 $ hg --config extensions.share= share . ../shared
723 updating working directory
722 updating working directory
724 cloning subrepo subrepo-2 from $TESTTMP/subrepo-status/subrepo-2
723 cloning subrepo subrepo-2 from $TESTTMP/subrepo-status/subrepo-2
725 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
724 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
726 $ test -f ../shared/subrepo-1/.hg/sharedpath
725 $ test -f ../shared/subrepo-1/.hg/sharedpath
727 [1]
726 [1]
728 $ hg -R ../shared in
727 $ hg -R ../shared in
729 abort: repository default not found!
728 abort: repository default not found!
730 [255]
729 [255]
731 $ hg -R ../shared/subrepo-2 showconfig paths
730 $ hg -R ../shared/subrepo-2 showconfig paths
732 paths.default=$TESTTMP/subrepo-status/subrepo-2
731 paths.default=$TESTTMP/subrepo-status/subrepo-2
733 $ hg -R ../shared/subrepo-1 sum --remote
732 $ hg -R ../shared/subrepo-1 sum --remote
734 parent: -1:000000000000 tip (empty repository)
733 parent: -1:000000000000 tip (empty repository)
735 branch: default
734 branch: default
736 commit: (clean)
735 commit: (clean)
737 update: (current)
736 update: (current)
738 remote: (synced)
737 remote: (synced)
739
738
740 Check hg update --clean
739 Check hg update --clean
741 $ cd $TESTTMP/t
740 $ cd $TESTTMP/t
742 $ rm -r t/t.orig
741 $ rm -r t/t.orig
743 $ hg status -S --all
742 $ hg status -S --all
744 C .hgsub
743 C .hgsub
745 C .hgsubstate
744 C .hgsubstate
746 C a
745 C a
747 C s/.hgsub
746 C s/.hgsub
748 C s/.hgsubstate
747 C s/.hgsubstate
749 C s/a
748 C s/a
750 C s/ss/a
749 C s/ss/a
751 C t/t
750 C t/t
752 $ echo c1 > s/a
751 $ echo c1 > s/a
753 $ cd s
752 $ cd s
754 $ echo c1 > b
753 $ echo c1 > b
755 $ echo c1 > c
754 $ echo c1 > c
756 $ hg add b
755 $ hg add b
757 $ cd ..
756 $ cd ..
758 $ hg status -S
757 $ hg status -S
759 M s/a
758 M s/a
760 A s/b
759 A s/b
761 ? s/c
760 ? s/c
762 $ hg update -C
761 $ hg update -C
763 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
762 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
764 $ hg status -S
763 $ hg status -S
765 ? s/b
764 ? s/b
766 ? s/c
765 ? s/c
767
766
768 Sticky subrepositories, no changes
767 Sticky subrepositories, no changes
769 $ cd $TESTTMP/t
768 $ cd $TESTTMP/t
770 $ hg id
769 $ hg id
771 925c17564ef8 tip
770 925c17564ef8 tip
772 $ hg -R s id
771 $ hg -R s id
773 12a213df6fa9 tip
772 12a213df6fa9 tip
774 $ hg -R t id
773 $ hg -R t id
775 52c0adc0515a tip
774 52c0adc0515a tip
776 $ hg update 11
775 $ hg update 11
777 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
776 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
778 $ hg id
777 $ hg id
779 365661e5936a
778 365661e5936a
780 $ hg -R s id
779 $ hg -R s id
781 fc627a69481f
780 fc627a69481f
782 $ hg -R t id
781 $ hg -R t id
783 e95bcfa18a35
782 e95bcfa18a35
784
783
785 Sticky subrepositorys, file changes
784 Sticky subrepositorys, file changes
786 $ touch s/f1
785 $ touch s/f1
787 $ touch t/f1
786 $ touch t/f1
788 $ hg add -S s/f1
787 $ hg add -S s/f1
789 $ hg add -S t/f1
788 $ hg add -S t/f1
790 $ hg id
789 $ hg id
791 365661e5936a+
790 365661e5936a+
792 $ hg -R s id
791 $ hg -R s id
793 fc627a69481f+
792 fc627a69481f+
794 $ hg -R t id
793 $ hg -R t id
795 e95bcfa18a35+
794 e95bcfa18a35+
796 $ hg update tip
795 $ hg update tip
797 subrepository sources for s differ
796 subrepository sources for s differ
798 use (l)ocal source (fc627a69481f) or (r)emote source (12a213df6fa9)?
797 use (l)ocal source (fc627a69481f) or (r)emote source (12a213df6fa9)?
799 l
798 l
800 subrepository sources for t differ
799 subrepository sources for t differ
801 use (l)ocal source (e95bcfa18a35) or (r)emote source (52c0adc0515a)?
800 use (l)ocal source (e95bcfa18a35) or (r)emote source (52c0adc0515a)?
802 l
801 l
803 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
802 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
804 $ hg id
803 $ hg id
805 925c17564ef8+ tip
804 925c17564ef8+ tip
806 $ hg -R s id
805 $ hg -R s id
807 fc627a69481f+
806 fc627a69481f+
808 $ hg -R t id
807 $ hg -R t id
809 e95bcfa18a35+
808 e95bcfa18a35+
810 $ hg update --clean tip
809 $ hg update --clean tip
811 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
810 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
812
811
813 Sticky subrepository, revision updates
812 Sticky subrepository, revision updates
814 $ hg id
813 $ hg id
815 925c17564ef8 tip
814 925c17564ef8 tip
816 $ hg -R s id
815 $ hg -R s id
817 12a213df6fa9 tip
816 12a213df6fa9 tip
818 $ hg -R t id
817 $ hg -R t id
819 52c0adc0515a tip
818 52c0adc0515a tip
820 $ cd s
819 $ cd s
821 $ hg update -r -2
820 $ hg update -r -2
822 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
821 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
823 $ cd ../t
822 $ cd ../t
824 $ hg update -r 2
823 $ hg update -r 2
825 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
824 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
826 $ cd ..
825 $ cd ..
827 $ hg update 10
826 $ hg update 10
828 subrepository sources for t differ (in checked out version)
827 subrepository sources for t differ (in checked out version)
829 use (l)ocal source (7af322bc1198) or (r)emote source (20a0db6fbf6c)?
828 use (l)ocal source (7af322bc1198) or (r)emote source (20a0db6fbf6c)?
830 l
829 l
831 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
830 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
832 $ hg id
831 $ hg id
833 e45c8b14af55+
832 e45c8b14af55+
834 $ hg -R s id
833 $ hg -R s id
835 02dcf1d70411
834 02dcf1d70411
836 $ hg -R t id
835 $ hg -R t id
837 7af322bc1198
836 7af322bc1198
838
837
839 Sticky subrepository, file changes and revision updates
838 Sticky subrepository, file changes and revision updates
840 $ touch s/f1
839 $ touch s/f1
841 $ touch t/f1
840 $ touch t/f1
842 $ hg add -S s/f1
841 $ hg add -S s/f1
843 $ hg add -S t/f1
842 $ hg add -S t/f1
844 $ hg id
843 $ hg id
845 e45c8b14af55+
844 e45c8b14af55+
846 $ hg -R s id
845 $ hg -R s id
847 02dcf1d70411+
846 02dcf1d70411+
848 $ hg -R t id
847 $ hg -R t id
849 7af322bc1198+
848 7af322bc1198+
850 $ hg update tip
849 $ hg update tip
851 subrepository sources for s differ
850 subrepository sources for s differ
852 use (l)ocal source (02dcf1d70411) or (r)emote source (12a213df6fa9)?
851 use (l)ocal source (02dcf1d70411) or (r)emote source (12a213df6fa9)?
853 l
852 l
854 subrepository sources for t differ
853 subrepository sources for t differ
855 use (l)ocal source (7af322bc1198) or (r)emote source (52c0adc0515a)?
854 use (l)ocal source (7af322bc1198) or (r)emote source (52c0adc0515a)?
856 l
855 l
857 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
856 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
858 $ hg id
857 $ hg id
859 925c17564ef8+ tip
858 925c17564ef8+ tip
860 $ hg -R s id
859 $ hg -R s id
861 02dcf1d70411+
860 02dcf1d70411+
862 $ hg -R t id
861 $ hg -R t id
863 7af322bc1198+
862 7af322bc1198+
864
863
865 Sticky repository, update --clean
864 Sticky repository, update --clean
866 $ hg update --clean tip
865 $ hg update --clean tip
867 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
866 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
868 $ hg id
867 $ hg id
869 925c17564ef8 tip
868 925c17564ef8 tip
870 $ hg -R s id
869 $ hg -R s id
871 12a213df6fa9 tip
870 12a213df6fa9 tip
872 $ hg -R t id
871 $ hg -R t id
873 52c0adc0515a tip
872 52c0adc0515a tip
874
873
875 Test subrepo already at intended revision:
874 Test subrepo already at intended revision:
876 $ cd s
875 $ cd s
877 $ hg update fc627a69481f
876 $ hg update fc627a69481f
878 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
877 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
879 $ cd ..
878 $ cd ..
880 $ hg update 11
879 $ hg update 11
881 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
880 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
882 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
881 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
883 $ hg id -n
882 $ hg id -n
884 11+
883 11+
885 $ hg -R s id
884 $ hg -R s id
886 fc627a69481f
885 fc627a69481f
887 $ hg -R t id
886 $ hg -R t id
888 e95bcfa18a35
887 e95bcfa18a35
889
888
890 Test that removing .hgsubstate doesn't break anything:
889 Test that removing .hgsubstate doesn't break anything:
891
890
892 $ hg rm -f .hgsubstate
891 $ hg rm -f .hgsubstate
893 $ hg ci -mrm
892 $ hg ci -mrm
894 nothing changed
893 nothing changed
895 [1]
894 [1]
896 $ hg log -vr tip
895 $ hg log -vr tip
897 changeset: 13:925c17564ef8
896 changeset: 13:925c17564ef8
898 tag: tip
897 tag: tip
899 user: test
898 user: test
900 date: Thu Jan 01 00:00:00 1970 +0000
899 date: Thu Jan 01 00:00:00 1970 +0000
901 files: .hgsubstate
900 files: .hgsubstate
902 description:
901 description:
903 13
902 13
904
903
905
904
906
905
907 Test that removing .hgsub removes .hgsubstate:
906 Test that removing .hgsub removes .hgsubstate:
908
907
909 $ hg rm .hgsub
908 $ hg rm .hgsub
910 $ hg ci -mrm2
909 $ hg ci -mrm2
911 created new head
910 created new head
912 $ hg log -vr tip
911 $ hg log -vr tip
913 changeset: 14:2400bccd50af
912 changeset: 14:2400bccd50af
914 tag: tip
913 tag: tip
915 parent: 11:365661e5936a
914 parent: 11:365661e5936a
916 user: test
915 user: test
917 date: Thu Jan 01 00:00:00 1970 +0000
916 date: Thu Jan 01 00:00:00 1970 +0000
918 files: .hgsub .hgsubstate
917 files: .hgsub .hgsubstate
919 description:
918 description:
920 rm2
919 rm2
921
920
922
921
923 Test issue3153: diff -S with deleted subrepos
922 Test issue3153: diff -S with deleted subrepos
924
923
925 $ hg diff --nodates -S -c .
924 $ hg diff --nodates -S -c .
926 diff -r 365661e5936a -r 2400bccd50af .hgsub
925 diff -r 365661e5936a -r 2400bccd50af .hgsub
927 --- a/.hgsub
926 --- a/.hgsub
928 +++ /dev/null
927 +++ /dev/null
929 @@ -1,2 +0,0 @@
928 @@ -1,2 +0,0 @@
930 -s = s
929 -s = s
931 -t = t
930 -t = t
932 diff -r 365661e5936a -r 2400bccd50af .hgsubstate
931 diff -r 365661e5936a -r 2400bccd50af .hgsubstate
933 --- a/.hgsubstate
932 --- a/.hgsubstate
934 +++ /dev/null
933 +++ /dev/null
935 @@ -1,2 +0,0 @@
934 @@ -1,2 +0,0 @@
936 -fc627a69481fcbe5f1135069e8a3881c023e4cf5 s
935 -fc627a69481fcbe5f1135069e8a3881c023e4cf5 s
937 -e95bcfa18a358dc4936da981ebf4147b4cad1362 t
936 -e95bcfa18a358dc4936da981ebf4147b4cad1362 t
938
937
939 Test behavior of add for explicit path in subrepo:
938 Test behavior of add for explicit path in subrepo:
940 $ cd ..
939 $ cd ..
941 $ hg init explicit
940 $ hg init explicit
942 $ cd explicit
941 $ cd explicit
943 $ echo s = s > .hgsub
942 $ echo s = s > .hgsub
944 $ hg add .hgsub
943 $ hg add .hgsub
945 $ hg init s
944 $ hg init s
946 $ hg ci -m0
945 $ hg ci -m0
947 Adding with an explicit path in a subrepo adds the file
946 Adding with an explicit path in a subrepo adds the file
948 $ echo c1 > f1
947 $ echo c1 > f1
949 $ echo c2 > s/f2
948 $ echo c2 > s/f2
950 $ hg st -S
949 $ hg st -S
951 ? f1
950 ? f1
952 ? s/f2
951 ? s/f2
953 $ hg add s/f2
952 $ hg add s/f2
954 $ hg st -S
953 $ hg st -S
955 A s/f2
954 A s/f2
956 ? f1
955 ? f1
957 $ hg ci -R s -m0
956 $ hg ci -R s -m0
958 $ hg ci -Am1
957 $ hg ci -Am1
959 adding f1
958 adding f1
960 Adding with an explicit path in a subrepo with -S has the same behavior
959 Adding with an explicit path in a subrepo with -S has the same behavior
961 $ echo c3 > f3
960 $ echo c3 > f3
962 $ echo c4 > s/f4
961 $ echo c4 > s/f4
963 $ hg st -S
962 $ hg st -S
964 ? f3
963 ? f3
965 ? s/f4
964 ? s/f4
966 $ hg add -S s/f4
965 $ hg add -S s/f4
967 $ hg st -S
966 $ hg st -S
968 A s/f4
967 A s/f4
969 ? f3
968 ? f3
970 $ hg ci -R s -m1
969 $ hg ci -R s -m1
971 $ hg ci -Ama2
970 $ hg ci -Ama2
972 adding f3
971 adding f3
973 Adding without a path or pattern silently ignores subrepos
972 Adding without a path or pattern silently ignores subrepos
974 $ echo c5 > f5
973 $ echo c5 > f5
975 $ echo c6 > s/f6
974 $ echo c6 > s/f6
976 $ echo c7 > s/f7
975 $ echo c7 > s/f7
977 $ hg st -S
976 $ hg st -S
978 ? f5
977 ? f5
979 ? s/f6
978 ? s/f6
980 ? s/f7
979 ? s/f7
981 $ hg add
980 $ hg add
982 adding f5
981 adding f5
983 $ hg st -S
982 $ hg st -S
984 A f5
983 A f5
985 ? s/f6
984 ? s/f6
986 ? s/f7
985 ? s/f7
987 $ hg ci -R s -Am2
986 $ hg ci -R s -Am2
988 adding f6
987 adding f6
989 adding f7
988 adding f7
990 $ hg ci -m3
989 $ hg ci -m3
991 Adding without a path or pattern with -S also adds files in subrepos
990 Adding without a path or pattern with -S also adds files in subrepos
992 $ echo c8 > f8
991 $ echo c8 > f8
993 $ echo c9 > s/f9
992 $ echo c9 > s/f9
994 $ echo c10 > s/f10
993 $ echo c10 > s/f10
995 $ hg st -S
994 $ hg st -S
996 ? f8
995 ? f8
997 ? s/f10
996 ? s/f10
998 ? s/f9
997 ? s/f9
999 $ hg add -S
998 $ hg add -S
1000 adding f8
999 adding f8
1001 adding s/f10 (glob)
1000 adding s/f10 (glob)
1002 adding s/f9 (glob)
1001 adding s/f9 (glob)
1003 $ hg st -S
1002 $ hg st -S
1004 A f8
1003 A f8
1005 A s/f10
1004 A s/f10
1006 A s/f9
1005 A s/f9
1007 $ hg ci -R s -m3
1006 $ hg ci -R s -m3
1008 $ hg ci -m4
1007 $ hg ci -m4
1009 Adding with a pattern silently ignores subrepos
1008 Adding with a pattern silently ignores subrepos
1010 $ echo c11 > fm11
1009 $ echo c11 > fm11
1011 $ echo c12 > fn12
1010 $ echo c12 > fn12
1012 $ echo c13 > s/fm13
1011 $ echo c13 > s/fm13
1013 $ echo c14 > s/fn14
1012 $ echo c14 > s/fn14
1014 $ hg st -S
1013 $ hg st -S
1015 ? fm11
1014 ? fm11
1016 ? fn12
1015 ? fn12
1017 ? s/fm13
1016 ? s/fm13
1018 ? s/fn14
1017 ? s/fn14
1019 $ hg add 'glob:**fm*'
1018 $ hg add 'glob:**fm*'
1020 adding fm11
1019 adding fm11
1021 $ hg st -S
1020 $ hg st -S
1022 A fm11
1021 A fm11
1023 ? fn12
1022 ? fn12
1024 ? s/fm13
1023 ? s/fm13
1025 ? s/fn14
1024 ? s/fn14
1026 $ hg ci -R s -Am4
1025 $ hg ci -R s -Am4
1027 adding fm13
1026 adding fm13
1028 adding fn14
1027 adding fn14
1029 $ hg ci -Am5
1028 $ hg ci -Am5
1030 adding fn12
1029 adding fn12
1031 Adding with a pattern with -S also adds matches in subrepos
1030 Adding with a pattern with -S also adds matches in subrepos
1032 $ echo c15 > fm15
1031 $ echo c15 > fm15
1033 $ echo c16 > fn16
1032 $ echo c16 > fn16
1034 $ echo c17 > s/fm17
1033 $ echo c17 > s/fm17
1035 $ echo c18 > s/fn18
1034 $ echo c18 > s/fn18
1036 $ hg st -S
1035 $ hg st -S
1037 ? fm15
1036 ? fm15
1038 ? fn16
1037 ? fn16
1039 ? s/fm17
1038 ? s/fm17
1040 ? s/fn18
1039 ? s/fn18
1041 $ hg add -S 'glob:**fm*'
1040 $ hg add -S 'glob:**fm*'
1042 adding fm15
1041 adding fm15
1043 adding s/fm17 (glob)
1042 adding s/fm17 (glob)
1044 $ hg st -S
1043 $ hg st -S
1045 A fm15
1044 A fm15
1046 A s/fm17
1045 A s/fm17
1047 ? fn16
1046 ? fn16
1048 ? s/fn18
1047 ? s/fn18
1049 $ hg ci -R s -Am5
1048 $ hg ci -R s -Am5
1050 adding fn18
1049 adding fn18
1051 $ hg ci -Am6
1050 $ hg ci -Am6
1052 adding fn16
1051 adding fn16
1053
1052
1054 Test behavior of forget for explicit path in subrepo:
1053 Test behavior of forget for explicit path in subrepo:
1055 Forgetting an explicit path in a subrepo untracks the file
1054 Forgetting an explicit path in a subrepo untracks the file
1056 $ echo c19 > s/f19
1055 $ echo c19 > s/f19
1057 $ hg add s/f19
1056 $ hg add s/f19
1058 $ hg st -S
1057 $ hg st -S
1059 A s/f19
1058 A s/f19
1060 $ hg forget s/f19
1059 $ hg forget s/f19
1061 $ hg st -S
1060 $ hg st -S
1062 ? s/f19
1061 ? s/f19
1063 $ rm s/f19
1062 $ rm s/f19
1064 $ cd ..
1063 $ cd ..
1065
1064
1066 Courtesy phases synchronisation to publishing server does not block the push
1065 Courtesy phases synchronisation to publishing server does not block the push
1067 (issue3781)
1066 (issue3781)
1068
1067
1069 $ cp -r main issue3781
1068 $ cp -r main issue3781
1070 $ cp -r main issue3781-dest
1069 $ cp -r main issue3781-dest
1071 $ cd issue3781-dest/s
1070 $ cd issue3781-dest/s
1072 $ hg phase tip # show we have draft changeset
1071 $ hg phase tip # show we have draft changeset
1073 5: draft
1072 5: draft
1074 $ chmod a-w .hg/store/phaseroots # prevent phase push
1073 $ chmod a-w .hg/store/phaseroots # prevent phase push
1075 $ cd ../../issue3781
1074 $ cd ../../issue3781
1076 $ cat >> .hg/hgrc << EOF
1075 $ cat >> .hg/hgrc << EOF
1077 > [paths]
1076 > [paths]
1078 > default=../issue3781-dest/
1077 > default=../issue3781-dest/
1079 > EOF
1078 > EOF
1080 $ hg push
1079 $ hg push
1081 pushing to $TESTTMP/issue3781-dest (glob)
1080 pushing to $TESTTMP/issue3781-dest (glob)
1082 pushing subrepo s to $TESTTMP/issue3781-dest/s
1081 pushing subrepo s to $TESTTMP/issue3781-dest/s
1083 searching for changes
1082 searching for changes
1084 no changes found
1083 no changes found
1085 searching for changes
1084 searching for changes
1086 no changes found
1085 no changes found
1087 [1]
1086 [1]
1088
1087
General Comments 0
You need to be logged in to leave comments. Login now