##// END OF EJS Templates
mergecopies: invoke _computenonoverlap for both base and tca during merges...
Gábor Stefanik -
r30197:0accd5a5 default
parent child Browse files
Show More
@@ -1,618 +1,630
1 # copies.py - copy detection for Mercurial
1 # copies.py - copy detection for Mercurial
2 #
2 #
3 # Copyright 2008 Matt Mackall <mpm@selenic.com>
3 # Copyright 2008 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import heapq
10 import heapq
11
11
12 from . import (
12 from . import (
13 node,
13 node,
14 pathutil,
14 pathutil,
15 scmutil,
15 scmutil,
16 util,
16 util,
17 )
17 )
18
18
19 def _findlimit(repo, a, b):
19 def _findlimit(repo, a, b):
20 """
20 """
21 Find the last revision that needs to be checked to ensure that a full
21 Find the last revision that needs to be checked to ensure that a full
22 transitive closure for file copies can be properly calculated.
22 transitive closure for file copies can be properly calculated.
23 Generally, this means finding the earliest revision number that's an
23 Generally, this means finding the earliest revision number that's an
24 ancestor of a or b but not both, except when a or b is a direct descendent
24 ancestor of a or b but not both, except when a or b is a direct descendent
25 of the other, in which case we can return the minimum revnum of a and b.
25 of the other, in which case we can return the minimum revnum of a and b.
26 None if no such revision exists.
26 None if no such revision exists.
27 """
27 """
28
28
29 # basic idea:
29 # basic idea:
30 # - mark a and b with different sides
30 # - mark a and b with different sides
31 # - if a parent's children are all on the same side, the parent is
31 # - if a parent's children are all on the same side, the parent is
32 # on that side, otherwise it is on no side
32 # on that side, otherwise it is on no side
33 # - walk the graph in topological order with the help of a heap;
33 # - walk the graph in topological order with the help of a heap;
34 # - add unseen parents to side map
34 # - add unseen parents to side map
35 # - clear side of any parent that has children on different sides
35 # - clear side of any parent that has children on different sides
36 # - track number of interesting revs that might still be on a side
36 # - track number of interesting revs that might still be on a side
37 # - track the lowest interesting rev seen
37 # - track the lowest interesting rev seen
38 # - quit when interesting revs is zero
38 # - quit when interesting revs is zero
39
39
40 cl = repo.changelog
40 cl = repo.changelog
41 working = len(cl) # pseudo rev for the working directory
41 working = len(cl) # pseudo rev for the working directory
42 if a is None:
42 if a is None:
43 a = working
43 a = working
44 if b is None:
44 if b is None:
45 b = working
45 b = working
46
46
47 side = {a: -1, b: 1}
47 side = {a: -1, b: 1}
48 visit = [-a, -b]
48 visit = [-a, -b]
49 heapq.heapify(visit)
49 heapq.heapify(visit)
50 interesting = len(visit)
50 interesting = len(visit)
51 hascommonancestor = False
51 hascommonancestor = False
52 limit = working
52 limit = working
53
53
54 while interesting:
54 while interesting:
55 r = -heapq.heappop(visit)
55 r = -heapq.heappop(visit)
56 if r == working:
56 if r == working:
57 parents = [cl.rev(p) for p in repo.dirstate.parents()]
57 parents = [cl.rev(p) for p in repo.dirstate.parents()]
58 else:
58 else:
59 parents = cl.parentrevs(r)
59 parents = cl.parentrevs(r)
60 for p in parents:
60 for p in parents:
61 if p < 0:
61 if p < 0:
62 continue
62 continue
63 if p not in side:
63 if p not in side:
64 # first time we see p; add it to visit
64 # first time we see p; add it to visit
65 side[p] = side[r]
65 side[p] = side[r]
66 if side[p]:
66 if side[p]:
67 interesting += 1
67 interesting += 1
68 heapq.heappush(visit, -p)
68 heapq.heappush(visit, -p)
69 elif side[p] and side[p] != side[r]:
69 elif side[p] and side[p] != side[r]:
70 # p was interesting but now we know better
70 # p was interesting but now we know better
71 side[p] = 0
71 side[p] = 0
72 interesting -= 1
72 interesting -= 1
73 hascommonancestor = True
73 hascommonancestor = True
74 if side[r]:
74 if side[r]:
75 limit = r # lowest rev visited
75 limit = r # lowest rev visited
76 interesting -= 1
76 interesting -= 1
77
77
78 if not hascommonancestor:
78 if not hascommonancestor:
79 return None
79 return None
80
80
81 # Consider the following flow (see test-commit-amend.t under issue4405):
81 # Consider the following flow (see test-commit-amend.t under issue4405):
82 # 1/ File 'a0' committed
82 # 1/ File 'a0' committed
83 # 2/ File renamed from 'a0' to 'a1' in a new commit (call it 'a1')
83 # 2/ File renamed from 'a0' to 'a1' in a new commit (call it 'a1')
84 # 3/ Move back to first commit
84 # 3/ Move back to first commit
85 # 4/ Create a new commit via revert to contents of 'a1' (call it 'a1-amend')
85 # 4/ Create a new commit via revert to contents of 'a1' (call it 'a1-amend')
86 # 5/ Rename file from 'a1' to 'a2' and commit --amend 'a1-msg'
86 # 5/ Rename file from 'a1' to 'a2' and commit --amend 'a1-msg'
87 #
87 #
88 # During the amend in step five, we will be in this state:
88 # During the amend in step five, we will be in this state:
89 #
89 #
90 # @ 3 temporary amend commit for a1-amend
90 # @ 3 temporary amend commit for a1-amend
91 # |
91 # |
92 # o 2 a1-amend
92 # o 2 a1-amend
93 # |
93 # |
94 # | o 1 a1
94 # | o 1 a1
95 # |/
95 # |/
96 # o 0 a0
96 # o 0 a0
97 #
97 #
98 # When _findlimit is called, a and b are revs 3 and 0, so limit will be 2,
98 # When _findlimit is called, a and b are revs 3 and 0, so limit will be 2,
99 # yet the filelog has the copy information in rev 1 and we will not look
99 # yet the filelog has the copy information in rev 1 and we will not look
100 # back far enough unless we also look at the a and b as candidates.
100 # back far enough unless we also look at the a and b as candidates.
101 # This only occurs when a is a descendent of b or visa-versa.
101 # This only occurs when a is a descendent of b or visa-versa.
102 return min(limit, a, b)
102 return min(limit, a, b)
103
103
104 def _chain(src, dst, a, b):
104 def _chain(src, dst, a, b):
105 '''chain two sets of copies a->b'''
105 '''chain two sets of copies a->b'''
106 t = a.copy()
106 t = a.copy()
107 for k, v in b.iteritems():
107 for k, v in b.iteritems():
108 if v in t:
108 if v in t:
109 # found a chain
109 # found a chain
110 if t[v] != k:
110 if t[v] != k:
111 # file wasn't renamed back to itself
111 # file wasn't renamed back to itself
112 t[k] = t[v]
112 t[k] = t[v]
113 if v not in dst:
113 if v not in dst:
114 # chain was a rename, not a copy
114 # chain was a rename, not a copy
115 del t[v]
115 del t[v]
116 if v in src:
116 if v in src:
117 # file is a copy of an existing file
117 # file is a copy of an existing file
118 t[k] = v
118 t[k] = v
119
119
120 # remove criss-crossed copies
120 # remove criss-crossed copies
121 for k, v in t.items():
121 for k, v in t.items():
122 if k in src and v in dst:
122 if k in src and v in dst:
123 del t[k]
123 del t[k]
124
124
125 return t
125 return t
126
126
127 def _tracefile(fctx, am, limit=-1):
127 def _tracefile(fctx, am, limit=-1):
128 '''return file context that is the ancestor of fctx present in ancestor
128 '''return file context that is the ancestor of fctx present in ancestor
129 manifest am, stopping after the first ancestor lower than limit'''
129 manifest am, stopping after the first ancestor lower than limit'''
130
130
131 for f in fctx.ancestors():
131 for f in fctx.ancestors():
132 if am.get(f.path(), None) == f.filenode():
132 if am.get(f.path(), None) == f.filenode():
133 return f
133 return f
134 if limit >= 0 and f.linkrev() < limit and f.rev() < limit:
134 if limit >= 0 and f.linkrev() < limit and f.rev() < limit:
135 return None
135 return None
136
136
137 def _dirstatecopies(d):
137 def _dirstatecopies(d):
138 ds = d._repo.dirstate
138 ds = d._repo.dirstate
139 c = ds.copies().copy()
139 c = ds.copies().copy()
140 for k in c.keys():
140 for k in c.keys():
141 if ds[k] not in 'anm':
141 if ds[k] not in 'anm':
142 del c[k]
142 del c[k]
143 return c
143 return c
144
144
145 def _computeforwardmissing(a, b, match=None):
145 def _computeforwardmissing(a, b, match=None):
146 """Computes which files are in b but not a.
146 """Computes which files are in b but not a.
147 This is its own function so extensions can easily wrap this call to see what
147 This is its own function so extensions can easily wrap this call to see what
148 files _forwardcopies is about to process.
148 files _forwardcopies is about to process.
149 """
149 """
150 ma = a.manifest()
150 ma = a.manifest()
151 mb = b.manifest()
151 mb = b.manifest()
152 if match:
152 if match:
153 ma = ma.matches(match)
153 ma = ma.matches(match)
154 mb = mb.matches(match)
154 mb = mb.matches(match)
155 return mb.filesnotin(ma)
155 return mb.filesnotin(ma)
156
156
157 def _forwardcopies(a, b, match=None):
157 def _forwardcopies(a, b, match=None):
158 '''find {dst@b: src@a} copy mapping where a is an ancestor of b'''
158 '''find {dst@b: src@a} copy mapping where a is an ancestor of b'''
159
159
160 # check for working copy
160 # check for working copy
161 w = None
161 w = None
162 if b.rev() is None:
162 if b.rev() is None:
163 w = b
163 w = b
164 b = w.p1()
164 b = w.p1()
165 if a == b:
165 if a == b:
166 # short-circuit to avoid issues with merge states
166 # short-circuit to avoid issues with merge states
167 return _dirstatecopies(w)
167 return _dirstatecopies(w)
168
168
169 # files might have to be traced back to the fctx parent of the last
169 # files might have to be traced back to the fctx parent of the last
170 # one-side-only changeset, but not further back than that
170 # one-side-only changeset, but not further back than that
171 limit = _findlimit(a._repo, a.rev(), b.rev())
171 limit = _findlimit(a._repo, a.rev(), b.rev())
172 if limit is None:
172 if limit is None:
173 limit = -1
173 limit = -1
174 am = a.manifest()
174 am = a.manifest()
175
175
176 # find where new files came from
176 # find where new files came from
177 # we currently don't try to find where old files went, too expensive
177 # we currently don't try to find where old files went, too expensive
178 # this means we can miss a case like 'hg rm b; hg cp a b'
178 # this means we can miss a case like 'hg rm b; hg cp a b'
179 cm = {}
179 cm = {}
180
180
181 # Computing the forward missing is quite expensive on large manifests, since
181 # Computing the forward missing is quite expensive on large manifests, since
182 # it compares the entire manifests. We can optimize it in the common use
182 # it compares the entire manifests. We can optimize it in the common use
183 # case of computing what copies are in a commit versus its parent (like
183 # case of computing what copies are in a commit versus its parent (like
184 # during a rebase or histedit). Note, we exclude merge commits from this
184 # during a rebase or histedit). Note, we exclude merge commits from this
185 # optimization, since the ctx.files() for a merge commit is not correct for
185 # optimization, since the ctx.files() for a merge commit is not correct for
186 # this comparison.
186 # this comparison.
187 forwardmissingmatch = match
187 forwardmissingmatch = match
188 if not match and b.p1() == a and b.p2().node() == node.nullid:
188 if not match and b.p1() == a and b.p2().node() == node.nullid:
189 forwardmissingmatch = scmutil.matchfiles(a._repo, b.files())
189 forwardmissingmatch = scmutil.matchfiles(a._repo, b.files())
190 missing = _computeforwardmissing(a, b, match=forwardmissingmatch)
190 missing = _computeforwardmissing(a, b, match=forwardmissingmatch)
191
191
192 ancestrycontext = a._repo.changelog.ancestors([b.rev()], inclusive=True)
192 ancestrycontext = a._repo.changelog.ancestors([b.rev()], inclusive=True)
193 for f in missing:
193 for f in missing:
194 fctx = b[f]
194 fctx = b[f]
195 fctx._ancestrycontext = ancestrycontext
195 fctx._ancestrycontext = ancestrycontext
196 ofctx = _tracefile(fctx, am, limit)
196 ofctx = _tracefile(fctx, am, limit)
197 if ofctx:
197 if ofctx:
198 cm[f] = ofctx.path()
198 cm[f] = ofctx.path()
199
199
200 # combine copies from dirstate if necessary
200 # combine copies from dirstate if necessary
201 if w is not None:
201 if w is not None:
202 cm = _chain(a, w, cm, _dirstatecopies(w))
202 cm = _chain(a, w, cm, _dirstatecopies(w))
203
203
204 return cm
204 return cm
205
205
206 def _backwardrenames(a, b):
206 def _backwardrenames(a, b):
207 if a._repo.ui.configbool('experimental', 'disablecopytrace'):
207 if a._repo.ui.configbool('experimental', 'disablecopytrace'):
208 return {}
208 return {}
209
209
210 # Even though we're not taking copies into account, 1:n rename situations
210 # Even though we're not taking copies into account, 1:n rename situations
211 # can still exist (e.g. hg cp a b; hg mv a c). In those cases we
211 # can still exist (e.g. hg cp a b; hg mv a c). In those cases we
212 # arbitrarily pick one of the renames.
212 # arbitrarily pick one of the renames.
213 f = _forwardcopies(b, a)
213 f = _forwardcopies(b, a)
214 r = {}
214 r = {}
215 for k, v in sorted(f.iteritems()):
215 for k, v in sorted(f.iteritems()):
216 # remove copies
216 # remove copies
217 if v in a:
217 if v in a:
218 continue
218 continue
219 r[v] = k
219 r[v] = k
220 return r
220 return r
221
221
222 def pathcopies(x, y, match=None):
222 def pathcopies(x, y, match=None):
223 '''find {dst@y: src@x} copy mapping for directed compare'''
223 '''find {dst@y: src@x} copy mapping for directed compare'''
224 if x == y or not x or not y:
224 if x == y or not x or not y:
225 return {}
225 return {}
226 a = y.ancestor(x)
226 a = y.ancestor(x)
227 if a == x:
227 if a == x:
228 return _forwardcopies(x, y, match=match)
228 return _forwardcopies(x, y, match=match)
229 if a == y:
229 if a == y:
230 return _backwardrenames(x, y)
230 return _backwardrenames(x, y)
231 return _chain(x, y, _backwardrenames(x, a),
231 return _chain(x, y, _backwardrenames(x, a),
232 _forwardcopies(a, y, match=match))
232 _forwardcopies(a, y, match=match))
233
233
234 def _computenonoverlap(repo, c1, c2, addedinm1, addedinm2, baselabel=''):
234 def _computenonoverlap(repo, c1, c2, addedinm1, addedinm2, baselabel=''):
235 """Computes, based on addedinm1 and addedinm2, the files exclusive to c1
235 """Computes, based on addedinm1 and addedinm2, the files exclusive to c1
236 and c2. This is its own function so extensions can easily wrap this call
236 and c2. This is its own function so extensions can easily wrap this call
237 to see what files mergecopies is about to process.
237 to see what files mergecopies is about to process.
238
238
239 Even though c1 and c2 are not used in this function, they are useful in
239 Even though c1 and c2 are not used in this function, they are useful in
240 other extensions for being able to read the file nodes of the changed files.
240 other extensions for being able to read the file nodes of the changed files.
241
241
242 "baselabel" can be passed to help distinguish the multiple computations
242 "baselabel" can be passed to help distinguish the multiple computations
243 done in the graft case.
243 done in the graft case.
244 """
244 """
245 u1 = sorted(addedinm1 - addedinm2)
245 u1 = sorted(addedinm1 - addedinm2)
246 u2 = sorted(addedinm2 - addedinm1)
246 u2 = sorted(addedinm2 - addedinm1)
247
247
248 header = " unmatched files in %s"
248 header = " unmatched files in %s"
249 if baselabel:
249 if baselabel:
250 header += ' (from %s)' % baselabel
250 header += ' (from %s)' % baselabel
251 if u1:
251 if u1:
252 repo.ui.debug("%s:\n %s\n" % (header % 'local', "\n ".join(u1)))
252 repo.ui.debug("%s:\n %s\n" % (header % 'local', "\n ".join(u1)))
253 if u2:
253 if u2:
254 repo.ui.debug("%s:\n %s\n" % (header % 'other', "\n ".join(u2)))
254 repo.ui.debug("%s:\n %s\n" % (header % 'other', "\n ".join(u2)))
255 return u1, u2
255 return u1, u2
256
256
257 def _makegetfctx(ctx):
257 def _makegetfctx(ctx):
258 """return a 'getfctx' function suitable for _checkcopies usage
258 """return a 'getfctx' function suitable for _checkcopies usage
259
259
260 We have to re-setup the function building 'filectx' for each
260 We have to re-setup the function building 'filectx' for each
261 '_checkcopies' to ensure the linkrev adjustment is properly setup for
261 '_checkcopies' to ensure the linkrev adjustment is properly setup for
262 each. Linkrev adjustment is important to avoid bug in rename
262 each. Linkrev adjustment is important to avoid bug in rename
263 detection. Moreover, having a proper '_ancestrycontext' setup ensures
263 detection. Moreover, having a proper '_ancestrycontext' setup ensures
264 the performance impact of this adjustment is kept limited. Without it,
264 the performance impact of this adjustment is kept limited. Without it,
265 each file could do a full dag traversal making the time complexity of
265 each file could do a full dag traversal making the time complexity of
266 the operation explode (see issue4537).
266 the operation explode (see issue4537).
267
267
268 This function exists here mostly to limit the impact on stable. Feel
268 This function exists here mostly to limit the impact on stable. Feel
269 free to refactor on default.
269 free to refactor on default.
270 """
270 """
271 rev = ctx.rev()
271 rev = ctx.rev()
272 repo = ctx._repo
272 repo = ctx._repo
273 ac = getattr(ctx, '_ancestrycontext', None)
273 ac = getattr(ctx, '_ancestrycontext', None)
274 if ac is None:
274 if ac is None:
275 revs = [rev]
275 revs = [rev]
276 if rev is None:
276 if rev is None:
277 revs = [p.rev() for p in ctx.parents()]
277 revs = [p.rev() for p in ctx.parents()]
278 ac = repo.changelog.ancestors(revs, inclusive=True)
278 ac = repo.changelog.ancestors(revs, inclusive=True)
279 ctx._ancestrycontext = ac
279 ctx._ancestrycontext = ac
280 def makectx(f, n):
280 def makectx(f, n):
281 if len(n) != 20: # in a working context?
281 if len(n) != 20: # in a working context?
282 if ctx.rev() is None:
282 if ctx.rev() is None:
283 return ctx.filectx(f)
283 return ctx.filectx(f)
284 return repo[None][f]
284 return repo[None][f]
285 fctx = repo.filectx(f, fileid=n)
285 fctx = repo.filectx(f, fileid=n)
286 # setup only needed for filectx not create from a changectx
286 # setup only needed for filectx not create from a changectx
287 fctx._ancestrycontext = ac
287 fctx._ancestrycontext = ac
288 fctx._descendantrev = rev
288 fctx._descendantrev = rev
289 return fctx
289 return fctx
290 return util.lrucachefunc(makectx)
290 return util.lrucachefunc(makectx)
291
291
292 def mergecopies(repo, c1, c2, base):
292 def mergecopies(repo, c1, c2, base):
293 """
293 """
294 Find moves and copies between context c1 and c2 that are relevant
294 Find moves and copies between context c1 and c2 that are relevant
295 for merging. 'base' will be used as the merge base.
295 for merging. 'base' will be used as the merge base.
296
296
297 Returns four dicts: "copy", "movewithdir", "diverge", and
297 Returns four dicts: "copy", "movewithdir", "diverge", and
298 "renamedelete".
298 "renamedelete".
299
299
300 "copy" is a mapping from destination name -> source name,
300 "copy" is a mapping from destination name -> source name,
301 where source is in c1 and destination is in c2 or vice-versa.
301 where source is in c1 and destination is in c2 or vice-versa.
302
302
303 "movewithdir" is a mapping from source name -> destination name,
303 "movewithdir" is a mapping from source name -> destination name,
304 where the file at source present in one context but not the other
304 where the file at source present in one context but not the other
305 needs to be moved to destination by the merge process, because the
305 needs to be moved to destination by the merge process, because the
306 other context moved the directory it is in.
306 other context moved the directory it is in.
307
307
308 "diverge" is a mapping of source name -> list of destination names
308 "diverge" is a mapping of source name -> list of destination names
309 for divergent renames.
309 for divergent renames.
310
310
311 "renamedelete" is a mapping of source name -> list of destination
311 "renamedelete" is a mapping of source name -> list of destination
312 names for files deleted in c1 that were renamed in c2 or vice-versa.
312 names for files deleted in c1 that were renamed in c2 or vice-versa.
313 """
313 """
314 # avoid silly behavior for update from empty dir
314 # avoid silly behavior for update from empty dir
315 if not c1 or not c2 or c1 == c2:
315 if not c1 or not c2 or c1 == c2:
316 return {}, {}, {}, {}
316 return {}, {}, {}, {}
317
317
318 # avoid silly behavior for parent -> working dir
318 # avoid silly behavior for parent -> working dir
319 if c2.node() is None and c1.node() == repo.dirstate.p1():
319 if c2.node() is None and c1.node() == repo.dirstate.p1():
320 return repo.dirstate.copies(), {}, {}, {}
320 return repo.dirstate.copies(), {}, {}, {}
321
321
322 # Copy trace disabling is explicitly below the node == p1 logic above
322 # Copy trace disabling is explicitly below the node == p1 logic above
323 # because the logic above is required for a simple copy to be kept across a
323 # because the logic above is required for a simple copy to be kept across a
324 # rebase.
324 # rebase.
325 if repo.ui.configbool('experimental', 'disablecopytrace'):
325 if repo.ui.configbool('experimental', 'disablecopytrace'):
326 return {}, {}, {}, {}
326 return {}, {}, {}, {}
327
327
328 # In certain scenarios (e.g. graft, update or rebase), base can be
328 # In certain scenarios (e.g. graft, update or rebase), base can be
329 # overridden We still need to know a real common ancestor in this case We
329 # overridden We still need to know a real common ancestor in this case We
330 # can't just compute _c1.ancestor(_c2) and compare it to ca, because there
330 # can't just compute _c1.ancestor(_c2) and compare it to ca, because there
331 # can be multiple common ancestors, e.g. in case of bidmerge. Because our
331 # can be multiple common ancestors, e.g. in case of bidmerge. Because our
332 # caller may not know if the revision passed in lieu of the CA is a genuine
332 # caller may not know if the revision passed in lieu of the CA is a genuine
333 # common ancestor or not without explicitly checking it, it's better to
333 # common ancestor or not without explicitly checking it, it's better to
334 # determine that here.
334 # determine that here.
335 #
335 #
336 # base.descendant(wc) and base.descendant(base) are False, work around that
336 # base.descendant(wc) and base.descendant(base) are False, work around that
337 _c1 = c1.p1() if c1.rev() is None else c1
337 _c1 = c1.p1() if c1.rev() is None else c1
338 _c2 = c2.p1() if c2.rev() is None else c2
338 _c2 = c2.p1() if c2.rev() is None else c2
339 # an endpoint is "dirty" if it isn't a descendant of the merge base
339 # an endpoint is "dirty" if it isn't a descendant of the merge base
340 # if we have a dirty endpoint, we need to trigger graft logic, and also
340 # if we have a dirty endpoint, we need to trigger graft logic, and also
341 # keep track of which endpoint is dirty
341 # keep track of which endpoint is dirty
342 dirtyc1 = not (base == _c1 or base.descendant(_c1))
342 dirtyc1 = not (base == _c1 or base.descendant(_c1))
343 dirtyc2 = not (base== _c2 or base.descendant(_c2))
343 dirtyc2 = not (base== _c2 or base.descendant(_c2))
344 graft = dirtyc1 or dirtyc2
344 graft = dirtyc1 or dirtyc2
345 tca = base
345 tca = base
346 if graft:
346 if graft:
347 tca = _c1.ancestor(_c2)
347 tca = _c1.ancestor(_c2)
348
348
349 limit = _findlimit(repo, c1.rev(), c2.rev())
349 limit = _findlimit(repo, c1.rev(), c2.rev())
350 if limit is None:
350 if limit is None:
351 # no common ancestor, no copies
351 # no common ancestor, no copies
352 return {}, {}, {}, {}
352 return {}, {}, {}, {}
353 repo.ui.debug(" searching for copies back to rev %d\n" % limit)
353 repo.ui.debug(" searching for copies back to rev %d\n" % limit)
354
354
355 m1 = c1.manifest()
355 m1 = c1.manifest()
356 m2 = c2.manifest()
356 m2 = c2.manifest()
357 mb = base.manifest()
357 mb = base.manifest()
358
358
359 # gather data from _checkcopies:
359 # gather data from _checkcopies:
360 # - diverge = record all diverges in this dict
360 # - diverge = record all diverges in this dict
361 # - copy = record all non-divergent copies in this dict
361 # - copy = record all non-divergent copies in this dict
362 # - fullcopy = record all copies in this dict
362 # - fullcopy = record all copies in this dict
363 diverge = {} # divergence data is shared
363 diverge = {} # divergence data is shared
364 data1 = {'copy': {},
364 data1 = {'copy': {},
365 'fullcopy': {},
365 'fullcopy': {},
366 'diverge': diverge,
366 'diverge': diverge,
367 }
367 }
368 data2 = {'copy': {},
368 data2 = {'copy': {},
369 'fullcopy': {},
369 'fullcopy': {},
370 'diverge': diverge,
370 'diverge': diverge,
371 }
371 }
372
372
373 # find interesting file sets from manifests
373 # find interesting file sets from manifests
374 addedinm1 = m1.filesnotin(mb)
374 addedinm1 = m1.filesnotin(mb)
375 addedinm2 = m2.filesnotin(mb)
375 addedinm2 = m2.filesnotin(mb)
376 u1r, u2r = _computenonoverlap(repo, c1, c2, addedinm1, addedinm2)
377 u1u, u2u = u1r, u2r
378 bothnew = sorted(addedinm1 & addedinm2)
376 bothnew = sorted(addedinm1 & addedinm2)
377 if tca == base:
378 # unmatched file from base
379 u1r, u2r = _computenonoverlap(repo, c1, c2, addedinm1, addedinm2)
380 u1u, u2u = u1r, u2r
381 else:
382 # unmatched file from base (DAG rotation in the graft case)
383 u1r, u2r = _computenonoverlap(repo, c1, c2, addedinm1, addedinm2,
384 baselabel='base')
385 # unmatched file from topological common ancestors (no DAG rotation)
386 # need to recompute this for directory move handling when grafting
387 mta = tca.manifest()
388 u1u, u2u = _computenonoverlap(repo, c1, c2, m1.filesnotin(mta),
389 m2.filesnotin(mta),
390 baselabel='topological common ancestor')
379
391
380 for f in u1u:
392 for f in u1u:
381 _checkcopies(c1, f, m1, m2, base, tca, limit, data1)
393 _checkcopies(c1, f, m1, m2, base, tca, limit, data1)
382
394
383 for f in u2u:
395 for f in u2u:
384 _checkcopies(c2, f, m2, m1, base, tca, limit, data2)
396 _checkcopies(c2, f, m2, m1, base, tca, limit, data2)
385
397
386 copy = dict(data1['copy'].items() + data2['copy'].items())
398 copy = dict(data1['copy'].items() + data2['copy'].items())
387 fullcopy = dict(data1['fullcopy'].items() + data2['fullcopy'].items())
399 fullcopy = dict(data1['fullcopy'].items() + data2['fullcopy'].items())
388
400
389 renamedelete = {}
401 renamedelete = {}
390 renamedeleteset = set()
402 renamedeleteset = set()
391 divergeset = set()
403 divergeset = set()
392 for of, fl in diverge.items():
404 for of, fl in diverge.items():
393 if len(fl) == 1 or of in c1 or of in c2:
405 if len(fl) == 1 or of in c1 or of in c2:
394 del diverge[of] # not actually divergent, or not a rename
406 del diverge[of] # not actually divergent, or not a rename
395 if of not in c1 and of not in c2:
407 if of not in c1 and of not in c2:
396 # renamed on one side, deleted on the other side, but filter
408 # renamed on one side, deleted on the other side, but filter
397 # out files that have been renamed and then deleted
409 # out files that have been renamed and then deleted
398 renamedelete[of] = [f for f in fl if f in c1 or f in c2]
410 renamedelete[of] = [f for f in fl if f in c1 or f in c2]
399 renamedeleteset.update(fl) # reverse map for below
411 renamedeleteset.update(fl) # reverse map for below
400 else:
412 else:
401 divergeset.update(fl) # reverse map for below
413 divergeset.update(fl) # reverse map for below
402
414
403 if bothnew:
415 if bothnew:
404 repo.ui.debug(" unmatched files new in both:\n %s\n"
416 repo.ui.debug(" unmatched files new in both:\n %s\n"
405 % "\n ".join(bothnew))
417 % "\n ".join(bothnew))
406 bothdiverge = {}
418 bothdiverge = {}
407 bothdata = {'copy': {},
419 bothdata = {'copy': {},
408 'fullcopy': {},
420 'fullcopy': {},
409 'diverge': bothdiverge,
421 'diverge': bothdiverge,
410 }
422 }
411 for f in bothnew:
423 for f in bothnew:
412 _checkcopies(c1, f, m1, m2, base, tca, limit, bothdata)
424 _checkcopies(c1, f, m1, m2, base, tca, limit, bothdata)
413 _checkcopies(c2, f, m2, m1, base, tca, limit, bothdata)
425 _checkcopies(c2, f, m2, m1, base, tca, limit, bothdata)
414 for of, fl in bothdiverge.items():
426 for of, fl in bothdiverge.items():
415 if len(fl) == 2 and fl[0] == fl[1]:
427 if len(fl) == 2 and fl[0] == fl[1]:
416 copy[fl[0]] = of # not actually divergent, just matching renames
428 copy[fl[0]] = of # not actually divergent, just matching renames
417
429
418 if fullcopy and repo.ui.debugflag:
430 if fullcopy and repo.ui.debugflag:
419 repo.ui.debug(" all copies found (* = to merge, ! = divergent, "
431 repo.ui.debug(" all copies found (* = to merge, ! = divergent, "
420 "% = renamed and deleted):\n")
432 "% = renamed and deleted):\n")
421 for f in sorted(fullcopy):
433 for f in sorted(fullcopy):
422 note = ""
434 note = ""
423 if f in copy:
435 if f in copy:
424 note += "*"
436 note += "*"
425 if f in divergeset:
437 if f in divergeset:
426 note += "!"
438 note += "!"
427 if f in renamedeleteset:
439 if f in renamedeleteset:
428 note += "%"
440 note += "%"
429 repo.ui.debug(" src: '%s' -> dst: '%s' %s\n" % (fullcopy[f], f,
441 repo.ui.debug(" src: '%s' -> dst: '%s' %s\n" % (fullcopy[f], f,
430 note))
442 note))
431 del divergeset
443 del divergeset
432
444
433 if not fullcopy:
445 if not fullcopy:
434 return copy, {}, diverge, renamedelete
446 return copy, {}, diverge, renamedelete
435
447
436 repo.ui.debug(" checking for directory renames\n")
448 repo.ui.debug(" checking for directory renames\n")
437
449
438 # generate a directory move map
450 # generate a directory move map
439 d1, d2 = c1.dirs(), c2.dirs()
451 d1, d2 = c1.dirs(), c2.dirs()
440 # Hack for adding '', which is not otherwise added, to d1 and d2
452 # Hack for adding '', which is not otherwise added, to d1 and d2
441 d1.addpath('/')
453 d1.addpath('/')
442 d2.addpath('/')
454 d2.addpath('/')
443 invalid = set()
455 invalid = set()
444 dirmove = {}
456 dirmove = {}
445
457
446 # examine each file copy for a potential directory move, which is
458 # examine each file copy for a potential directory move, which is
447 # when all the files in a directory are moved to a new directory
459 # when all the files in a directory are moved to a new directory
448 for dst, src in fullcopy.iteritems():
460 for dst, src in fullcopy.iteritems():
449 dsrc, ddst = pathutil.dirname(src), pathutil.dirname(dst)
461 dsrc, ddst = pathutil.dirname(src), pathutil.dirname(dst)
450 if dsrc in invalid:
462 if dsrc in invalid:
451 # already seen to be uninteresting
463 # already seen to be uninteresting
452 continue
464 continue
453 elif dsrc in d1 and ddst in d1:
465 elif dsrc in d1 and ddst in d1:
454 # directory wasn't entirely moved locally
466 # directory wasn't entirely moved locally
455 invalid.add(dsrc + "/")
467 invalid.add(dsrc + "/")
456 elif dsrc in d2 and ddst in d2:
468 elif dsrc in d2 and ddst in d2:
457 # directory wasn't entirely moved remotely
469 # directory wasn't entirely moved remotely
458 invalid.add(dsrc + "/")
470 invalid.add(dsrc + "/")
459 elif dsrc + "/" in dirmove and dirmove[dsrc + "/"] != ddst + "/":
471 elif dsrc + "/" in dirmove and dirmove[dsrc + "/"] != ddst + "/":
460 # files from the same directory moved to two different places
472 # files from the same directory moved to two different places
461 invalid.add(dsrc + "/")
473 invalid.add(dsrc + "/")
462 else:
474 else:
463 # looks good so far
475 # looks good so far
464 dirmove[dsrc + "/"] = ddst + "/"
476 dirmove[dsrc + "/"] = ddst + "/"
465
477
466 for i in invalid:
478 for i in invalid:
467 if i in dirmove:
479 if i in dirmove:
468 del dirmove[i]
480 del dirmove[i]
469 del d1, d2, invalid
481 del d1, d2, invalid
470
482
471 if not dirmove:
483 if not dirmove:
472 return copy, {}, diverge, renamedelete
484 return copy, {}, diverge, renamedelete
473
485
474 for d in dirmove:
486 for d in dirmove:
475 repo.ui.debug(" discovered dir src: '%s' -> dst: '%s'\n" %
487 repo.ui.debug(" discovered dir src: '%s' -> dst: '%s'\n" %
476 (d, dirmove[d]))
488 (d, dirmove[d]))
477
489
478 movewithdir = {}
490 movewithdir = {}
479 # check unaccounted nonoverlapping files against directory moves
491 # check unaccounted nonoverlapping files against directory moves
480 for f in u1r + u2r:
492 for f in u1r + u2r:
481 if f not in fullcopy:
493 if f not in fullcopy:
482 for d in dirmove:
494 for d in dirmove:
483 if f.startswith(d):
495 if f.startswith(d):
484 # new file added in a directory that was moved, move it
496 # new file added in a directory that was moved, move it
485 df = dirmove[d] + f[len(d):]
497 df = dirmove[d] + f[len(d):]
486 if df not in copy:
498 if df not in copy:
487 movewithdir[f] = df
499 movewithdir[f] = df
488 repo.ui.debug((" pending file src: '%s' -> "
500 repo.ui.debug((" pending file src: '%s' -> "
489 "dst: '%s'\n") % (f, df))
501 "dst: '%s'\n") % (f, df))
490 break
502 break
491
503
492 return copy, movewithdir, diverge, renamedelete
504 return copy, movewithdir, diverge, renamedelete
493
505
494 def _related(f1, f2, limit):
506 def _related(f1, f2, limit):
495 """return True if f1 and f2 filectx have a common ancestor
507 """return True if f1 and f2 filectx have a common ancestor
496
508
497 Walk back to common ancestor to see if the two files originate
509 Walk back to common ancestor to see if the two files originate
498 from the same file. Since workingfilectx's rev() is None it messes
510 from the same file. Since workingfilectx's rev() is None it messes
499 up the integer comparison logic, hence the pre-step check for
511 up the integer comparison logic, hence the pre-step check for
500 None (f1 and f2 can only be workingfilectx's initially).
512 None (f1 and f2 can only be workingfilectx's initially).
501 """
513 """
502
514
503 if f1 == f2:
515 if f1 == f2:
504 return f1 # a match
516 return f1 # a match
505
517
506 g1, g2 = f1.ancestors(), f2.ancestors()
518 g1, g2 = f1.ancestors(), f2.ancestors()
507 try:
519 try:
508 f1r, f2r = f1.linkrev(), f2.linkrev()
520 f1r, f2r = f1.linkrev(), f2.linkrev()
509
521
510 if f1r is None:
522 if f1r is None:
511 f1 = next(g1)
523 f1 = next(g1)
512 if f2r is None:
524 if f2r is None:
513 f2 = next(g2)
525 f2 = next(g2)
514
526
515 while True:
527 while True:
516 f1r, f2r = f1.linkrev(), f2.linkrev()
528 f1r, f2r = f1.linkrev(), f2.linkrev()
517 if f1r > f2r:
529 if f1r > f2r:
518 f1 = next(g1)
530 f1 = next(g1)
519 elif f2r > f1r:
531 elif f2r > f1r:
520 f2 = next(g2)
532 f2 = next(g2)
521 elif f1 == f2:
533 elif f1 == f2:
522 return f1 # a match
534 return f1 # a match
523 elif f1r == f2r or f1r < limit or f2r < limit:
535 elif f1r == f2r or f1r < limit or f2r < limit:
524 return False # copy no longer relevant
536 return False # copy no longer relevant
525 except StopIteration:
537 except StopIteration:
526 return False
538 return False
527
539
528 def _checkcopies(ctx, f, m1, m2, base, tca, limit, data):
540 def _checkcopies(ctx, f, m1, m2, base, tca, limit, data):
529 """
541 """
530 check possible copies of f from m1 to m2
542 check possible copies of f from m1 to m2
531
543
532 ctx = starting context for f in m1
544 ctx = starting context for f in m1
533 f = the filename to check (as in m1)
545 f = the filename to check (as in m1)
534 m1 = the source manifest
546 m1 = the source manifest
535 m2 = the destination manifest
547 m2 = the destination manifest
536 base = the changectx used as a merge base
548 base = the changectx used as a merge base
537 tca = topological common ancestor for graft-like scenarios
549 tca = topological common ancestor for graft-like scenarios
538 limit = the rev number to not search beyond
550 limit = the rev number to not search beyond
539 data = dictionary of dictionary to store copy data. (see mergecopies)
551 data = dictionary of dictionary to store copy data. (see mergecopies)
540
552
541 note: limit is only an optimization, and there is no guarantee that
553 note: limit is only an optimization, and there is no guarantee that
542 irrelevant revisions will not be limited
554 irrelevant revisions will not be limited
543 there is no easy way to make this algorithm stop in a guaranteed way
555 there is no easy way to make this algorithm stop in a guaranteed way
544 once it "goes behind a certain revision".
556 once it "goes behind a certain revision".
545 """
557 """
546
558
547 mb = base.manifest()
559 mb = base.manifest()
548 # Might be true if this call is about finding backward renames,
560 # Might be true if this call is about finding backward renames,
549 # This happens in the case of grafts because the DAG is then rotated.
561 # This happens in the case of grafts because the DAG is then rotated.
550 # If the file exists in both the base and the source, we are not looking
562 # If the file exists in both the base and the source, we are not looking
551 # for a rename on the source side, but on the part of the DAG that is
563 # for a rename on the source side, but on the part of the DAG that is
552 # traversed backwards.
564 # traversed backwards.
553 #
565 #
554 # In the case there is both backward and forward renames (before and after
566 # In the case there is both backward and forward renames (before and after
555 # the base) this is more complicated as we must detect a divergence. This
567 # the base) this is more complicated as we must detect a divergence. This
556 # is currently broken and hopefully some later code update will make that
568 # is currently broken and hopefully some later code update will make that
557 # work (we use 'backwards = False' in that case)
569 # work (we use 'backwards = False' in that case)
558 backwards = base != tca and f in mb
570 backwards = base != tca and f in mb
559 getfctx = _makegetfctx(ctx)
571 getfctx = _makegetfctx(ctx)
560
572
561 of = None
573 of = None
562 seen = set([f])
574 seen = set([f])
563 for oc in getfctx(f, m1[f]).ancestors():
575 for oc in getfctx(f, m1[f]).ancestors():
564 ocr = oc.linkrev()
576 ocr = oc.linkrev()
565 of = oc.path()
577 of = oc.path()
566 if of in seen:
578 if of in seen:
567 # check limit late - grab last rename before
579 # check limit late - grab last rename before
568 if ocr < limit:
580 if ocr < limit:
569 break
581 break
570 continue
582 continue
571 seen.add(of)
583 seen.add(of)
572
584
573 # remember for dir rename detection
585 # remember for dir rename detection
574 if backwards:
586 if backwards:
575 data['fullcopy'][of] = f # grafting backwards through renames
587 data['fullcopy'][of] = f # grafting backwards through renames
576 else:
588 else:
577 data['fullcopy'][f] = of
589 data['fullcopy'][f] = of
578 if of not in m2:
590 if of not in m2:
579 continue # no match, keep looking
591 continue # no match, keep looking
580 if m2[of] == mb.get(of):
592 if m2[of] == mb.get(of):
581 return # no merge needed, quit early
593 return # no merge needed, quit early
582 c2 = getfctx(of, m2[of])
594 c2 = getfctx(of, m2[of])
583 # c2 might be a plain new file on added on destination side that is
595 # c2 might be a plain new file on added on destination side that is
584 # unrelated to the droids we are looking for.
596 # unrelated to the droids we are looking for.
585 cr = _related(oc, c2, tca.rev())
597 cr = _related(oc, c2, tca.rev())
586 if cr and (of == f or of == c2.path()): # non-divergent
598 if cr and (of == f or of == c2.path()): # non-divergent
587 if backwards:
599 if backwards:
588 data['copy'][of] = f
600 data['copy'][of] = f
589 elif of in mb:
601 elif of in mb:
590 data['copy'][f] = of
602 data['copy'][f] = of
591 return
603 return
592
604
593 if of in mb:
605 if of in mb:
594 data['diverge'].setdefault(of, []).append(f)
606 data['diverge'].setdefault(of, []).append(f)
595
607
596 def duplicatecopies(repo, rev, fromrev, skiprev=None):
608 def duplicatecopies(repo, rev, fromrev, skiprev=None):
597 '''reproduce copies from fromrev to rev in the dirstate
609 '''reproduce copies from fromrev to rev in the dirstate
598
610
599 If skiprev is specified, it's a revision that should be used to
611 If skiprev is specified, it's a revision that should be used to
600 filter copy records. Any copies that occur between fromrev and
612 filter copy records. Any copies that occur between fromrev and
601 skiprev will not be duplicated, even if they appear in the set of
613 skiprev will not be duplicated, even if they appear in the set of
602 copies between fromrev and rev.
614 copies between fromrev and rev.
603 '''
615 '''
604 exclude = {}
616 exclude = {}
605 if (skiprev is not None and
617 if (skiprev is not None and
606 not repo.ui.configbool('experimental', 'disablecopytrace')):
618 not repo.ui.configbool('experimental', 'disablecopytrace')):
607 # disablecopytrace skips this line, but not the entire function because
619 # disablecopytrace skips this line, but not the entire function because
608 # the line below is O(size of the repo) during a rebase, while the rest
620 # the line below is O(size of the repo) during a rebase, while the rest
609 # of the function is much faster (and is required for carrying copy
621 # of the function is much faster (and is required for carrying copy
610 # metadata across the rebase anyway).
622 # metadata across the rebase anyway).
611 exclude = pathcopies(repo[fromrev], repo[skiprev])
623 exclude = pathcopies(repo[fromrev], repo[skiprev])
612 for dst, src in pathcopies(repo[fromrev], repo[rev]).iteritems():
624 for dst, src in pathcopies(repo[fromrev], repo[rev]).iteritems():
613 # copies.pathcopies returns backward renames, so dst might not
625 # copies.pathcopies returns backward renames, so dst might not
614 # actually be in the dirstate
626 # actually be in the dirstate
615 if dst in exclude:
627 if dst in exclude:
616 continue
628 continue
617 if repo.dirstate[dst] in "nma":
629 if repo.dirstate[dst] in "nma":
618 repo.dirstate.copy(src, dst)
630 repo.dirstate.copy(src, dst)
@@ -1,1302 +1,1333
1 $ cat >> $HGRCPATH <<EOF
1 $ cat >> $HGRCPATH <<EOF
2 > [extdiff]
2 > [extdiff]
3 > # for portability:
3 > # for portability:
4 > pdiff = sh "$RUNTESTDIR/pdiff"
4 > pdiff = sh "$RUNTESTDIR/pdiff"
5 > EOF
5 > EOF
6
6
7 Create a repo with some stuff in it:
7 Create a repo with some stuff in it:
8
8
9 $ hg init a
9 $ hg init a
10 $ cd a
10 $ cd a
11 $ echo a > a
11 $ echo a > a
12 $ echo a > d
12 $ echo a > d
13 $ echo a > e
13 $ echo a > e
14 $ hg ci -qAm0
14 $ hg ci -qAm0
15 $ echo b > a
15 $ echo b > a
16 $ hg ci -m1 -u bar
16 $ hg ci -m1 -u bar
17 $ hg mv a b
17 $ hg mv a b
18 $ hg ci -m2
18 $ hg ci -m2
19 $ hg cp b c
19 $ hg cp b c
20 $ hg ci -m3 -u baz
20 $ hg ci -m3 -u baz
21 $ echo b > d
21 $ echo b > d
22 $ echo f > e
22 $ echo f > e
23 $ hg ci -m4
23 $ hg ci -m4
24 $ hg up -q 3
24 $ hg up -q 3
25 $ echo b > e
25 $ echo b > e
26 $ hg branch -q stable
26 $ hg branch -q stable
27 $ hg ci -m5
27 $ hg ci -m5
28 $ hg merge -q default --tool internal:local
28 $ hg merge -q default --tool internal:local
29 $ hg branch -q default
29 $ hg branch -q default
30 $ hg ci -m6
30 $ hg ci -m6
31 $ hg phase --public 3
31 $ hg phase --public 3
32 $ hg phase --force --secret 6
32 $ hg phase --force --secret 6
33
33
34 $ hg log -G --template '{author}@{rev}.{phase}: {desc}\n'
34 $ hg log -G --template '{author}@{rev}.{phase}: {desc}\n'
35 @ test@6.secret: 6
35 @ test@6.secret: 6
36 |\
36 |\
37 | o test@5.draft: 5
37 | o test@5.draft: 5
38 | |
38 | |
39 o | test@4.draft: 4
39 o | test@4.draft: 4
40 |/
40 |/
41 o baz@3.public: 3
41 o baz@3.public: 3
42 |
42 |
43 o test@2.public: 2
43 o test@2.public: 2
44 |
44 |
45 o bar@1.public: 1
45 o bar@1.public: 1
46 |
46 |
47 o test@0.public: 0
47 o test@0.public: 0
48
48
49 Can't continue without starting:
49 Can't continue without starting:
50
50
51 $ hg rm -q e
51 $ hg rm -q e
52 $ hg graft --continue
52 $ hg graft --continue
53 abort: no graft in progress
53 abort: no graft in progress
54 [255]
54 [255]
55 $ hg revert -r . -q e
55 $ hg revert -r . -q e
56
56
57 Need to specify a rev:
57 Need to specify a rev:
58
58
59 $ hg graft
59 $ hg graft
60 abort: no revisions specified
60 abort: no revisions specified
61 [255]
61 [255]
62
62
63 Can't graft ancestor:
63 Can't graft ancestor:
64
64
65 $ hg graft 1 2
65 $ hg graft 1 2
66 skipping ancestor revision 1:5d205f8b35b6
66 skipping ancestor revision 1:5d205f8b35b6
67 skipping ancestor revision 2:5c095ad7e90f
67 skipping ancestor revision 2:5c095ad7e90f
68 [255]
68 [255]
69
69
70 Specify revisions with -r:
70 Specify revisions with -r:
71
71
72 $ hg graft -r 1 -r 2
72 $ hg graft -r 1 -r 2
73 skipping ancestor revision 1:5d205f8b35b6
73 skipping ancestor revision 1:5d205f8b35b6
74 skipping ancestor revision 2:5c095ad7e90f
74 skipping ancestor revision 2:5c095ad7e90f
75 [255]
75 [255]
76
76
77 $ hg graft -r 1 2
77 $ hg graft -r 1 2
78 warning: inconsistent use of --rev might give unexpected revision ordering!
78 warning: inconsistent use of --rev might give unexpected revision ordering!
79 skipping ancestor revision 2:5c095ad7e90f
79 skipping ancestor revision 2:5c095ad7e90f
80 skipping ancestor revision 1:5d205f8b35b6
80 skipping ancestor revision 1:5d205f8b35b6
81 [255]
81 [255]
82
82
83 Can't graft with dirty wd:
83 Can't graft with dirty wd:
84
84
85 $ hg up -q 0
85 $ hg up -q 0
86 $ echo foo > a
86 $ echo foo > a
87 $ hg graft 1
87 $ hg graft 1
88 abort: uncommitted changes
88 abort: uncommitted changes
89 [255]
89 [255]
90 $ hg revert a
90 $ hg revert a
91
91
92 Graft a rename:
92 Graft a rename:
93 (this also tests that editor is invoked if '--edit' is specified)
93 (this also tests that editor is invoked if '--edit' is specified)
94
94
95 $ hg status --rev "2^1" --rev 2
95 $ hg status --rev "2^1" --rev 2
96 A b
96 A b
97 R a
97 R a
98 $ HGEDITOR=cat hg graft 2 -u foo --edit
98 $ HGEDITOR=cat hg graft 2 -u foo --edit
99 grafting 2:5c095ad7e90f "2"
99 grafting 2:5c095ad7e90f "2"
100 merging a and b to b
100 merging a and b to b
101 2
101 2
102
102
103
103
104 HG: Enter commit message. Lines beginning with 'HG:' are removed.
104 HG: Enter commit message. Lines beginning with 'HG:' are removed.
105 HG: Leave message empty to abort commit.
105 HG: Leave message empty to abort commit.
106 HG: --
106 HG: --
107 HG: user: foo
107 HG: user: foo
108 HG: branch 'default'
108 HG: branch 'default'
109 HG: added b
109 HG: added b
110 HG: removed a
110 HG: removed a
111 $ hg export tip --git
111 $ hg export tip --git
112 # HG changeset patch
112 # HG changeset patch
113 # User foo
113 # User foo
114 # Date 0 0
114 # Date 0 0
115 # Thu Jan 01 00:00:00 1970 +0000
115 # Thu Jan 01 00:00:00 1970 +0000
116 # Node ID ef0ef43d49e79e81ddafdc7997401ba0041efc82
116 # Node ID ef0ef43d49e79e81ddafdc7997401ba0041efc82
117 # Parent 68795b066622ca79a25816a662041d8f78f3cd9e
117 # Parent 68795b066622ca79a25816a662041d8f78f3cd9e
118 2
118 2
119
119
120 diff --git a/a b/b
120 diff --git a/a b/b
121 rename from a
121 rename from a
122 rename to b
122 rename to b
123
123
124 Look for extra:source
124 Look for extra:source
125
125
126 $ hg log --debug -r tip
126 $ hg log --debug -r tip
127 changeset: 7:ef0ef43d49e79e81ddafdc7997401ba0041efc82
127 changeset: 7:ef0ef43d49e79e81ddafdc7997401ba0041efc82
128 tag: tip
128 tag: tip
129 phase: draft
129 phase: draft
130 parent: 0:68795b066622ca79a25816a662041d8f78f3cd9e
130 parent: 0:68795b066622ca79a25816a662041d8f78f3cd9e
131 parent: -1:0000000000000000000000000000000000000000
131 parent: -1:0000000000000000000000000000000000000000
132 manifest: 7:e59b6b228f9cbf9903d5e9abf996e083a1f533eb
132 manifest: 7:e59b6b228f9cbf9903d5e9abf996e083a1f533eb
133 user: foo
133 user: foo
134 date: Thu Jan 01 00:00:00 1970 +0000
134 date: Thu Jan 01 00:00:00 1970 +0000
135 files+: b
135 files+: b
136 files-: a
136 files-: a
137 extra: branch=default
137 extra: branch=default
138 extra: source=5c095ad7e90f871700f02dd1fa5012cb4498a2d4
138 extra: source=5c095ad7e90f871700f02dd1fa5012cb4498a2d4
139 description:
139 description:
140 2
140 2
141
141
142
142
143
143
144 Graft out of order, skipping a merge and a duplicate
144 Graft out of order, skipping a merge and a duplicate
145 (this also tests that editor is not invoked if '--edit' is not specified)
145 (this also tests that editor is not invoked if '--edit' is not specified)
146
146
147 $ hg graft 1 5 4 3 'merge()' 2 -n
147 $ hg graft 1 5 4 3 'merge()' 2 -n
148 skipping ungraftable merge revision 6
148 skipping ungraftable merge revision 6
149 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
149 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
150 grafting 1:5d205f8b35b6 "1"
150 grafting 1:5d205f8b35b6 "1"
151 grafting 5:97f8bfe72746 "5"
151 grafting 5:97f8bfe72746 "5"
152 grafting 4:9c233e8e184d "4"
152 grafting 4:9c233e8e184d "4"
153 grafting 3:4c60f11aa304 "3"
153 grafting 3:4c60f11aa304 "3"
154
154
155 $ HGEDITOR=cat hg graft 1 5 'merge()' 2 --debug
155 $ HGEDITOR=cat hg graft 1 5 'merge()' 2 --debug
156 skipping ungraftable merge revision 6
156 skipping ungraftable merge revision 6
157 scanning for duplicate grafts
157 scanning for duplicate grafts
158 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
158 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
159 grafting 1:5d205f8b35b6 "1"
159 grafting 1:5d205f8b35b6 "1"
160 searching for copies back to rev 1
160 searching for copies back to rev 1
161 unmatched files in local:
161 unmatched files in local:
162 b
162 b
163 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
163 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
164 src: 'a' -> dst: 'b' *
164 src: 'a' -> dst: 'b' *
165 checking for directory renames
165 checking for directory renames
166 resolving manifests
166 resolving manifests
167 branchmerge: True, force: True, partial: False
167 branchmerge: True, force: True, partial: False
168 ancestor: 68795b066622, local: ef0ef43d49e7+, remote: 5d205f8b35b6
168 ancestor: 68795b066622, local: ef0ef43d49e7+, remote: 5d205f8b35b6
169 preserving b for resolve of b
169 preserving b for resolve of b
170 starting 4 threads for background file closing (?)
170 starting 4 threads for background file closing (?)
171 b: local copied/moved from a -> m (premerge)
171 b: local copied/moved from a -> m (premerge)
172 picked tool ':merge' for b (binary False symlink False changedelete False)
172 picked tool ':merge' for b (binary False symlink False changedelete False)
173 merging b and a to b
173 merging b and a to b
174 my b@ef0ef43d49e7+ other a@5d205f8b35b6 ancestor a@68795b066622
174 my b@ef0ef43d49e7+ other a@5d205f8b35b6 ancestor a@68795b066622
175 premerge successful
175 premerge successful
176 committing files:
176 committing files:
177 b
177 b
178 committing manifest
178 committing manifest
179 committing changelog
179 committing changelog
180 grafting 5:97f8bfe72746 "5"
180 grafting 5:97f8bfe72746 "5"
181 searching for copies back to rev 1
181 searching for copies back to rev 1
182 unmatched files in other (from topological common ancestor):
183 c
184 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
185 src: 'c' -> dst: 'b' *
186 checking for directory renames
182 resolving manifests
187 resolving manifests
183 branchmerge: True, force: True, partial: False
188 branchmerge: True, force: True, partial: False
184 ancestor: 4c60f11aa304, local: 6b9e5368ca4e+, remote: 97f8bfe72746
189 ancestor: 4c60f11aa304, local: 6b9e5368ca4e+, remote: 97f8bfe72746
185 e: remote is newer -> g
190 e: remote is newer -> g
186 getting e
191 getting e
187 b: remote unchanged -> k
192 b: remote unchanged -> k
188 committing files:
193 committing files:
189 e
194 e
190 committing manifest
195 committing manifest
191 committing changelog
196 committing changelog
192 $ HGEDITOR=cat hg graft 4 3 --log --debug
197 $ HGEDITOR=cat hg graft 4 3 --log --debug
193 scanning for duplicate grafts
198 scanning for duplicate grafts
194 grafting 4:9c233e8e184d "4"
199 grafting 4:9c233e8e184d "4"
195 searching for copies back to rev 1
200 searching for copies back to rev 1
201 unmatched files in other (from topological common ancestor):
202 c
203 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
204 src: 'c' -> dst: 'b' *
205 checking for directory renames
196 resolving manifests
206 resolving manifests
197 branchmerge: True, force: True, partial: False
207 branchmerge: True, force: True, partial: False
198 ancestor: 4c60f11aa304, local: 1905859650ec+, remote: 9c233e8e184d
208 ancestor: 4c60f11aa304, local: 1905859650ec+, remote: 9c233e8e184d
199 preserving e for resolve of e
209 preserving e for resolve of e
200 d: remote is newer -> g
210 d: remote is newer -> g
201 getting d
211 getting d
202 b: remote unchanged -> k
212 b: remote unchanged -> k
203 e: versions differ -> m (premerge)
213 e: versions differ -> m (premerge)
204 picked tool ':merge' for e (binary False symlink False changedelete False)
214 picked tool ':merge' for e (binary False symlink False changedelete False)
205 merging e
215 merging e
206 my e@1905859650ec+ other e@9c233e8e184d ancestor e@4c60f11aa304
216 my e@1905859650ec+ other e@9c233e8e184d ancestor e@4c60f11aa304
207 e: versions differ -> m (merge)
217 e: versions differ -> m (merge)
208 picked tool ':merge' for e (binary False symlink False changedelete False)
218 picked tool ':merge' for e (binary False symlink False changedelete False)
209 my e@1905859650ec+ other e@9c233e8e184d ancestor e@4c60f11aa304
219 my e@1905859650ec+ other e@9c233e8e184d ancestor e@4c60f11aa304
210 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
220 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
211 abort: unresolved conflicts, can't continue
221 abort: unresolved conflicts, can't continue
212 (use 'hg resolve' and 'hg graft --continue --log')
222 (use 'hg resolve' and 'hg graft --continue --log')
213 [255]
223 [255]
214
224
215 Summary should mention graft:
225 Summary should mention graft:
216
226
217 $ hg summary |grep graft
227 $ hg summary |grep graft
218 commit: 2 modified, 2 unknown, 1 unresolved (graft in progress)
228 commit: 2 modified, 2 unknown, 1 unresolved (graft in progress)
219
229
220 Commit while interrupted should fail:
230 Commit while interrupted should fail:
221
231
222 $ hg ci -m 'commit interrupted graft'
232 $ hg ci -m 'commit interrupted graft'
223 abort: graft in progress
233 abort: graft in progress
224 (use 'hg graft --continue' or 'hg update' to abort)
234 (use 'hg graft --continue' or 'hg update' to abort)
225 [255]
235 [255]
226
236
227 Abort the graft and try committing:
237 Abort the graft and try committing:
228
238
229 $ hg up -C .
239 $ hg up -C .
230 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
240 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
231 $ echo c >> e
241 $ echo c >> e
232 $ hg ci -mtest
242 $ hg ci -mtest
233
243
234 $ hg strip . --config extensions.strip=
244 $ hg strip . --config extensions.strip=
235 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
245 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
236 saved backup bundle to $TESTTMP/a/.hg/strip-backup/*-backup.hg (glob)
246 saved backup bundle to $TESTTMP/a/.hg/strip-backup/*-backup.hg (glob)
237
247
238 Graft again:
248 Graft again:
239
249
240 $ hg graft 1 5 4 3 'merge()' 2
250 $ hg graft 1 5 4 3 'merge()' 2
241 skipping ungraftable merge revision 6
251 skipping ungraftable merge revision 6
242 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
252 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
243 skipping revision 1:5d205f8b35b6 (already grafted to 8:6b9e5368ca4e)
253 skipping revision 1:5d205f8b35b6 (already grafted to 8:6b9e5368ca4e)
244 skipping revision 5:97f8bfe72746 (already grafted to 9:1905859650ec)
254 skipping revision 5:97f8bfe72746 (already grafted to 9:1905859650ec)
245 grafting 4:9c233e8e184d "4"
255 grafting 4:9c233e8e184d "4"
246 merging e
256 merging e
247 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
257 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
248 abort: unresolved conflicts, can't continue
258 abort: unresolved conflicts, can't continue
249 (use 'hg resolve' and 'hg graft --continue')
259 (use 'hg resolve' and 'hg graft --continue')
250 [255]
260 [255]
251
261
252 Continue without resolve should fail:
262 Continue without resolve should fail:
253
263
254 $ hg graft -c
264 $ hg graft -c
255 grafting 4:9c233e8e184d "4"
265 grafting 4:9c233e8e184d "4"
256 abort: unresolved merge conflicts (see 'hg help resolve')
266 abort: unresolved merge conflicts (see 'hg help resolve')
257 [255]
267 [255]
258
268
259 Fix up:
269 Fix up:
260
270
261 $ echo b > e
271 $ echo b > e
262 $ hg resolve -m e
272 $ hg resolve -m e
263 (no more unresolved files)
273 (no more unresolved files)
264 continue: hg graft --continue
274 continue: hg graft --continue
265
275
266 Continue with a revision should fail:
276 Continue with a revision should fail:
267
277
268 $ hg graft -c 6
278 $ hg graft -c 6
269 abort: can't specify --continue and revisions
279 abort: can't specify --continue and revisions
270 [255]
280 [255]
271
281
272 $ hg graft -c -r 6
282 $ hg graft -c -r 6
273 abort: can't specify --continue and revisions
283 abort: can't specify --continue and revisions
274 [255]
284 [255]
275
285
276 Continue for real, clobber usernames
286 Continue for real, clobber usernames
277
287
278 $ hg graft -c -U
288 $ hg graft -c -U
279 grafting 4:9c233e8e184d "4"
289 grafting 4:9c233e8e184d "4"
280 grafting 3:4c60f11aa304 "3"
290 grafting 3:4c60f11aa304 "3"
281
291
282 Compare with original:
292 Compare with original:
283
293
284 $ hg diff -r 6
294 $ hg diff -r 6
285 $ hg status --rev 0:. -C
295 $ hg status --rev 0:. -C
286 M d
296 M d
287 M e
297 M e
288 A b
298 A b
289 a
299 a
290 A c
300 A c
291 a
301 a
292 R a
302 R a
293
303
294 View graph:
304 View graph:
295
305
296 $ hg log -G --template '{author}@{rev}.{phase}: {desc}\n'
306 $ hg log -G --template '{author}@{rev}.{phase}: {desc}\n'
297 @ test@11.draft: 3
307 @ test@11.draft: 3
298 |
308 |
299 o test@10.draft: 4
309 o test@10.draft: 4
300 |
310 |
301 o test@9.draft: 5
311 o test@9.draft: 5
302 |
312 |
303 o bar@8.draft: 1
313 o bar@8.draft: 1
304 |
314 |
305 o foo@7.draft: 2
315 o foo@7.draft: 2
306 |
316 |
307 | o test@6.secret: 6
317 | o test@6.secret: 6
308 | |\
318 | |\
309 | | o test@5.draft: 5
319 | | o test@5.draft: 5
310 | | |
320 | | |
311 | o | test@4.draft: 4
321 | o | test@4.draft: 4
312 | |/
322 | |/
313 | o baz@3.public: 3
323 | o baz@3.public: 3
314 | |
324 | |
315 | o test@2.public: 2
325 | o test@2.public: 2
316 | |
326 | |
317 | o bar@1.public: 1
327 | o bar@1.public: 1
318 |/
328 |/
319 o test@0.public: 0
329 o test@0.public: 0
320
330
321 Graft again onto another branch should preserve the original source
331 Graft again onto another branch should preserve the original source
322 $ hg up -q 0
332 $ hg up -q 0
323 $ echo 'g'>g
333 $ echo 'g'>g
324 $ hg add g
334 $ hg add g
325 $ hg ci -m 7
335 $ hg ci -m 7
326 created new head
336 created new head
327 $ hg graft 7
337 $ hg graft 7
328 grafting 7:ef0ef43d49e7 "2"
338 grafting 7:ef0ef43d49e7 "2"
329
339
330 $ hg log -r 7 --template '{rev}:{node}\n'
340 $ hg log -r 7 --template '{rev}:{node}\n'
331 7:ef0ef43d49e79e81ddafdc7997401ba0041efc82
341 7:ef0ef43d49e79e81ddafdc7997401ba0041efc82
332 $ hg log -r 2 --template '{rev}:{node}\n'
342 $ hg log -r 2 --template '{rev}:{node}\n'
333 2:5c095ad7e90f871700f02dd1fa5012cb4498a2d4
343 2:5c095ad7e90f871700f02dd1fa5012cb4498a2d4
334
344
335 $ hg log --debug -r tip
345 $ hg log --debug -r tip
336 changeset: 13:7a4785234d87ec1aa420ed6b11afe40fa73e12a9
346 changeset: 13:7a4785234d87ec1aa420ed6b11afe40fa73e12a9
337 tag: tip
347 tag: tip
338 phase: draft
348 phase: draft
339 parent: 12:b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
349 parent: 12:b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
340 parent: -1:0000000000000000000000000000000000000000
350 parent: -1:0000000000000000000000000000000000000000
341 manifest: 13:dc313617b8c32457c0d589e0dbbedfe71f3cd637
351 manifest: 13:dc313617b8c32457c0d589e0dbbedfe71f3cd637
342 user: foo
352 user: foo
343 date: Thu Jan 01 00:00:00 1970 +0000
353 date: Thu Jan 01 00:00:00 1970 +0000
344 files+: b
354 files+: b
345 files-: a
355 files-: a
346 extra: branch=default
356 extra: branch=default
347 extra: intermediate-source=ef0ef43d49e79e81ddafdc7997401ba0041efc82
357 extra: intermediate-source=ef0ef43d49e79e81ddafdc7997401ba0041efc82
348 extra: source=5c095ad7e90f871700f02dd1fa5012cb4498a2d4
358 extra: source=5c095ad7e90f871700f02dd1fa5012cb4498a2d4
349 description:
359 description:
350 2
360 2
351
361
352
362
353 Disallow grafting an already grafted cset onto its original branch
363 Disallow grafting an already grafted cset onto its original branch
354 $ hg up -q 6
364 $ hg up -q 6
355 $ hg graft 7
365 $ hg graft 7
356 skipping already grafted revision 7:ef0ef43d49e7 (was grafted from 2:5c095ad7e90f)
366 skipping already grafted revision 7:ef0ef43d49e7 (was grafted from 2:5c095ad7e90f)
357 [255]
367 [255]
358
368
359 $ hg pdiff --config extensions.extdiff= --patch -r 2 -r 13
369 $ hg pdiff --config extensions.extdiff= --patch -r 2 -r 13
360 --- */hg-5c095ad7e90f.patch * (glob)
370 --- */hg-5c095ad7e90f.patch * (glob)
361 +++ */hg-7a4785234d87.patch * (glob)
371 +++ */hg-7a4785234d87.patch * (glob)
362 @@ -1,18 +1,18 @@
372 @@ -1,18 +1,18 @@
363 # HG changeset patch
373 # HG changeset patch
364 -# User test
374 -# User test
365 +# User foo
375 +# User foo
366 # Date 0 0
376 # Date 0 0
367 # Thu Jan 01 00:00:00 1970 +0000
377 # Thu Jan 01 00:00:00 1970 +0000
368 -# Node ID 5c095ad7e90f871700f02dd1fa5012cb4498a2d4
378 -# Node ID 5c095ad7e90f871700f02dd1fa5012cb4498a2d4
369 -# Parent 5d205f8b35b66bc36375c9534ffd3237730e8f04
379 -# Parent 5d205f8b35b66bc36375c9534ffd3237730e8f04
370 +# Node ID 7a4785234d87ec1aa420ed6b11afe40fa73e12a9
380 +# Node ID 7a4785234d87ec1aa420ed6b11afe40fa73e12a9
371 +# Parent b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
381 +# Parent b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
372 2
382 2
373
383
374 -diff -r 5d205f8b35b6 -r 5c095ad7e90f a
384 -diff -r 5d205f8b35b6 -r 5c095ad7e90f a
375 +diff -r b592ea63bb0c -r 7a4785234d87 a
385 +diff -r b592ea63bb0c -r 7a4785234d87 a
376 --- a/a Thu Jan 01 00:00:00 1970 +0000
386 --- a/a Thu Jan 01 00:00:00 1970 +0000
377 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
387 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
378 @@ -1,1 +0,0 @@
388 @@ -1,1 +0,0 @@
379 --b
389 --b
380 -diff -r 5d205f8b35b6 -r 5c095ad7e90f b
390 -diff -r 5d205f8b35b6 -r 5c095ad7e90f b
381 +-a
391 +-a
382 +diff -r b592ea63bb0c -r 7a4785234d87 b
392 +diff -r b592ea63bb0c -r 7a4785234d87 b
383 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
393 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
384 +++ b/b Thu Jan 01 00:00:00 1970 +0000
394 +++ b/b Thu Jan 01 00:00:00 1970 +0000
385 @@ -0,0 +1,1 @@
395 @@ -0,0 +1,1 @@
386 -+b
396 -+b
387 ++a
397 ++a
388 [1]
398 [1]
389
399
390 $ hg pdiff --config extensions.extdiff= --patch -r 2 -r 13 -X .
400 $ hg pdiff --config extensions.extdiff= --patch -r 2 -r 13 -X .
391 --- */hg-5c095ad7e90f.patch * (glob)
401 --- */hg-5c095ad7e90f.patch * (glob)
392 +++ */hg-7a4785234d87.patch * (glob)
402 +++ */hg-7a4785234d87.patch * (glob)
393 @@ -1,8 +1,8 @@
403 @@ -1,8 +1,8 @@
394 # HG changeset patch
404 # HG changeset patch
395 -# User test
405 -# User test
396 +# User foo
406 +# User foo
397 # Date 0 0
407 # Date 0 0
398 # Thu Jan 01 00:00:00 1970 +0000
408 # Thu Jan 01 00:00:00 1970 +0000
399 -# Node ID 5c095ad7e90f871700f02dd1fa5012cb4498a2d4
409 -# Node ID 5c095ad7e90f871700f02dd1fa5012cb4498a2d4
400 -# Parent 5d205f8b35b66bc36375c9534ffd3237730e8f04
410 -# Parent 5d205f8b35b66bc36375c9534ffd3237730e8f04
401 +# Node ID 7a4785234d87ec1aa420ed6b11afe40fa73e12a9
411 +# Node ID 7a4785234d87ec1aa420ed6b11afe40fa73e12a9
402 +# Parent b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
412 +# Parent b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
403 2
413 2
404
414
405 [1]
415 [1]
406
416
407 Disallow grafting already grafted csets with the same origin onto each other
417 Disallow grafting already grafted csets with the same origin onto each other
408 $ hg up -q 13
418 $ hg up -q 13
409 $ hg graft 2
419 $ hg graft 2
410 skipping revision 2:5c095ad7e90f (already grafted to 13:7a4785234d87)
420 skipping revision 2:5c095ad7e90f (already grafted to 13:7a4785234d87)
411 [255]
421 [255]
412 $ hg graft 7
422 $ hg graft 7
413 skipping already grafted revision 7:ef0ef43d49e7 (13:7a4785234d87 also has origin 2:5c095ad7e90f)
423 skipping already grafted revision 7:ef0ef43d49e7 (13:7a4785234d87 also has origin 2:5c095ad7e90f)
414 [255]
424 [255]
415
425
416 $ hg up -q 7
426 $ hg up -q 7
417 $ hg graft 2
427 $ hg graft 2
418 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
428 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
419 [255]
429 [255]
420 $ hg graft tip
430 $ hg graft tip
421 skipping already grafted revision 13:7a4785234d87 (7:ef0ef43d49e7 also has origin 2:5c095ad7e90f)
431 skipping already grafted revision 13:7a4785234d87 (7:ef0ef43d49e7 also has origin 2:5c095ad7e90f)
422 [255]
432 [255]
423
433
424 Graft with --log
434 Graft with --log
425
435
426 $ hg up -Cq 1
436 $ hg up -Cq 1
427 $ hg graft 3 --log -u foo
437 $ hg graft 3 --log -u foo
428 grafting 3:4c60f11aa304 "3"
438 grafting 3:4c60f11aa304 "3"
429 warning: can't find ancestor for 'c' copied from 'b'!
439 warning: can't find ancestor for 'c' copied from 'b'!
430 $ hg log --template '{rev}:{node|short} {parents} {desc}\n' -r tip
440 $ hg log --template '{rev}:{node|short} {parents} {desc}\n' -r tip
431 14:0c921c65ef1e 1:5d205f8b35b6 3
441 14:0c921c65ef1e 1:5d205f8b35b6 3
432 (grafted from 4c60f11aa304a54ae1c199feb94e7fc771e51ed8)
442 (grafted from 4c60f11aa304a54ae1c199feb94e7fc771e51ed8)
433
443
434 Resolve conflicted graft
444 Resolve conflicted graft
435 $ hg up -q 0
445 $ hg up -q 0
436 $ echo b > a
446 $ echo b > a
437 $ hg ci -m 8
447 $ hg ci -m 8
438 created new head
448 created new head
439 $ echo c > a
449 $ echo c > a
440 $ hg ci -m 9
450 $ hg ci -m 9
441 $ hg graft 1 --tool internal:fail
451 $ hg graft 1 --tool internal:fail
442 grafting 1:5d205f8b35b6 "1"
452 grafting 1:5d205f8b35b6 "1"
443 abort: unresolved conflicts, can't continue
453 abort: unresolved conflicts, can't continue
444 (use 'hg resolve' and 'hg graft --continue')
454 (use 'hg resolve' and 'hg graft --continue')
445 [255]
455 [255]
446 $ hg resolve --all
456 $ hg resolve --all
447 merging a
457 merging a
448 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
458 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
449 [1]
459 [1]
450 $ cat a
460 $ cat a
451 <<<<<<< local: aaa4406d4f0a - test: 9
461 <<<<<<< local: aaa4406d4f0a - test: 9
452 c
462 c
453 =======
463 =======
454 b
464 b
455 >>>>>>> graft: 5d205f8b35b6 - bar: 1
465 >>>>>>> graft: 5d205f8b35b6 - bar: 1
456 $ echo b > a
466 $ echo b > a
457 $ hg resolve -m a
467 $ hg resolve -m a
458 (no more unresolved files)
468 (no more unresolved files)
459 continue: hg graft --continue
469 continue: hg graft --continue
460 $ hg graft -c
470 $ hg graft -c
461 grafting 1:5d205f8b35b6 "1"
471 grafting 1:5d205f8b35b6 "1"
462 $ hg export tip --git
472 $ hg export tip --git
463 # HG changeset patch
473 # HG changeset patch
464 # User bar
474 # User bar
465 # Date 0 0
475 # Date 0 0
466 # Thu Jan 01 00:00:00 1970 +0000
476 # Thu Jan 01 00:00:00 1970 +0000
467 # Node ID f67661df0c4804d301f064f332b57e7d5ddaf2be
477 # Node ID f67661df0c4804d301f064f332b57e7d5ddaf2be
468 # Parent aaa4406d4f0ae9befd6e58c82ec63706460cbca6
478 # Parent aaa4406d4f0ae9befd6e58c82ec63706460cbca6
469 1
479 1
470
480
471 diff --git a/a b/a
481 diff --git a/a b/a
472 --- a/a
482 --- a/a
473 +++ b/a
483 +++ b/a
474 @@ -1,1 +1,1 @@
484 @@ -1,1 +1,1 @@
475 -c
485 -c
476 +b
486 +b
477
487
478 Resolve conflicted graft with rename
488 Resolve conflicted graft with rename
479 $ echo c > a
489 $ echo c > a
480 $ hg ci -m 10
490 $ hg ci -m 10
481 $ hg graft 2 --tool internal:fail
491 $ hg graft 2 --tool internal:fail
482 grafting 2:5c095ad7e90f "2"
492 grafting 2:5c095ad7e90f "2"
483 abort: unresolved conflicts, can't continue
493 abort: unresolved conflicts, can't continue
484 (use 'hg resolve' and 'hg graft --continue')
494 (use 'hg resolve' and 'hg graft --continue')
485 [255]
495 [255]
486 $ hg resolve --all
496 $ hg resolve --all
487 merging a and b to b
497 merging a and b to b
488 (no more unresolved files)
498 (no more unresolved files)
489 continue: hg graft --continue
499 continue: hg graft --continue
490 $ hg graft -c
500 $ hg graft -c
491 grafting 2:5c095ad7e90f "2"
501 grafting 2:5c095ad7e90f "2"
492 $ hg export tip --git
502 $ hg export tip --git
493 # HG changeset patch
503 # HG changeset patch
494 # User test
504 # User test
495 # Date 0 0
505 # Date 0 0
496 # Thu Jan 01 00:00:00 1970 +0000
506 # Thu Jan 01 00:00:00 1970 +0000
497 # Node ID 9627f653b421c61fc1ea4c4e366745070fa3d2bc
507 # Node ID 9627f653b421c61fc1ea4c4e366745070fa3d2bc
498 # Parent ee295f490a40b97f3d18dd4c4f1c8936c233b612
508 # Parent ee295f490a40b97f3d18dd4c4f1c8936c233b612
499 2
509 2
500
510
501 diff --git a/a b/b
511 diff --git a/a b/b
502 rename from a
512 rename from a
503 rename to b
513 rename to b
504
514
505 Test simple origin(), with and without args
515 Test simple origin(), with and without args
506 $ hg log -r 'origin()'
516 $ hg log -r 'origin()'
507 changeset: 1:5d205f8b35b6
517 changeset: 1:5d205f8b35b6
508 user: bar
518 user: bar
509 date: Thu Jan 01 00:00:00 1970 +0000
519 date: Thu Jan 01 00:00:00 1970 +0000
510 summary: 1
520 summary: 1
511
521
512 changeset: 2:5c095ad7e90f
522 changeset: 2:5c095ad7e90f
513 user: test
523 user: test
514 date: Thu Jan 01 00:00:00 1970 +0000
524 date: Thu Jan 01 00:00:00 1970 +0000
515 summary: 2
525 summary: 2
516
526
517 changeset: 3:4c60f11aa304
527 changeset: 3:4c60f11aa304
518 user: baz
528 user: baz
519 date: Thu Jan 01 00:00:00 1970 +0000
529 date: Thu Jan 01 00:00:00 1970 +0000
520 summary: 3
530 summary: 3
521
531
522 changeset: 4:9c233e8e184d
532 changeset: 4:9c233e8e184d
523 user: test
533 user: test
524 date: Thu Jan 01 00:00:00 1970 +0000
534 date: Thu Jan 01 00:00:00 1970 +0000
525 summary: 4
535 summary: 4
526
536
527 changeset: 5:97f8bfe72746
537 changeset: 5:97f8bfe72746
528 branch: stable
538 branch: stable
529 parent: 3:4c60f11aa304
539 parent: 3:4c60f11aa304
530 user: test
540 user: test
531 date: Thu Jan 01 00:00:00 1970 +0000
541 date: Thu Jan 01 00:00:00 1970 +0000
532 summary: 5
542 summary: 5
533
543
534 $ hg log -r 'origin(7)'
544 $ hg log -r 'origin(7)'
535 changeset: 2:5c095ad7e90f
545 changeset: 2:5c095ad7e90f
536 user: test
546 user: test
537 date: Thu Jan 01 00:00:00 1970 +0000
547 date: Thu Jan 01 00:00:00 1970 +0000
538 summary: 2
548 summary: 2
539
549
540 Now transplant a graft to test following through copies
550 Now transplant a graft to test following through copies
541 $ hg up -q 0
551 $ hg up -q 0
542 $ hg branch -q dev
552 $ hg branch -q dev
543 $ hg ci -qm "dev branch"
553 $ hg ci -qm "dev branch"
544 $ hg --config extensions.transplant= transplant -q 7
554 $ hg --config extensions.transplant= transplant -q 7
545 $ hg log -r 'origin(.)'
555 $ hg log -r 'origin(.)'
546 changeset: 2:5c095ad7e90f
556 changeset: 2:5c095ad7e90f
547 user: test
557 user: test
548 date: Thu Jan 01 00:00:00 1970 +0000
558 date: Thu Jan 01 00:00:00 1970 +0000
549 summary: 2
559 summary: 2
550
560
551 Test that the graft and transplant markers in extra are converted, allowing
561 Test that the graft and transplant markers in extra are converted, allowing
552 origin() to still work. Note that these recheck the immediately preceeding two
562 origin() to still work. Note that these recheck the immediately preceeding two
553 tests.
563 tests.
554 $ hg --quiet --config extensions.convert= --config convert.hg.saverev=True convert . ../converted
564 $ hg --quiet --config extensions.convert= --config convert.hg.saverev=True convert . ../converted
555
565
556 The graft case
566 The graft case
557 $ hg -R ../converted log -r 7 --template "{rev}: {node}\n{join(extras, '\n')}\n"
567 $ hg -R ../converted log -r 7 --template "{rev}: {node}\n{join(extras, '\n')}\n"
558 7: 7ae846e9111fc8f57745634250c7b9ac0a60689b
568 7: 7ae846e9111fc8f57745634250c7b9ac0a60689b
559 branch=default
569 branch=default
560 convert_revision=ef0ef43d49e79e81ddafdc7997401ba0041efc82
570 convert_revision=ef0ef43d49e79e81ddafdc7997401ba0041efc82
561 source=e0213322b2c1a5d5d236c74e79666441bee67a7d
571 source=e0213322b2c1a5d5d236c74e79666441bee67a7d
562 $ hg -R ../converted log -r 'origin(7)'
572 $ hg -R ../converted log -r 'origin(7)'
563 changeset: 2:e0213322b2c1
573 changeset: 2:e0213322b2c1
564 user: test
574 user: test
565 date: Thu Jan 01 00:00:00 1970 +0000
575 date: Thu Jan 01 00:00:00 1970 +0000
566 summary: 2
576 summary: 2
567
577
568 Test that template correctly expands more than one 'extra' (issue4362), and that
578 Test that template correctly expands more than one 'extra' (issue4362), and that
569 'intermediate-source' is converted.
579 'intermediate-source' is converted.
570 $ hg -R ../converted log -r 13 --template "{extras % ' Extra: {extra}\n'}"
580 $ hg -R ../converted log -r 13 --template "{extras % ' Extra: {extra}\n'}"
571 Extra: branch=default
581 Extra: branch=default
572 Extra: convert_revision=7a4785234d87ec1aa420ed6b11afe40fa73e12a9
582 Extra: convert_revision=7a4785234d87ec1aa420ed6b11afe40fa73e12a9
573 Extra: intermediate-source=7ae846e9111fc8f57745634250c7b9ac0a60689b
583 Extra: intermediate-source=7ae846e9111fc8f57745634250c7b9ac0a60689b
574 Extra: source=e0213322b2c1a5d5d236c74e79666441bee67a7d
584 Extra: source=e0213322b2c1a5d5d236c74e79666441bee67a7d
575
585
576 The transplant case
586 The transplant case
577 $ hg -R ../converted log -r tip --template "{rev}: {node}\n{join(extras, '\n')}\n"
587 $ hg -R ../converted log -r tip --template "{rev}: {node}\n{join(extras, '\n')}\n"
578 21: fbb6c5cc81002f2b4b49c9d731404688bcae5ade
588 21: fbb6c5cc81002f2b4b49c9d731404688bcae5ade
579 branch=dev
589 branch=dev
580 convert_revision=7e61b508e709a11d28194a5359bc3532d910af21
590 convert_revision=7e61b508e709a11d28194a5359bc3532d910af21
581 transplant_source=z\xe8F\xe9\x11\x1f\xc8\xf5wEcBP\xc7\xb9\xac (esc)
591 transplant_source=z\xe8F\xe9\x11\x1f\xc8\xf5wEcBP\xc7\xb9\xac (esc)
582 `h\x9b (esc)
592 `h\x9b (esc)
583 $ hg -R ../converted log -r 'origin(tip)'
593 $ hg -R ../converted log -r 'origin(tip)'
584 changeset: 2:e0213322b2c1
594 changeset: 2:e0213322b2c1
585 user: test
595 user: test
586 date: Thu Jan 01 00:00:00 1970 +0000
596 date: Thu Jan 01 00:00:00 1970 +0000
587 summary: 2
597 summary: 2
588
598
589
599
590 Test simple destination
600 Test simple destination
591 $ hg log -r 'destination()'
601 $ hg log -r 'destination()'
592 changeset: 7:ef0ef43d49e7
602 changeset: 7:ef0ef43d49e7
593 parent: 0:68795b066622
603 parent: 0:68795b066622
594 user: foo
604 user: foo
595 date: Thu Jan 01 00:00:00 1970 +0000
605 date: Thu Jan 01 00:00:00 1970 +0000
596 summary: 2
606 summary: 2
597
607
598 changeset: 8:6b9e5368ca4e
608 changeset: 8:6b9e5368ca4e
599 user: bar
609 user: bar
600 date: Thu Jan 01 00:00:00 1970 +0000
610 date: Thu Jan 01 00:00:00 1970 +0000
601 summary: 1
611 summary: 1
602
612
603 changeset: 9:1905859650ec
613 changeset: 9:1905859650ec
604 user: test
614 user: test
605 date: Thu Jan 01 00:00:00 1970 +0000
615 date: Thu Jan 01 00:00:00 1970 +0000
606 summary: 5
616 summary: 5
607
617
608 changeset: 10:52dc0b4c6907
618 changeset: 10:52dc0b4c6907
609 user: test
619 user: test
610 date: Thu Jan 01 00:00:00 1970 +0000
620 date: Thu Jan 01 00:00:00 1970 +0000
611 summary: 4
621 summary: 4
612
622
613 changeset: 11:882b35362a6b
623 changeset: 11:882b35362a6b
614 user: test
624 user: test
615 date: Thu Jan 01 00:00:00 1970 +0000
625 date: Thu Jan 01 00:00:00 1970 +0000
616 summary: 3
626 summary: 3
617
627
618 changeset: 13:7a4785234d87
628 changeset: 13:7a4785234d87
619 user: foo
629 user: foo
620 date: Thu Jan 01 00:00:00 1970 +0000
630 date: Thu Jan 01 00:00:00 1970 +0000
621 summary: 2
631 summary: 2
622
632
623 changeset: 14:0c921c65ef1e
633 changeset: 14:0c921c65ef1e
624 parent: 1:5d205f8b35b6
634 parent: 1:5d205f8b35b6
625 user: foo
635 user: foo
626 date: Thu Jan 01 00:00:00 1970 +0000
636 date: Thu Jan 01 00:00:00 1970 +0000
627 summary: 3
637 summary: 3
628
638
629 changeset: 17:f67661df0c48
639 changeset: 17:f67661df0c48
630 user: bar
640 user: bar
631 date: Thu Jan 01 00:00:00 1970 +0000
641 date: Thu Jan 01 00:00:00 1970 +0000
632 summary: 1
642 summary: 1
633
643
634 changeset: 19:9627f653b421
644 changeset: 19:9627f653b421
635 user: test
645 user: test
636 date: Thu Jan 01 00:00:00 1970 +0000
646 date: Thu Jan 01 00:00:00 1970 +0000
637 summary: 2
647 summary: 2
638
648
639 changeset: 21:7e61b508e709
649 changeset: 21:7e61b508e709
640 branch: dev
650 branch: dev
641 tag: tip
651 tag: tip
642 user: foo
652 user: foo
643 date: Thu Jan 01 00:00:00 1970 +0000
653 date: Thu Jan 01 00:00:00 1970 +0000
644 summary: 2
654 summary: 2
645
655
646 $ hg log -r 'destination(2)'
656 $ hg log -r 'destination(2)'
647 changeset: 7:ef0ef43d49e7
657 changeset: 7:ef0ef43d49e7
648 parent: 0:68795b066622
658 parent: 0:68795b066622
649 user: foo
659 user: foo
650 date: Thu Jan 01 00:00:00 1970 +0000
660 date: Thu Jan 01 00:00:00 1970 +0000
651 summary: 2
661 summary: 2
652
662
653 changeset: 13:7a4785234d87
663 changeset: 13:7a4785234d87
654 user: foo
664 user: foo
655 date: Thu Jan 01 00:00:00 1970 +0000
665 date: Thu Jan 01 00:00:00 1970 +0000
656 summary: 2
666 summary: 2
657
667
658 changeset: 19:9627f653b421
668 changeset: 19:9627f653b421
659 user: test
669 user: test
660 date: Thu Jan 01 00:00:00 1970 +0000
670 date: Thu Jan 01 00:00:00 1970 +0000
661 summary: 2
671 summary: 2
662
672
663 changeset: 21:7e61b508e709
673 changeset: 21:7e61b508e709
664 branch: dev
674 branch: dev
665 tag: tip
675 tag: tip
666 user: foo
676 user: foo
667 date: Thu Jan 01 00:00:00 1970 +0000
677 date: Thu Jan 01 00:00:00 1970 +0000
668 summary: 2
678 summary: 2
669
679
670 Transplants of grafts can find a destination...
680 Transplants of grafts can find a destination...
671 $ hg log -r 'destination(7)'
681 $ hg log -r 'destination(7)'
672 changeset: 21:7e61b508e709
682 changeset: 21:7e61b508e709
673 branch: dev
683 branch: dev
674 tag: tip
684 tag: tip
675 user: foo
685 user: foo
676 date: Thu Jan 01 00:00:00 1970 +0000
686 date: Thu Jan 01 00:00:00 1970 +0000
677 summary: 2
687 summary: 2
678
688
679 ... grafts of grafts unfortunately can't
689 ... grafts of grafts unfortunately can't
680 $ hg graft -q 13
690 $ hg graft -q 13
681 warning: can't find ancestor for 'b' copied from 'a'!
691 warning: can't find ancestor for 'b' copied from 'a'!
682 $ hg log -r 'destination(13)'
692 $ hg log -r 'destination(13)'
683 All copies of a cset
693 All copies of a cset
684 $ hg log -r 'origin(13) or destination(origin(13))'
694 $ hg log -r 'origin(13) or destination(origin(13))'
685 changeset: 2:5c095ad7e90f
695 changeset: 2:5c095ad7e90f
686 user: test
696 user: test
687 date: Thu Jan 01 00:00:00 1970 +0000
697 date: Thu Jan 01 00:00:00 1970 +0000
688 summary: 2
698 summary: 2
689
699
690 changeset: 7:ef0ef43d49e7
700 changeset: 7:ef0ef43d49e7
691 parent: 0:68795b066622
701 parent: 0:68795b066622
692 user: foo
702 user: foo
693 date: Thu Jan 01 00:00:00 1970 +0000
703 date: Thu Jan 01 00:00:00 1970 +0000
694 summary: 2
704 summary: 2
695
705
696 changeset: 13:7a4785234d87
706 changeset: 13:7a4785234d87
697 user: foo
707 user: foo
698 date: Thu Jan 01 00:00:00 1970 +0000
708 date: Thu Jan 01 00:00:00 1970 +0000
699 summary: 2
709 summary: 2
700
710
701 changeset: 19:9627f653b421
711 changeset: 19:9627f653b421
702 user: test
712 user: test
703 date: Thu Jan 01 00:00:00 1970 +0000
713 date: Thu Jan 01 00:00:00 1970 +0000
704 summary: 2
714 summary: 2
705
715
706 changeset: 21:7e61b508e709
716 changeset: 21:7e61b508e709
707 branch: dev
717 branch: dev
708 user: foo
718 user: foo
709 date: Thu Jan 01 00:00:00 1970 +0000
719 date: Thu Jan 01 00:00:00 1970 +0000
710 summary: 2
720 summary: 2
711
721
712 changeset: 22:d1cb6591fa4b
722 changeset: 22:d1cb6591fa4b
713 branch: dev
723 branch: dev
714 tag: tip
724 tag: tip
715 user: foo
725 user: foo
716 date: Thu Jan 01 00:00:00 1970 +0000
726 date: Thu Jan 01 00:00:00 1970 +0000
717 summary: 2
727 summary: 2
718
728
719
729
720 graft works on complex revset
730 graft works on complex revset
721
731
722 $ hg graft 'origin(13) or destination(origin(13))'
732 $ hg graft 'origin(13) or destination(origin(13))'
723 skipping ancestor revision 21:7e61b508e709
733 skipping ancestor revision 21:7e61b508e709
724 skipping ancestor revision 22:d1cb6591fa4b
734 skipping ancestor revision 22:d1cb6591fa4b
725 skipping revision 2:5c095ad7e90f (already grafted to 22:d1cb6591fa4b)
735 skipping revision 2:5c095ad7e90f (already grafted to 22:d1cb6591fa4b)
726 grafting 7:ef0ef43d49e7 "2"
736 grafting 7:ef0ef43d49e7 "2"
727 warning: can't find ancestor for 'b' copied from 'a'!
737 warning: can't find ancestor for 'b' copied from 'a'!
728 grafting 13:7a4785234d87 "2"
738 grafting 13:7a4785234d87 "2"
729 warning: can't find ancestor for 'b' copied from 'a'!
739 warning: can't find ancestor for 'b' copied from 'a'!
730 grafting 19:9627f653b421 "2"
740 grafting 19:9627f653b421 "2"
731 merging b
741 merging b
732 warning: can't find ancestor for 'b' copied from 'a'!
742 warning: can't find ancestor for 'b' copied from 'a'!
733
743
734 graft with --force (still doesn't graft merges)
744 graft with --force (still doesn't graft merges)
735
745
736 $ hg graft 19 0 6
746 $ hg graft 19 0 6
737 skipping ungraftable merge revision 6
747 skipping ungraftable merge revision 6
738 skipping ancestor revision 0:68795b066622
748 skipping ancestor revision 0:68795b066622
739 skipping already grafted revision 19:9627f653b421 (22:d1cb6591fa4b also has origin 2:5c095ad7e90f)
749 skipping already grafted revision 19:9627f653b421 (22:d1cb6591fa4b also has origin 2:5c095ad7e90f)
740 [255]
750 [255]
741 $ hg graft 19 0 6 --force
751 $ hg graft 19 0 6 --force
742 skipping ungraftable merge revision 6
752 skipping ungraftable merge revision 6
743 grafting 19:9627f653b421 "2"
753 grafting 19:9627f653b421 "2"
744 merging b
754 merging b
745 warning: can't find ancestor for 'b' copied from 'a'!
755 warning: can't find ancestor for 'b' copied from 'a'!
746 grafting 0:68795b066622 "0"
756 grafting 0:68795b066622 "0"
747
757
748 graft --force after backout
758 graft --force after backout
749
759
750 $ echo abc > a
760 $ echo abc > a
751 $ hg ci -m 28
761 $ hg ci -m 28
752 $ hg backout 28
762 $ hg backout 28
753 reverting a
763 reverting a
754 changeset 29:53177ba928f6 backs out changeset 28:50a516bb8b57
764 changeset 29:53177ba928f6 backs out changeset 28:50a516bb8b57
755 $ hg graft 28
765 $ hg graft 28
756 skipping ancestor revision 28:50a516bb8b57
766 skipping ancestor revision 28:50a516bb8b57
757 [255]
767 [255]
758 $ hg graft 28 --force
768 $ hg graft 28 --force
759 grafting 28:50a516bb8b57 "28"
769 grafting 28:50a516bb8b57 "28"
760 merging a
770 merging a
761 $ cat a
771 $ cat a
762 abc
772 abc
763
773
764 graft --continue after --force
774 graft --continue after --force
765
775
766 $ echo def > a
776 $ echo def > a
767 $ hg ci -m 31
777 $ hg ci -m 31
768 $ hg graft 28 --force --tool internal:fail
778 $ hg graft 28 --force --tool internal:fail
769 grafting 28:50a516bb8b57 "28"
779 grafting 28:50a516bb8b57 "28"
770 abort: unresolved conflicts, can't continue
780 abort: unresolved conflicts, can't continue
771 (use 'hg resolve' and 'hg graft --continue')
781 (use 'hg resolve' and 'hg graft --continue')
772 [255]
782 [255]
773 $ hg resolve --all
783 $ hg resolve --all
774 merging a
784 merging a
775 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
785 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
776 [1]
786 [1]
777 $ echo abc > a
787 $ echo abc > a
778 $ hg resolve -m a
788 $ hg resolve -m a
779 (no more unresolved files)
789 (no more unresolved files)
780 continue: hg graft --continue
790 continue: hg graft --continue
781 $ hg graft -c
791 $ hg graft -c
782 grafting 28:50a516bb8b57 "28"
792 grafting 28:50a516bb8b57 "28"
783 $ cat a
793 $ cat a
784 abc
794 abc
785
795
786 Continue testing same origin policy, using revision numbers from test above
796 Continue testing same origin policy, using revision numbers from test above
787 but do some destructive editing of the repo:
797 but do some destructive editing of the repo:
788
798
789 $ hg up -qC 7
799 $ hg up -qC 7
790 $ hg tag -l -r 13 tmp
800 $ hg tag -l -r 13 tmp
791 $ hg --config extensions.strip= strip 2
801 $ hg --config extensions.strip= strip 2
792 saved backup bundle to $TESTTMP/a/.hg/strip-backup/5c095ad7e90f-d323a1e4-backup.hg (glob)
802 saved backup bundle to $TESTTMP/a/.hg/strip-backup/5c095ad7e90f-d323a1e4-backup.hg (glob)
793 $ hg graft tmp
803 $ hg graft tmp
794 skipping already grafted revision 8:7a4785234d87 (2:ef0ef43d49e7 also has unknown origin 5c095ad7e90f)
804 skipping already grafted revision 8:7a4785234d87 (2:ef0ef43d49e7 also has unknown origin 5c095ad7e90f)
795 [255]
805 [255]
796
806
797 Empty graft
807 Empty graft
798
808
799 $ hg up -qr 26
809 $ hg up -qr 26
800 $ hg tag -f something
810 $ hg tag -f something
801 $ hg graft -qr 27
811 $ hg graft -qr 27
802 $ hg graft -f 27
812 $ hg graft -f 27
803 grafting 27:ed6c7e54e319 "28"
813 grafting 27:ed6c7e54e319 "28"
804 note: graft of 27:ed6c7e54e319 created no changes to commit
814 note: graft of 27:ed6c7e54e319 created no changes to commit
805
815
806 $ cd ..
816 $ cd ..
807
817
808 Graft to duplicate a commit
818 Graft to duplicate a commit
809
819
810 $ hg init graftsibling
820 $ hg init graftsibling
811 $ cd graftsibling
821 $ cd graftsibling
812 $ touch a
822 $ touch a
813 $ hg commit -qAm a
823 $ hg commit -qAm a
814 $ touch b
824 $ touch b
815 $ hg commit -qAm b
825 $ hg commit -qAm b
816 $ hg log -G -T '{rev}\n'
826 $ hg log -G -T '{rev}\n'
817 @ 1
827 @ 1
818 |
828 |
819 o 0
829 o 0
820
830
821 $ hg up -q 0
831 $ hg up -q 0
822 $ hg graft -r 1
832 $ hg graft -r 1
823 grafting 1:0e067c57feba "b" (tip)
833 grafting 1:0e067c57feba "b" (tip)
824 $ hg log -G -T '{rev}\n'
834 $ hg log -G -T '{rev}\n'
825 @ 2
835 @ 2
826 |
836 |
827 | o 1
837 | o 1
828 |/
838 |/
829 o 0
839 o 0
830
840
831 Graft to duplicate a commit twice
841 Graft to duplicate a commit twice
832
842
833 $ hg up -q 0
843 $ hg up -q 0
834 $ hg graft -r 2
844 $ hg graft -r 2
835 grafting 2:044ec77f6389 "b" (tip)
845 grafting 2:044ec77f6389 "b" (tip)
836 $ hg log -G -T '{rev}\n'
846 $ hg log -G -T '{rev}\n'
837 @ 3
847 @ 3
838 |
848 |
839 | o 2
849 | o 2
840 |/
850 |/
841 | o 1
851 | o 1
842 |/
852 |/
843 o 0
853 o 0
844
854
845 Graft from behind a move or rename
855 Graft from behind a move or rename
846 ==================================
856 ==================================
847
857
848 NOTE: This is affected by issue5343, and will need updating when it's fixed
858 NOTE: This is affected by issue5343, and will need updating when it's fixed
849
859
850 Possible cases during a regular graft (when ca is between cta and c2):
860 Possible cases during a regular graft (when ca is between cta and c2):
851
861
852 name | c1<-cta | cta<->ca | ca->c2
862 name | c1<-cta | cta<->ca | ca->c2
853 A.0 | | |
863 A.0 | | |
854 A.1 | X | |
864 A.1 | X | |
855 A.2 | | X |
865 A.2 | | X |
856 A.3 | | | X
866 A.3 | | | X
857 A.4 | X | X |
867 A.4 | X | X |
858 A.5 | X | | X
868 A.5 | X | | X
859 A.6 | | X | X
869 A.6 | | X | X
860 A.7 | X | X | X
870 A.7 | X | X | X
861
871
862 A.0 is trivial, and doesn't need copy tracking.
872 A.0 is trivial, and doesn't need copy tracking.
863 For A.1, a forward rename is recorded in the c1 pass, to be followed later.
873 For A.1, a forward rename is recorded in the c1 pass, to be followed later.
864 In A.2, the rename is recorded in the c2 pass and followed backwards.
874 In A.2, the rename is recorded in the c2 pass and followed backwards.
865 A.3 is recorded in the c2 pass as a forward rename to be duplicated on target.
875 A.3 is recorded in the c2 pass as a forward rename to be duplicated on target.
866 In A.4, both passes of checkcopies record incomplete renames, which are
876 In A.4, both passes of checkcopies record incomplete renames, which are
867 then joined in mergecopies to record a rename to be followed.
877 then joined in mergecopies to record a rename to be followed.
868 In A.5 and A.7, the c1 pass records an incomplete rename, while the c2 pass
878 In A.5 and A.7, the c1 pass records an incomplete rename, while the c2 pass
869 records an incomplete divergence. The incomplete rename is then joined to the
879 records an incomplete divergence. The incomplete rename is then joined to the
870 appropriate side of the incomplete divergence, and the result is recorded as a
880 appropriate side of the incomplete divergence, and the result is recorded as a
871 divergence. The code doesn't distinguish at all between these two cases, since
881 divergence. The code doesn't distinguish at all between these two cases, since
872 the end result of them is the same: an incomplete divergence joined with an
882 the end result of them is the same: an incomplete divergence joined with an
873 incomplete rename into a divergence.
883 incomplete rename into a divergence.
874 Finally, A.6 records a divergence entirely in the c2 pass.
884 Finally, A.6 records a divergence entirely in the c2 pass.
875
885
876 A.4 has a degenerate case a<-b<-a->a, where checkcopies isn't needed at all.
886 A.4 has a degenerate case a<-b<-a->a, where checkcopies isn't needed at all.
877 A.5 has a special case a<-b<-b->a, which is treated like a<-b->a in a merge.
887 A.5 has a special case a<-b<-b->a, which is treated like a<-b->a in a merge.
878 A.6 has a special case a<-a<-b->a. Here, checkcopies will find a spurious
888 A.6 has a special case a<-a<-b->a. Here, checkcopies will find a spurious
879 incomplete divergence, which is in fact complete. This is handled later in
889 incomplete divergence, which is in fact complete. This is handled later in
880 mergecopies.
890 mergecopies.
881 A.7 has 4 special cases: a<-b<-a->b (the "ping-pong" case), a<-b<-c->b,
891 A.7 has 4 special cases: a<-b<-a->b (the "ping-pong" case), a<-b<-c->b,
882 a<-b<-a->c and a<-b<-c->a. Of these, only the "ping-pong" case is interesting,
892 a<-b<-a->c and a<-b<-c->a. Of these, only the "ping-pong" case is interesting,
883 the others are fairly trivial (a<-b<-c->b and a<-b<-a->c proceed like the base
893 the others are fairly trivial (a<-b<-c->b and a<-b<-a->c proceed like the base
884 case, a<-b<-c->a is treated the same as a<-b<-b->a).
894 case, a<-b<-c->a is treated the same as a<-b<-b->a).
885
895
886 f5a therefore tests the "ping-pong" rename case, where a file is renamed to the
896 f5a therefore tests the "ping-pong" rename case, where a file is renamed to the
887 same name on both branches, then the rename is backed out on one branch, and
897 same name on both branches, then the rename is backed out on one branch, and
888 the backout is grafted to the other branch. This creates a challenging rename
898 the backout is grafted to the other branch. This creates a challenging rename
889 sequence of a<-b<-a->b in the graft target, topological CA, graft CA and graft
899 sequence of a<-b<-a->b in the graft target, topological CA, graft CA and graft
890 source, respectively. Since rename detection will run on the c1 side for such a
900 source, respectively. Since rename detection will run on the c1 side for such a
891 sequence (as for technical reasons, we split the c1 and c2 sides not at the
901 sequence (as for technical reasons, we split the c1 and c2 sides not at the
892 graft CA, but rather at the topological CA), it will pick up a false rename,
902 graft CA, but rather at the topological CA), it will pick up a false rename,
893 and cause a spurious merge conflict. This false rename is always exactly the
903 and cause a spurious merge conflict. This false rename is always exactly the
894 reverse of the true rename that would be detected on the c2 side, so we can
904 reverse of the true rename that would be detected on the c2 side, so we can
895 correct for it by detecting this condition and reversing as necessary.
905 correct for it by detecting this condition and reversing as necessary.
896
906
897 First, set up the repository with commits to be grafted
907 First, set up the repository with commits to be grafted
898
908
899 $ hg init ../graftmove
909 $ hg init ../graftmove
900 $ cd ../graftmove
910 $ cd ../graftmove
901 $ echo c1a > f1a
911 $ echo c1a > f1a
902 $ echo c2a > f2a
912 $ echo c2a > f2a
903 $ echo c3a > f3a
913 $ echo c3a > f3a
904 $ echo c4a > f4a
914 $ echo c4a > f4a
905 $ echo c5a > f5a
915 $ echo c5a > f5a
906 $ hg ci -qAm A0
916 $ hg ci -qAm A0
907 $ hg mv f1a f1b
917 $ hg mv f1a f1b
908 $ hg mv f3a f3b
918 $ hg mv f3a f3b
909 $ hg mv f5a f5b
919 $ hg mv f5a f5b
910 $ hg ci -qAm B0
920 $ hg ci -qAm B0
911 $ echo c1c > f1b
921 $ echo c1c > f1b
912 $ hg mv f2a f2c
922 $ hg mv f2a f2c
913 $ hg mv f5b f5a
923 $ hg mv f5b f5a
914 $ echo c5c > f5a
924 $ echo c5c > f5a
915 $ hg ci -qAm C0
925 $ hg ci -qAm C0
916 $ hg mv f3b f3d
926 $ hg mv f3b f3d
917 $ echo c4d > f4a
927 $ echo c4d > f4a
918 $ hg ci -qAm D0
928 $ hg ci -qAm D0
919 $ hg log -G
929 $ hg log -G
920 @ changeset: 3:b69f5839d2d9
930 @ changeset: 3:b69f5839d2d9
921 | tag: tip
931 | tag: tip
922 | user: test
932 | user: test
923 | date: Thu Jan 01 00:00:00 1970 +0000
933 | date: Thu Jan 01 00:00:00 1970 +0000
924 | summary: D0
934 | summary: D0
925 |
935 |
926 o changeset: 2:f58c7e2b28fa
936 o changeset: 2:f58c7e2b28fa
927 | user: test
937 | user: test
928 | date: Thu Jan 01 00:00:00 1970 +0000
938 | date: Thu Jan 01 00:00:00 1970 +0000
929 | summary: C0
939 | summary: C0
930 |
940 |
931 o changeset: 1:3d7bba921b5d
941 o changeset: 1:3d7bba921b5d
932 | user: test
942 | user: test
933 | date: Thu Jan 01 00:00:00 1970 +0000
943 | date: Thu Jan 01 00:00:00 1970 +0000
934 | summary: B0
944 | summary: B0
935 |
945 |
936 o changeset: 0:11f7a1b56675
946 o changeset: 0:11f7a1b56675
937 user: test
947 user: test
938 date: Thu Jan 01 00:00:00 1970 +0000
948 date: Thu Jan 01 00:00:00 1970 +0000
939 summary: A0
949 summary: A0
940
950
941
951
942 Test the cases A.2 (f1x), A.3 (f2x) and a special case of A.6 (f5x) where the
952 Test the cases A.2 (f1x), A.3 (f2x) and a special case of A.6 (f5x) where the
943 two renames actually converge to the same name (thus no actual divergence).
953 two renames actually converge to the same name (thus no actual divergence).
944
954
945 $ hg up -q 'desc("A0")'
955 $ hg up -q 'desc("A0")'
946 $ HGEDITOR="echo C1 >" hg graft -r 'desc("C0")' --edit
956 $ HGEDITOR="echo C1 >" hg graft -r 'desc("C0")' --edit
947 grafting 2:f58c7e2b28fa "C0"
957 grafting 2:f58c7e2b28fa "C0"
958 merging f1a and f1b to f1a
948 merging f5a
959 merging f5a
949 warning: conflicts while merging f5a! (edit, then use 'hg resolve --mark')
960 warning: conflicts while merging f5a! (edit, then use 'hg resolve --mark')
950 abort: unresolved conflicts, can't continue
961 abort: unresolved conflicts, can't continue
951 (use 'hg resolve' and 'hg graft --continue')
962 (use 'hg resolve' and 'hg graft --continue')
952 [255]
963 [255]
953 $ hg resolve f5a -t ':other' # XXX work around failure
964 $ hg resolve f5a -t ':other' # XXX work around failure
954 (no more unresolved files)
965 (no more unresolved files)
955 continue: hg graft --continue
966 continue: hg graft --continue
956 $ hg graft --continue # XXX work around failure
967 $ hg graft --continue # XXX work around failure
957 grafting 2:f58c7e2b28fa "C0"
968 grafting 2:f58c7e2b28fa "C0"
958 warning: can't find ancestor for 'f5a' copied from 'f5b'!
969 warning: can't find ancestor for 'f5a' copied from 'f5b'!
959 $ hg status --change .
970 $ hg status --change .
971 M f1a
960 M f5a
972 M f5a
961 A f1b
962 A f2c
973 A f2c
963 R f2a
974 R f2a
964 $ hg cat f1a
975 $ hg cat f1a
965 c1a
976 c1c
966 $ hg cat f1b
977 $ hg cat f1b
967 c1c
978 f1b: no such file in rev 43e4b415492d
979 [1]
968
980
969 Test the cases A.0 (f4x) and A.6 (f3x)
981 Test the cases A.0 (f4x) and A.6 (f3x)
970
982
971 $ HGEDITOR="echo D1 >" hg graft -r 'desc("D0")' --edit
983 $ HGEDITOR="echo D1 >" hg graft -r 'desc("D0")' --edit
972 grafting 3:b69f5839d2d9 "D0"
984 grafting 3:b69f5839d2d9 "D0"
973 warning: can't find ancestor for 'f3d' copied from 'f3b'!
985 warning: can't find ancestor for 'f3d' copied from 'f3b'!
974
986
975 Set up the repository for some further tests
987 Set up the repository for some further tests
976
988
977 $ hg up -q "min(desc("A0"))"
989 $ hg up -q "min(desc("A0"))"
978 $ hg mv f1a f1e
990 $ hg mv f1a f1e
979 $ echo c2e > f2a
991 $ echo c2e > f2a
980 $ hg mv f3a f3e
992 $ hg mv f3a f3e
981 $ hg mv f4a f4e
993 $ hg mv f4a f4e
982 $ hg mv f5a f5b
994 $ hg mv f5a f5b
983 $ hg ci -qAm "E0"
995 $ hg ci -qAm "E0"
984 $ hg log -G
996 $ hg log -G
985 @ changeset: 6:ebba59d1fb02
997 @ changeset: 6:ebba59d1fb02
986 | tag: tip
998 | tag: tip
987 | parent: 0:11f7a1b56675
999 | parent: 0:11f7a1b56675
988 | user: test
1000 | user: test
989 | date: Thu Jan 01 00:00:00 1970 +0000
1001 | date: Thu Jan 01 00:00:00 1970 +0000
990 | summary: E0
1002 | summary: E0
991 |
1003 |
992 | o changeset: 5:573bb6b4b56d
1004 | o changeset: 5:4f4ba7a6e606
993 | | user: test
1005 | | user: test
994 | | date: Thu Jan 01 00:00:00 1970 +0000
1006 | | date: Thu Jan 01 00:00:00 1970 +0000
995 | | summary: D1
1007 | | summary: D1
996 | |
1008 | |
997 | o changeset: 4:af23416e619b
1009 | o changeset: 4:43e4b415492d
998 |/ parent: 0:11f7a1b56675
1010 |/ parent: 0:11f7a1b56675
999 | user: test
1011 | user: test
1000 | date: Thu Jan 01 00:00:00 1970 +0000
1012 | date: Thu Jan 01 00:00:00 1970 +0000
1001 | summary: C0
1013 | summary: C0
1002 |
1014 |
1003 | o changeset: 3:b69f5839d2d9
1015 | o changeset: 3:b69f5839d2d9
1004 | | user: test
1016 | | user: test
1005 | | date: Thu Jan 01 00:00:00 1970 +0000
1017 | | date: Thu Jan 01 00:00:00 1970 +0000
1006 | | summary: D0
1018 | | summary: D0
1007 | |
1019 | |
1008 | o changeset: 2:f58c7e2b28fa
1020 | o changeset: 2:f58c7e2b28fa
1009 | | user: test
1021 | | user: test
1010 | | date: Thu Jan 01 00:00:00 1970 +0000
1022 | | date: Thu Jan 01 00:00:00 1970 +0000
1011 | | summary: C0
1023 | | summary: C0
1012 | |
1024 | |
1013 | o changeset: 1:3d7bba921b5d
1025 | o changeset: 1:3d7bba921b5d
1014 |/ user: test
1026 |/ user: test
1015 | date: Thu Jan 01 00:00:00 1970 +0000
1027 | date: Thu Jan 01 00:00:00 1970 +0000
1016 | summary: B0
1028 | summary: B0
1017 |
1029 |
1018 o changeset: 0:11f7a1b56675
1030 o changeset: 0:11f7a1b56675
1019 user: test
1031 user: test
1020 date: Thu Jan 01 00:00:00 1970 +0000
1032 date: Thu Jan 01 00:00:00 1970 +0000
1021 summary: A0
1033 summary: A0
1022
1034
1023
1035
1024 Test the cases A.4 (f1x), the "ping-pong" special case of A.7 (f5x),
1036 Test the cases A.4 (f1x), the "ping-pong" special case of A.7 (f5x),
1025 and A.3 with a local content change to be preserved (f2x).
1037 and A.3 with a local content change to be preserved (f2x).
1026
1038
1027 $ HGEDITOR="echo C2 >" hg graft -r 'desc("C0")' --edit
1039 $ HGEDITOR="echo C2 >" hg graft -r 'desc("C0")' --edit
1028 grafting 2:f58c7e2b28fa "C0"
1040 grafting 2:f58c7e2b28fa "C0"
1029 other [graft] changed f1b which local [local] deleted
1041 other [graft] changed f1b which local [local] deleted
1030 use (c)hanged version, leave (d)eleted, or leave (u)nresolved? u
1042 use (c)hanged version, leave (d)eleted, or leave (u)nresolved? u
1031 merging f2a and f2c to f2c
1043 merging f2a and f2c to f2c
1044 merging f5b and f5a to f5a
1032 abort: unresolved conflicts, can't continue
1045 abort: unresolved conflicts, can't continue
1033 (use 'hg resolve' and 'hg graft --continue')
1046 (use 'hg resolve' and 'hg graft --continue')
1034 [255]
1047 [255]
1035 $ hg resolve f1b -t ':other' # XXX work around failure
1048 $ hg resolve f1b -t ':other' # XXX work around failure
1036 (no more unresolved files)
1049 (no more unresolved files)
1037 continue: hg graft --continue
1050 continue: hg graft --continue
1038 $ hg graft --continue # XXX work around failure
1051 $ hg graft --continue # XXX work around failure
1039 grafting 2:f58c7e2b28fa "C0"
1052 grafting 2:f58c7e2b28fa "C0"
1040 grafting 4:af23416e619b "C0"
1053 grafting 4:43e4b415492d "C0"
1054 merging f1e and f1a to f1e
1041 merging f2c
1055 merging f2c
1042 warning: can't find ancestor for 'f2c' copied from 'f2a'!
1056 warning: can't find ancestor for 'f2c' copied from 'f2a'!
1043
1057
1044 Test the cases A.1 (f4x) and A.7 (f3x).
1058 Test the cases A.1 (f4x) and A.7 (f3x).
1045
1059
1046 $ HGEDITOR="echo D2 >" hg graft -r 'desc("D0")' --edit
1060 $ HGEDITOR="echo D2 >" hg graft -r 'desc("D0")' --edit
1047 grafting 3:b69f5839d2d9 "D0"
1061 grafting 3:b69f5839d2d9 "D0"
1048 merging f4e and f4a to f4e
1062 merging f4e and f4a to f4e
1049 warning: can't find ancestor for 'f3d' copied from 'f3b'!
1063 warning: can't find ancestor for 'f3d' copied from 'f3b'!
1050
1064
1051 Check the results of the grafts tested
1065 Check the results of the grafts tested
1052
1066
1053 $ hg log -CGv --patch --git
1067 $ hg log -CGv --patch --git
1054 @ changeset: 9:6d76b84e6e84
1068 @ changeset: 9:100f4d78e056
1055 | tag: tip
1069 | tag: tip
1056 | user: test
1070 | user: test
1057 | date: Thu Jan 01 00:00:00 1970 +0000
1071 | date: Thu Jan 01 00:00:00 1970 +0000
1058 | files: f3d f4e
1072 | files: f3d f4e
1059 | description:
1073 | description:
1060 | D2
1074 | D2
1061 |
1075 |
1062 |
1076 |
1063 | diff --git a/f3d b/f3d
1077 | diff --git a/f3d b/f3d
1064 | new file mode 100644
1078 | new file mode 100644
1065 | --- /dev/null
1079 | --- /dev/null
1066 | +++ b/f3d
1080 | +++ b/f3d
1067 | @@ -0,0 +1,1 @@
1081 | @@ -0,0 +1,1 @@
1068 | +c3a
1082 | +c3a
1069 | diff --git a/f4e b/f4e
1083 | diff --git a/f4e b/f4e
1070 | --- a/f4e
1084 | --- a/f4e
1071 | +++ b/f4e
1085 | +++ b/f4e
1072 | @@ -1,1 +1,1 @@
1086 | @@ -1,1 +1,1 @@
1073 | -c4a
1087 | -c4a
1074 | +c4d
1088 | +c4d
1075 |
1089 |
1076 o changeset: 8:3079ba7d03f0
1090 o changeset: 8:84915a7da133
1077 | user: test
1091 | user: test
1078 | date: Thu Jan 01 00:00:00 1970 +0000
1092 | date: Thu Jan 01 00:00:00 1970 +0000
1093 | files: f1e f5a.orig
1079 | description:
1094 | description:
1080 | C0
1095 | C0
1081 |
1096 |
1082 |
1097 |
1098 | diff --git a/f1e b/f1e
1099 | --- a/f1e
1100 | +++ b/f1e
1101 | @@ -1,1 +1,1 @@
1102 | -c1a
1103 | +c1c
1104 | diff --git a/f5a.orig b/f5a.orig
1105 | deleted file mode 100644
1106 | --- a/f5a.orig
1107 | +++ /dev/null
1108 | @@ -1,5 +0,0 @@
1109 | -<<<<<<< local: 11f7a1b56675 - test: A0
1110 | -c5a
1111 | -=======
1112 | -c5c
1113 | ->>>>>>> graft: f58c7e2b28fa - test: C0
1083 |
1114 |
1084 o changeset: 7:dc778749ee9a
1115 o changeset: 7:dc778749ee9a
1085 | user: test
1116 | user: test
1086 | date: Thu Jan 01 00:00:00 1970 +0000
1117 | date: Thu Jan 01 00:00:00 1970 +0000
1087 | files: f1b f2a f2c f5a f5b
1118 | files: f1b f2a f2c f5a f5b
1088 | copies: f2c (f2a) f5a (f5b)
1119 | copies: f2c (f2a) f5a (f5b)
1089 | description:
1120 | description:
1090 | C0
1121 | C0
1091 |
1122 |
1092 |
1123 |
1093 | diff --git a/f1b b/f1b
1124 | diff --git a/f1b b/f1b
1094 | new file mode 100644
1125 | new file mode 100644
1095 | --- /dev/null
1126 | --- /dev/null
1096 | +++ b/f1b
1127 | +++ b/f1b
1097 | @@ -0,0 +1,1 @@
1128 | @@ -0,0 +1,1 @@
1098 | +c1c
1129 | +c1c
1099 | diff --git a/f2a b/f2c
1130 | diff --git a/f2a b/f2c
1100 | rename from f2a
1131 | rename from f2a
1101 | rename to f2c
1132 | rename to f2c
1102 | diff --git a/f5b b/f5a
1133 | diff --git a/f5b b/f5a
1103 | rename from f5b
1134 | rename from f5b
1104 | rename to f5a
1135 | rename to f5a
1105 | --- a/f5b
1136 | --- a/f5b
1106 | +++ b/f5a
1137 | +++ b/f5a
1107 | @@ -1,1 +1,1 @@
1138 | @@ -1,1 +1,1 @@
1108 | -c5a
1139 | -c5a
1109 | +c5c
1140 | +c5c
1110 |
1141 |
1111 o changeset: 6:ebba59d1fb02
1142 o changeset: 6:ebba59d1fb02
1112 | parent: 0:11f7a1b56675
1143 | parent: 0:11f7a1b56675
1113 | user: test
1144 | user: test
1114 | date: Thu Jan 01 00:00:00 1970 +0000
1145 | date: Thu Jan 01 00:00:00 1970 +0000
1115 | files: f1a f1e f2a f3a f3e f4a f4e f5a f5a.orig f5b
1146 | files: f1a f1e f2a f3a f3e f4a f4e f5a f5a.orig f5b
1116 | copies: f1e (f1a) f3e (f3a) f4e (f4a) f5b (f5a)
1147 | copies: f1e (f1a) f3e (f3a) f4e (f4a) f5b (f5a)
1117 | description:
1148 | description:
1118 | E0
1149 | E0
1119 |
1150 |
1120 |
1151 |
1121 | diff --git a/f1a b/f1e
1152 | diff --git a/f1a b/f1e
1122 | rename from f1a
1153 | rename from f1a
1123 | rename to f1e
1154 | rename to f1e
1124 | diff --git a/f2a b/f2a
1155 | diff --git a/f2a b/f2a
1125 | --- a/f2a
1156 | --- a/f2a
1126 | +++ b/f2a
1157 | +++ b/f2a
1127 | @@ -1,1 +1,1 @@
1158 | @@ -1,1 +1,1 @@
1128 | -c2a
1159 | -c2a
1129 | +c2e
1160 | +c2e
1130 | diff --git a/f3a b/f3e
1161 | diff --git a/f3a b/f3e
1131 | rename from f3a
1162 | rename from f3a
1132 | rename to f3e
1163 | rename to f3e
1133 | diff --git a/f4a b/f4e
1164 | diff --git a/f4a b/f4e
1134 | rename from f4a
1165 | rename from f4a
1135 | rename to f4e
1166 | rename to f4e
1136 | diff --git a/f5a.orig b/f5a.orig
1167 | diff --git a/f5a.orig b/f5a.orig
1137 | new file mode 100644
1168 | new file mode 100644
1138 | --- /dev/null
1169 | --- /dev/null
1139 | +++ b/f5a.orig
1170 | +++ b/f5a.orig
1140 | @@ -0,0 +1,5 @@
1171 | @@ -0,0 +1,5 @@
1141 | +<<<<<<< local: 11f7a1b56675 - test: A0
1172 | +<<<<<<< local: 11f7a1b56675 - test: A0
1142 | +c5a
1173 | +c5a
1143 | +=======
1174 | +=======
1144 | +c5c
1175 | +c5c
1145 | +>>>>>>> graft: f58c7e2b28fa - test: C0
1176 | +>>>>>>> graft: f58c7e2b28fa - test: C0
1146 | diff --git a/f5a b/f5b
1177 | diff --git a/f5a b/f5b
1147 | rename from f5a
1178 | rename from f5a
1148 | rename to f5b
1179 | rename to f5b
1149 |
1180 |
1150 | o changeset: 5:573bb6b4b56d
1181 | o changeset: 5:4f4ba7a6e606
1151 | | user: test
1182 | | user: test
1152 | | date: Thu Jan 01 00:00:00 1970 +0000
1183 | | date: Thu Jan 01 00:00:00 1970 +0000
1153 | | files: f3d f4a
1184 | | files: f3d f4a
1154 | | description:
1185 | | description:
1155 | | D1
1186 | | D1
1156 | |
1187 | |
1157 | |
1188 | |
1158 | | diff --git a/f3d b/f3d
1189 | | diff --git a/f3d b/f3d
1159 | | new file mode 100644
1190 | | new file mode 100644
1160 | | --- /dev/null
1191 | | --- /dev/null
1161 | | +++ b/f3d
1192 | | +++ b/f3d
1162 | | @@ -0,0 +1,1 @@
1193 | | @@ -0,0 +1,1 @@
1163 | | +c3a
1194 | | +c3a
1164 | | diff --git a/f4a b/f4a
1195 | | diff --git a/f4a b/f4a
1165 | | --- a/f4a
1196 | | --- a/f4a
1166 | | +++ b/f4a
1197 | | +++ b/f4a
1167 | | @@ -1,1 +1,1 @@
1198 | | @@ -1,1 +1,1 @@
1168 | | -c4a
1199 | | -c4a
1169 | | +c4d
1200 | | +c4d
1170 | |
1201 | |
1171 | o changeset: 4:af23416e619b
1202 | o changeset: 4:43e4b415492d
1172 |/ parent: 0:11f7a1b56675
1203 |/ parent: 0:11f7a1b56675
1173 | user: test
1204 | user: test
1174 | date: Thu Jan 01 00:00:00 1970 +0000
1205 | date: Thu Jan 01 00:00:00 1970 +0000
1175 | files: f1b f2a f2c f5a
1206 | files: f1a f2a f2c f5a
1176 | copies: f2c (f2a)
1207 | copies: f2c (f2a)
1177 | description:
1208 | description:
1178 | C0
1209 | C0
1179 |
1210 |
1180 |
1211 |
1181 | diff --git a/f1b b/f1b
1212 | diff --git a/f1a b/f1a
1182 | new file mode 100644
1213 | --- a/f1a
1183 | --- /dev/null
1214 | +++ b/f1a
1184 | +++ b/f1b
1215 | @@ -1,1 +1,1 @@
1185 | @@ -0,0 +1,1 @@
1216 | -c1a
1186 | +c1c
1217 | +c1c
1187 | diff --git a/f2a b/f2c
1218 | diff --git a/f2a b/f2c
1188 | rename from f2a
1219 | rename from f2a
1189 | rename to f2c
1220 | rename to f2c
1190 | diff --git a/f5a b/f5a
1221 | diff --git a/f5a b/f5a
1191 | --- a/f5a
1222 | --- a/f5a
1192 | +++ b/f5a
1223 | +++ b/f5a
1193 | @@ -1,1 +1,1 @@
1224 | @@ -1,1 +1,1 @@
1194 | -c5a
1225 | -c5a
1195 | +c5c
1226 | +c5c
1196 |
1227 |
1197 | o changeset: 3:b69f5839d2d9
1228 | o changeset: 3:b69f5839d2d9
1198 | | user: test
1229 | | user: test
1199 | | date: Thu Jan 01 00:00:00 1970 +0000
1230 | | date: Thu Jan 01 00:00:00 1970 +0000
1200 | | files: f3b f3d f4a
1231 | | files: f3b f3d f4a
1201 | | copies: f3d (f3b)
1232 | | copies: f3d (f3b)
1202 | | description:
1233 | | description:
1203 | | D0
1234 | | D0
1204 | |
1235 | |
1205 | |
1236 | |
1206 | | diff --git a/f3b b/f3d
1237 | | diff --git a/f3b b/f3d
1207 | | rename from f3b
1238 | | rename from f3b
1208 | | rename to f3d
1239 | | rename to f3d
1209 | | diff --git a/f4a b/f4a
1240 | | diff --git a/f4a b/f4a
1210 | | --- a/f4a
1241 | | --- a/f4a
1211 | | +++ b/f4a
1242 | | +++ b/f4a
1212 | | @@ -1,1 +1,1 @@
1243 | | @@ -1,1 +1,1 @@
1213 | | -c4a
1244 | | -c4a
1214 | | +c4d
1245 | | +c4d
1215 | |
1246 | |
1216 | o changeset: 2:f58c7e2b28fa
1247 | o changeset: 2:f58c7e2b28fa
1217 | | user: test
1248 | | user: test
1218 | | date: Thu Jan 01 00:00:00 1970 +0000
1249 | | date: Thu Jan 01 00:00:00 1970 +0000
1219 | | files: f1b f2a f2c f5a f5b
1250 | | files: f1b f2a f2c f5a f5b
1220 | | copies: f2c (f2a) f5a (f5b)
1251 | | copies: f2c (f2a) f5a (f5b)
1221 | | description:
1252 | | description:
1222 | | C0
1253 | | C0
1223 | |
1254 | |
1224 | |
1255 | |
1225 | | diff --git a/f1b b/f1b
1256 | | diff --git a/f1b b/f1b
1226 | | --- a/f1b
1257 | | --- a/f1b
1227 | | +++ b/f1b
1258 | | +++ b/f1b
1228 | | @@ -1,1 +1,1 @@
1259 | | @@ -1,1 +1,1 @@
1229 | | -c1a
1260 | | -c1a
1230 | | +c1c
1261 | | +c1c
1231 | | diff --git a/f2a b/f2c
1262 | | diff --git a/f2a b/f2c
1232 | | rename from f2a
1263 | | rename from f2a
1233 | | rename to f2c
1264 | | rename to f2c
1234 | | diff --git a/f5b b/f5a
1265 | | diff --git a/f5b b/f5a
1235 | | rename from f5b
1266 | | rename from f5b
1236 | | rename to f5a
1267 | | rename to f5a
1237 | | --- a/f5b
1268 | | --- a/f5b
1238 | | +++ b/f5a
1269 | | +++ b/f5a
1239 | | @@ -1,1 +1,1 @@
1270 | | @@ -1,1 +1,1 @@
1240 | | -c5a
1271 | | -c5a
1241 | | +c5c
1272 | | +c5c
1242 | |
1273 | |
1243 | o changeset: 1:3d7bba921b5d
1274 | o changeset: 1:3d7bba921b5d
1244 |/ user: test
1275 |/ user: test
1245 | date: Thu Jan 01 00:00:00 1970 +0000
1276 | date: Thu Jan 01 00:00:00 1970 +0000
1246 | files: f1a f1b f3a f3b f5a f5b
1277 | files: f1a f1b f3a f3b f5a f5b
1247 | copies: f1b (f1a) f3b (f3a) f5b (f5a)
1278 | copies: f1b (f1a) f3b (f3a) f5b (f5a)
1248 | description:
1279 | description:
1249 | B0
1280 | B0
1250 |
1281 |
1251 |
1282 |
1252 | diff --git a/f1a b/f1b
1283 | diff --git a/f1a b/f1b
1253 | rename from f1a
1284 | rename from f1a
1254 | rename to f1b
1285 | rename to f1b
1255 | diff --git a/f3a b/f3b
1286 | diff --git a/f3a b/f3b
1256 | rename from f3a
1287 | rename from f3a
1257 | rename to f3b
1288 | rename to f3b
1258 | diff --git a/f5a b/f5b
1289 | diff --git a/f5a b/f5b
1259 | rename from f5a
1290 | rename from f5a
1260 | rename to f5b
1291 | rename to f5b
1261 |
1292 |
1262 o changeset: 0:11f7a1b56675
1293 o changeset: 0:11f7a1b56675
1263 user: test
1294 user: test
1264 date: Thu Jan 01 00:00:00 1970 +0000
1295 date: Thu Jan 01 00:00:00 1970 +0000
1265 files: f1a f2a f3a f4a f5a
1296 files: f1a f2a f3a f4a f5a
1266 description:
1297 description:
1267 A0
1298 A0
1268
1299
1269
1300
1270 diff --git a/f1a b/f1a
1301 diff --git a/f1a b/f1a
1271 new file mode 100644
1302 new file mode 100644
1272 --- /dev/null
1303 --- /dev/null
1273 +++ b/f1a
1304 +++ b/f1a
1274 @@ -0,0 +1,1 @@
1305 @@ -0,0 +1,1 @@
1275 +c1a
1306 +c1a
1276 diff --git a/f2a b/f2a
1307 diff --git a/f2a b/f2a
1277 new file mode 100644
1308 new file mode 100644
1278 --- /dev/null
1309 --- /dev/null
1279 +++ b/f2a
1310 +++ b/f2a
1280 @@ -0,0 +1,1 @@
1311 @@ -0,0 +1,1 @@
1281 +c2a
1312 +c2a
1282 diff --git a/f3a b/f3a
1313 diff --git a/f3a b/f3a
1283 new file mode 100644
1314 new file mode 100644
1284 --- /dev/null
1315 --- /dev/null
1285 +++ b/f3a
1316 +++ b/f3a
1286 @@ -0,0 +1,1 @@
1317 @@ -0,0 +1,1 @@
1287 +c3a
1318 +c3a
1288 diff --git a/f4a b/f4a
1319 diff --git a/f4a b/f4a
1289 new file mode 100644
1320 new file mode 100644
1290 --- /dev/null
1321 --- /dev/null
1291 +++ b/f4a
1322 +++ b/f4a
1292 @@ -0,0 +1,1 @@
1323 @@ -0,0 +1,1 @@
1293 +c4a
1324 +c4a
1294 diff --git a/f5a b/f5a
1325 diff --git a/f5a b/f5a
1295 new file mode 100644
1326 new file mode 100644
1296 --- /dev/null
1327 --- /dev/null
1297 +++ b/f5a
1328 +++ b/f5a
1298 @@ -0,0 +1,1 @@
1329 @@ -0,0 +1,1 @@
1299 +c5a
1330 +c5a
1300
1331
1301 $ hg cat f2c
1332 $ hg cat f2c
1302 c2e
1333 c2e
@@ -1,359 +1,363
1 $ cat >> $HGRCPATH <<EOF
1 $ cat >> $HGRCPATH <<EOF
2 > [format]
2 > [format]
3 > usegeneraldelta=yes
3 > usegeneraldelta=yes
4 > [extensions]
4 > [extensions]
5 > rebase=
5 > rebase=
6 >
6 >
7 > [phases]
7 > [phases]
8 > publish=False
8 > publish=False
9 >
9 >
10 > [alias]
10 > [alias]
11 > tglog = log -G --template "{rev}:{phase} '{desc}' {branches} {bookmarks}\n"
11 > tglog = log -G --template "{rev}:{phase} '{desc}' {branches} {bookmarks}\n"
12 > EOF
12 > EOF
13
13
14 $ hg init a
14 $ hg init a
15 $ cd a
15 $ cd a
16 $ echo c1 >common
16 $ echo c1 >common
17 $ hg add common
17 $ hg add common
18 $ hg ci -m C1
18 $ hg ci -m C1
19
19
20 $ echo c2 >>common
20 $ echo c2 >>common
21 $ hg ci -m C2
21 $ hg ci -m C2
22
22
23 $ echo c3 >>common
23 $ echo c3 >>common
24 $ hg ci -m C3
24 $ hg ci -m C3
25
25
26 $ hg up -q -C 1
26 $ hg up -q -C 1
27
27
28 $ echo l1 >>extra
28 $ echo l1 >>extra
29 $ hg add extra
29 $ hg add extra
30 $ hg ci -m L1
30 $ hg ci -m L1
31 created new head
31 created new head
32
32
33 $ sed -e 's/c2/l2/' common > common.new
33 $ sed -e 's/c2/l2/' common > common.new
34 $ mv common.new common
34 $ mv common.new common
35 $ hg ci -m L2
35 $ hg ci -m L2
36
36
37 $ echo l3 >> extra2
37 $ echo l3 >> extra2
38 $ hg add extra2
38 $ hg add extra2
39 $ hg ci -m L3
39 $ hg ci -m L3
40 $ hg bookmark mybook
40 $ hg bookmark mybook
41
41
42 $ hg phase --force --secret 4
42 $ hg phase --force --secret 4
43
43
44 $ hg tglog
44 $ hg tglog
45 @ 5:secret 'L3' mybook
45 @ 5:secret 'L3' mybook
46 |
46 |
47 o 4:secret 'L2'
47 o 4:secret 'L2'
48 |
48 |
49 o 3:draft 'L1'
49 o 3:draft 'L1'
50 |
50 |
51 | o 2:draft 'C3'
51 | o 2:draft 'C3'
52 |/
52 |/
53 o 1:draft 'C2'
53 o 1:draft 'C2'
54 |
54 |
55 o 0:draft 'C1'
55 o 0:draft 'C1'
56
56
57 Try to call --continue:
57 Try to call --continue:
58
58
59 $ hg rebase --continue
59 $ hg rebase --continue
60 abort: no rebase in progress
60 abort: no rebase in progress
61 [255]
61 [255]
62
62
63 Conflicting rebase:
63 Conflicting rebase:
64
64
65 $ hg rebase -s 3 -d 2
65 $ hg rebase -s 3 -d 2
66 rebasing 3:3163e20567cc "L1"
66 rebasing 3:3163e20567cc "L1"
67 rebasing 4:46f0b057b5c0 "L2"
67 rebasing 4:46f0b057b5c0 "L2"
68 merging common
68 merging common
69 warning: conflicts while merging common! (edit, then use 'hg resolve --mark')
69 warning: conflicts while merging common! (edit, then use 'hg resolve --mark')
70 unresolved conflicts (see hg resolve, then hg rebase --continue)
70 unresolved conflicts (see hg resolve, then hg rebase --continue)
71 [1]
71 [1]
72
72
73 Try to continue without solving the conflict:
73 Try to continue without solving the conflict:
74
74
75 $ hg rebase --continue
75 $ hg rebase --continue
76 already rebased 3:3163e20567cc "L1" as 3e046f2ecedb
76 already rebased 3:3163e20567cc "L1" as 3e046f2ecedb
77 rebasing 4:46f0b057b5c0 "L2"
77 rebasing 4:46f0b057b5c0 "L2"
78 abort: unresolved merge conflicts (see 'hg help resolve')
78 abort: unresolved merge conflicts (see 'hg help resolve')
79 [255]
79 [255]
80
80
81 Conclude rebase:
81 Conclude rebase:
82
82
83 $ echo 'resolved merge' >common
83 $ echo 'resolved merge' >common
84 $ hg resolve -m common
84 $ hg resolve -m common
85 (no more unresolved files)
85 (no more unresolved files)
86 continue: hg rebase --continue
86 continue: hg rebase --continue
87 $ hg rebase --continue
87 $ hg rebase --continue
88 already rebased 3:3163e20567cc "L1" as 3e046f2ecedb
88 already rebased 3:3163e20567cc "L1" as 3e046f2ecedb
89 rebasing 4:46f0b057b5c0 "L2"
89 rebasing 4:46f0b057b5c0 "L2"
90 rebasing 5:8029388f38dc "L3" (mybook)
90 rebasing 5:8029388f38dc "L3" (mybook)
91 saved backup bundle to $TESTTMP/a/.hg/strip-backup/3163e20567cc-5ca4656e-backup.hg (glob)
91 saved backup bundle to $TESTTMP/a/.hg/strip-backup/3163e20567cc-5ca4656e-backup.hg (glob)
92
92
93 $ hg tglog
93 $ hg tglog
94 @ 5:secret 'L3' mybook
94 @ 5:secret 'L3' mybook
95 |
95 |
96 o 4:secret 'L2'
96 o 4:secret 'L2'
97 |
97 |
98 o 3:draft 'L1'
98 o 3:draft 'L1'
99 |
99 |
100 o 2:draft 'C3'
100 o 2:draft 'C3'
101 |
101 |
102 o 1:draft 'C2'
102 o 1:draft 'C2'
103 |
103 |
104 o 0:draft 'C1'
104 o 0:draft 'C1'
105
105
106 Check correctness:
106 Check correctness:
107
107
108 $ hg cat -r 0 common
108 $ hg cat -r 0 common
109 c1
109 c1
110
110
111 $ hg cat -r 1 common
111 $ hg cat -r 1 common
112 c1
112 c1
113 c2
113 c2
114
114
115 $ hg cat -r 2 common
115 $ hg cat -r 2 common
116 c1
116 c1
117 c2
117 c2
118 c3
118 c3
119
119
120 $ hg cat -r 3 common
120 $ hg cat -r 3 common
121 c1
121 c1
122 c2
122 c2
123 c3
123 c3
124
124
125 $ hg cat -r 4 common
125 $ hg cat -r 4 common
126 resolved merge
126 resolved merge
127
127
128 $ hg cat -r 5 common
128 $ hg cat -r 5 common
129 resolved merge
129 resolved merge
130
130
131 Bookmark stays active after --continue
131 Bookmark stays active after --continue
132 $ hg bookmarks
132 $ hg bookmarks
133 * mybook 5:d67b21408fc0
133 * mybook 5:d67b21408fc0
134
134
135 $ cd ..
135 $ cd ..
136
136
137 Check that the right ancestors is used while rebasing a merge (issue4041)
137 Check that the right ancestors is used while rebasing a merge (issue4041)
138
138
139 $ hg clone "$TESTDIR/bundles/issue4041.hg" issue4041
139 $ hg clone "$TESTDIR/bundles/issue4041.hg" issue4041
140 requesting all changes
140 requesting all changes
141 adding changesets
141 adding changesets
142 adding manifests
142 adding manifests
143 adding file changes
143 adding file changes
144 added 11 changesets with 8 changes to 3 files (+1 heads)
144 added 11 changesets with 8 changes to 3 files (+1 heads)
145 updating to branch default
145 updating to branch default
146 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
146 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
147 $ cd issue4041
147 $ cd issue4041
148 $ hg log -G
148 $ hg log -G
149 o changeset: 10:2f2496ddf49d
149 o changeset: 10:2f2496ddf49d
150 |\ branch: f1
150 |\ branch: f1
151 | | tag: tip
151 | | tag: tip
152 | | parent: 7:4c9fbe56a16f
152 | | parent: 7:4c9fbe56a16f
153 | | parent: 9:e31216eec445
153 | | parent: 9:e31216eec445
154 | | user: szhang
154 | | user: szhang
155 | | date: Thu Sep 05 12:59:39 2013 -0400
155 | | date: Thu Sep 05 12:59:39 2013 -0400
156 | | summary: merge
156 | | summary: merge
157 | |
157 | |
158 | o changeset: 9:e31216eec445
158 | o changeset: 9:e31216eec445
159 | | branch: f1
159 | | branch: f1
160 | | user: szhang
160 | | user: szhang
161 | | date: Thu Sep 05 12:59:10 2013 -0400
161 | | date: Thu Sep 05 12:59:10 2013 -0400
162 | | summary: more changes to f1
162 | | summary: more changes to f1
163 | |
163 | |
164 | o changeset: 8:8e4e2c1a07ae
164 | o changeset: 8:8e4e2c1a07ae
165 | |\ branch: f1
165 | |\ branch: f1
166 | | | parent: 2:4bc80088dc6b
166 | | | parent: 2:4bc80088dc6b
167 | | | parent: 6:400110238667
167 | | | parent: 6:400110238667
168 | | | user: szhang
168 | | | user: szhang
169 | | | date: Thu Sep 05 12:57:59 2013 -0400
169 | | | date: Thu Sep 05 12:57:59 2013 -0400
170 | | | summary: bad merge
170 | | | summary: bad merge
171 | | |
171 | | |
172 o | | changeset: 7:4c9fbe56a16f
172 o | | changeset: 7:4c9fbe56a16f
173 |/ / branch: f1
173 |/ / branch: f1
174 | | parent: 2:4bc80088dc6b
174 | | parent: 2:4bc80088dc6b
175 | | user: szhang
175 | | user: szhang
176 | | date: Thu Sep 05 12:54:00 2013 -0400
176 | | date: Thu Sep 05 12:54:00 2013 -0400
177 | | summary: changed f1
177 | | summary: changed f1
178 | |
178 | |
179 | o changeset: 6:400110238667
179 | o changeset: 6:400110238667
180 | | branch: f2
180 | | branch: f2
181 | | parent: 4:12e8ec6bb010
181 | | parent: 4:12e8ec6bb010
182 | | user: szhang
182 | | user: szhang
183 | | date: Tue Sep 03 13:58:02 2013 -0400
183 | | date: Tue Sep 03 13:58:02 2013 -0400
184 | | summary: changed f2 on f2
184 | | summary: changed f2 on f2
185 | |
185 | |
186 | | @ changeset: 5:d79e2059b5c0
186 | | @ changeset: 5:d79e2059b5c0
187 | | | parent: 3:8a951942e016
187 | | | parent: 3:8a951942e016
188 | | | user: szhang
188 | | | user: szhang
189 | | | date: Tue Sep 03 13:57:39 2013 -0400
189 | | | date: Tue Sep 03 13:57:39 2013 -0400
190 | | | summary: changed f2 on default
190 | | | summary: changed f2 on default
191 | | |
191 | | |
192 | o | changeset: 4:12e8ec6bb010
192 | o | changeset: 4:12e8ec6bb010
193 | |/ branch: f2
193 | |/ branch: f2
194 | | user: szhang
194 | | user: szhang
195 | | date: Tue Sep 03 13:57:18 2013 -0400
195 | | date: Tue Sep 03 13:57:18 2013 -0400
196 | | summary: created f2 branch
196 | | summary: created f2 branch
197 | |
197 | |
198 | o changeset: 3:8a951942e016
198 | o changeset: 3:8a951942e016
199 | | parent: 0:24797d4f68de
199 | | parent: 0:24797d4f68de
200 | | user: szhang
200 | | user: szhang
201 | | date: Tue Sep 03 13:57:11 2013 -0400
201 | | date: Tue Sep 03 13:57:11 2013 -0400
202 | | summary: added f2.txt
202 | | summary: added f2.txt
203 | |
203 | |
204 o | changeset: 2:4bc80088dc6b
204 o | changeset: 2:4bc80088dc6b
205 | | branch: f1
205 | | branch: f1
206 | | user: szhang
206 | | user: szhang
207 | | date: Tue Sep 03 13:56:20 2013 -0400
207 | | date: Tue Sep 03 13:56:20 2013 -0400
208 | | summary: added f1.txt
208 | | summary: added f1.txt
209 | |
209 | |
210 o | changeset: 1:ef53c9e6b608
210 o | changeset: 1:ef53c9e6b608
211 |/ branch: f1
211 |/ branch: f1
212 | user: szhang
212 | user: szhang
213 | date: Tue Sep 03 13:55:26 2013 -0400
213 | date: Tue Sep 03 13:55:26 2013 -0400
214 | summary: created f1 branch
214 | summary: created f1 branch
215 |
215 |
216 o changeset: 0:24797d4f68de
216 o changeset: 0:24797d4f68de
217 user: szhang
217 user: szhang
218 date: Tue Sep 03 13:55:08 2013 -0400
218 date: Tue Sep 03 13:55:08 2013 -0400
219 summary: added default.txt
219 summary: added default.txt
220
220
221 $ hg rebase -s9 -d2 --debug # use debug to really check merge base used
221 $ hg rebase -s9 -d2 --debug # use debug to really check merge base used
222 rebase onto 4bc80088dc6b starting from e31216eec445
222 rebase onto 4bc80088dc6b starting from e31216eec445
223 ignoring null merge rebase of 3
223 ignoring null merge rebase of 3
224 ignoring null merge rebase of 4
224 ignoring null merge rebase of 4
225 ignoring null merge rebase of 6
225 ignoring null merge rebase of 6
226 ignoring null merge rebase of 8
226 ignoring null merge rebase of 8
227 rebasing 9:e31216eec445 "more changes to f1"
227 rebasing 9:e31216eec445 "more changes to f1"
228 future parents are 2 and -1
228 future parents are 2 and -1
229 rebase status stored
229 rebase status stored
230 update to 2:4bc80088dc6b
230 update to 2:4bc80088dc6b
231 resolving manifests
231 resolving manifests
232 branchmerge: False, force: True, partial: False
232 branchmerge: False, force: True, partial: False
233 ancestor: d79e2059b5c0+, local: d79e2059b5c0+, remote: 4bc80088dc6b
233 ancestor: d79e2059b5c0+, local: d79e2059b5c0+, remote: 4bc80088dc6b
234 f2.txt: other deleted -> r
234 f2.txt: other deleted -> r
235 removing f2.txt
235 removing f2.txt
236 f1.txt: remote created -> g
236 f1.txt: remote created -> g
237 getting f1.txt
237 getting f1.txt
238 merge against 9:e31216eec445
238 merge against 9:e31216eec445
239 detach base 8:8e4e2c1a07ae
239 detach base 8:8e4e2c1a07ae
240 searching for copies back to rev 3
240 searching for copies back to rev 3
241 unmatched files in other (from topological common ancestor):
242 f2.txt
241 resolving manifests
243 resolving manifests
242 branchmerge: True, force: True, partial: False
244 branchmerge: True, force: True, partial: False
243 ancestor: 8e4e2c1a07ae, local: 4bc80088dc6b+, remote: e31216eec445
245 ancestor: 8e4e2c1a07ae, local: 4bc80088dc6b+, remote: e31216eec445
244 f1.txt: remote is newer -> g
246 f1.txt: remote is newer -> g
245 getting f1.txt
247 getting f1.txt
246 committing files:
248 committing files:
247 f1.txt
249 f1.txt
248 committing manifest
250 committing manifest
249 committing changelog
251 committing changelog
250 rebased as 19c888675e13
252 rebased as 19c888675e13
251 rebasing 10:2f2496ddf49d "merge" (tip)
253 rebasing 10:2f2496ddf49d "merge" (tip)
252 future parents are 11 and 7
254 future parents are 11 and 7
253 rebase status stored
255 rebase status stored
254 already in target
256 already in target
255 merge against 10:2f2496ddf49d
257 merge against 10:2f2496ddf49d
256 detach base 9:e31216eec445
258 detach base 9:e31216eec445
257 searching for copies back to rev 3
259 searching for copies back to rev 3
260 unmatched files in other (from topological common ancestor):
261 f2.txt
258 resolving manifests
262 resolving manifests
259 branchmerge: True, force: True, partial: False
263 branchmerge: True, force: True, partial: False
260 ancestor: e31216eec445, local: 19c888675e13+, remote: 2f2496ddf49d
264 ancestor: e31216eec445, local: 19c888675e13+, remote: 2f2496ddf49d
261 f1.txt: remote is newer -> g
265 f1.txt: remote is newer -> g
262 getting f1.txt
266 getting f1.txt
263 committing files:
267 committing files:
264 f1.txt
268 f1.txt
265 committing manifest
269 committing manifest
266 committing changelog
270 committing changelog
267 rebased as 2a7f09cac94c
271 rebased as 2a7f09cac94c
268 rebase merging completed
272 rebase merging completed
269 update back to initial working directory parent
273 update back to initial working directory parent
270 resolving manifests
274 resolving manifests
271 branchmerge: False, force: False, partial: False
275 branchmerge: False, force: False, partial: False
272 ancestor: 2a7f09cac94c, local: 2a7f09cac94c+, remote: d79e2059b5c0
276 ancestor: 2a7f09cac94c, local: 2a7f09cac94c+, remote: d79e2059b5c0
273 f1.txt: other deleted -> r
277 f1.txt: other deleted -> r
274 removing f1.txt
278 removing f1.txt
275 f2.txt: remote created -> g
279 f2.txt: remote created -> g
276 getting f2.txt
280 getting f2.txt
277 2 changesets found
281 2 changesets found
278 list of changesets:
282 list of changesets:
279 e31216eec445e44352c5f01588856059466a24c9
283 e31216eec445e44352c5f01588856059466a24c9
280 2f2496ddf49d69b5ef23ad8cf9fb2e0e4faf0ac2
284 2f2496ddf49d69b5ef23ad8cf9fb2e0e4faf0ac2
281 bundle2-output-bundle: "HG20", (1 params) 1 parts total
285 bundle2-output-bundle: "HG20", (1 params) 1 parts total
282 bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
286 bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
283 saved backup bundle to $TESTTMP/issue4041/.hg/strip-backup/e31216eec445-15f7a814-backup.hg (glob)
287 saved backup bundle to $TESTTMP/issue4041/.hg/strip-backup/e31216eec445-15f7a814-backup.hg (glob)
284 3 changesets found
288 3 changesets found
285 list of changesets:
289 list of changesets:
286 4c9fbe56a16f30c0d5dcc40ec1a97bbe3325209c
290 4c9fbe56a16f30c0d5dcc40ec1a97bbe3325209c
287 19c888675e133ab5dff84516926a65672eaf04d9
291 19c888675e133ab5dff84516926a65672eaf04d9
288 2a7f09cac94c7f4b73ebd5cd1a62d3b2e8e336bf
292 2a7f09cac94c7f4b73ebd5cd1a62d3b2e8e336bf
289 bundle2-output-bundle: "HG20", 1 parts total
293 bundle2-output-bundle: "HG20", 1 parts total
290 bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
294 bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
291 adding branch
295 adding branch
292 bundle2-input-bundle: with-transaction
296 bundle2-input-bundle: with-transaction
293 bundle2-input-part: "changegroup" (params: 1 mandatory 1 advisory) supported
297 bundle2-input-part: "changegroup" (params: 1 mandatory 1 advisory) supported
294 adding changesets
298 adding changesets
295 add changeset 4c9fbe56a16f
299 add changeset 4c9fbe56a16f
296 add changeset 19c888675e13
300 add changeset 19c888675e13
297 add changeset 2a7f09cac94c
301 add changeset 2a7f09cac94c
298 adding manifests
302 adding manifests
299 adding file changes
303 adding file changes
300 adding f1.txt revisions
304 adding f1.txt revisions
301 added 2 changesets with 2 changes to 1 files
305 added 2 changesets with 2 changes to 1 files
302 bundle2-input-part: total payload size 1713
306 bundle2-input-part: total payload size 1713
303 bundle2-input-bundle: 0 parts total
307 bundle2-input-bundle: 0 parts total
304 invalid branchheads cache (served): tip differs
308 invalid branchheads cache (served): tip differs
305 history modification detected - truncating revision branch cache to revision 9
309 history modification detected - truncating revision branch cache to revision 9
306 rebase completed
310 rebase completed
307 truncating cache/rbc-revs-v1 to 72
311 truncating cache/rbc-revs-v1 to 72
308
312
309 Test minimization of merge conflicts
313 Test minimization of merge conflicts
310 $ hg up -q null
314 $ hg up -q null
311 $ echo a > a
315 $ echo a > a
312 $ hg add a
316 $ hg add a
313 $ hg commit -q -m 'a'
317 $ hg commit -q -m 'a'
314 $ echo b >> a
318 $ echo b >> a
315 $ hg commit -q -m 'ab'
319 $ hg commit -q -m 'ab'
316 $ hg bookmark ab
320 $ hg bookmark ab
317 $ hg up -q '.^'
321 $ hg up -q '.^'
318 $ echo b >> a
322 $ echo b >> a
319 $ echo c >> a
323 $ echo c >> a
320 $ hg commit -q -m 'abc'
324 $ hg commit -q -m 'abc'
321 $ hg rebase -s 7bc217434fc1 -d ab --keep
325 $ hg rebase -s 7bc217434fc1 -d ab --keep
322 rebasing 13:7bc217434fc1 "abc" (tip)
326 rebasing 13:7bc217434fc1 "abc" (tip)
323 merging a
327 merging a
324 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
328 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
325 unresolved conflicts (see hg resolve, then hg rebase --continue)
329 unresolved conflicts (see hg resolve, then hg rebase --continue)
326 [1]
330 [1]
327 $ hg diff
331 $ hg diff
328 diff -r 328e4ab1f7cc a
332 diff -r 328e4ab1f7cc a
329 --- a/a Thu Jan 01 00:00:00 1970 +0000
333 --- a/a Thu Jan 01 00:00:00 1970 +0000
330 +++ b/a * (glob)
334 +++ b/a * (glob)
331 @@ -1,2 +1,6 @@
335 @@ -1,2 +1,6 @@
332 a
336 a
333 b
337 b
334 +<<<<<<< dest: 328e4ab1f7cc ab - test: ab
338 +<<<<<<< dest: 328e4ab1f7cc ab - test: ab
335 +=======
339 +=======
336 +c
340 +c
337 +>>>>>>> source: 7bc217434fc1 - test: abc
341 +>>>>>>> source: 7bc217434fc1 - test: abc
338 $ hg rebase --abort
342 $ hg rebase --abort
339 rebase aborted
343 rebase aborted
340 $ hg up -q -C 7bc217434fc1
344 $ hg up -q -C 7bc217434fc1
341 $ hg rebase -s . -d ab --keep -t internal:merge3
345 $ hg rebase -s . -d ab --keep -t internal:merge3
342 rebasing 13:7bc217434fc1 "abc" (tip)
346 rebasing 13:7bc217434fc1 "abc" (tip)
343 merging a
347 merging a
344 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
348 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
345 unresolved conflicts (see hg resolve, then hg rebase --continue)
349 unresolved conflicts (see hg resolve, then hg rebase --continue)
346 [1]
350 [1]
347 $ hg diff
351 $ hg diff
348 diff -r 328e4ab1f7cc a
352 diff -r 328e4ab1f7cc a
349 --- a/a Thu Jan 01 00:00:00 1970 +0000
353 --- a/a Thu Jan 01 00:00:00 1970 +0000
350 +++ b/a * (glob)
354 +++ b/a * (glob)
351 @@ -1,2 +1,8 @@
355 @@ -1,2 +1,8 @@
352 a
356 a
353 +<<<<<<< dest: 328e4ab1f7cc ab - test: ab
357 +<<<<<<< dest: 328e4ab1f7cc ab - test: ab
354 b
358 b
355 +||||||| base
359 +||||||| base
356 +=======
360 +=======
357 +b
361 +b
358 +c
362 +c
359 +>>>>>>> source: 7bc217434fc1 - test: abc
363 +>>>>>>> source: 7bc217434fc1 - test: abc
General Comments 0
You need to be logged in to leave comments. Login now