##// END OF EJS Templates
phases: prevent rebase to rebase immutable changeset.
Pierre-Yves David -
r15742:65df60a3 default
parent child Browse files
Show More
@@ -1,634 +1,643 b''
1 # rebase.py - rebasing feature for mercurial
1 # rebase.py - rebasing feature for mercurial
2 #
2 #
3 # Copyright 2008 Stefano Tortarolo <stefano.tortarolo at gmail dot com>
3 # Copyright 2008 Stefano Tortarolo <stefano.tortarolo at gmail dot 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 '''command to move sets of revisions to a different ancestor
8 '''command to move sets of revisions to a different ancestor
9
9
10 This extension lets you rebase changesets in an existing Mercurial
10 This extension lets you rebase changesets in an existing Mercurial
11 repository.
11 repository.
12
12
13 For more information:
13 For more information:
14 http://mercurial.selenic.com/wiki/RebaseExtension
14 http://mercurial.selenic.com/wiki/RebaseExtension
15 '''
15 '''
16
16
17 from mercurial import hg, util, repair, merge, cmdutil, commands, bookmarks
17 from mercurial import hg, util, repair, merge, cmdutil, commands, bookmarks
18 from mercurial import extensions, patch
18 from mercurial import extensions, patch
19 from mercurial.commands import templateopts
19 from mercurial.commands import templateopts
20 from mercurial.node import nullrev
20 from mercurial.node import nullrev
21 from mercurial.lock import release
21 from mercurial.lock import release
22 from mercurial.i18n import _
22 from mercurial.i18n import _
23 import os, errno
23 import os, errno
24
24
25 nullmerge = -2
25 nullmerge = -2
26
26
27 cmdtable = {}
27 cmdtable = {}
28 command = cmdutil.command(cmdtable)
28 command = cmdutil.command(cmdtable)
29
29
30 @command('rebase',
30 @command('rebase',
31 [('s', 'source', '',
31 [('s', 'source', '',
32 _('rebase from the specified changeset'), _('REV')),
32 _('rebase from the specified changeset'), _('REV')),
33 ('b', 'base', '',
33 ('b', 'base', '',
34 _('rebase from the base of the specified changeset '
34 _('rebase from the base of the specified changeset '
35 '(up to greatest common ancestor of base and dest)'),
35 '(up to greatest common ancestor of base and dest)'),
36 _('REV')),
36 _('REV')),
37 ('r', 'rev', [],
37 ('r', 'rev', [],
38 _('rebase these revisions'),
38 _('rebase these revisions'),
39 _('REV')),
39 _('REV')),
40 ('d', 'dest', '',
40 ('d', 'dest', '',
41 _('rebase onto the specified changeset'), _('REV')),
41 _('rebase onto the specified changeset'), _('REV')),
42 ('', 'collapse', False, _('collapse the rebased changesets')),
42 ('', 'collapse', False, _('collapse the rebased changesets')),
43 ('m', 'message', '',
43 ('m', 'message', '',
44 _('use text as collapse commit message'), _('TEXT')),
44 _('use text as collapse commit message'), _('TEXT')),
45 ('e', 'edit', False, _('invoke editor on commit messages')),
45 ('e', 'edit', False, _('invoke editor on commit messages')),
46 ('l', 'logfile', '',
46 ('l', 'logfile', '',
47 _('read collapse commit message from file'), _('FILE')),
47 _('read collapse commit message from file'), _('FILE')),
48 ('', 'keep', False, _('keep original changesets')),
48 ('', 'keep', False, _('keep original changesets')),
49 ('', 'keepbranches', False, _('keep original branch names')),
49 ('', 'keepbranches', False, _('keep original branch names')),
50 ('D', 'detach', False, _('force detaching of source from its original '
50 ('D', 'detach', False, _('force detaching of source from its original '
51 'branch')),
51 'branch')),
52 ('t', 'tool', '', _('specify merge tool')),
52 ('t', 'tool', '', _('specify merge tool')),
53 ('c', 'continue', False, _('continue an interrupted rebase')),
53 ('c', 'continue', False, _('continue an interrupted rebase')),
54 ('a', 'abort', False, _('abort an interrupted rebase'))] +
54 ('a', 'abort', False, _('abort an interrupted rebase'))] +
55 templateopts,
55 templateopts,
56 _('hg rebase [-s REV | -b REV] [-d REV] [options]\n'
56 _('hg rebase [-s REV | -b REV] [-d REV] [options]\n'
57 'hg rebase {-a|-c}'))
57 'hg rebase {-a|-c}'))
58 def rebase(ui, repo, **opts):
58 def rebase(ui, repo, **opts):
59 """move changeset (and descendants) to a different branch
59 """move changeset (and descendants) to a different branch
60
60
61 Rebase uses repeated merging to graft changesets from one part of
61 Rebase uses repeated merging to graft changesets from one part of
62 history (the source) onto another (the destination). This can be
62 history (the source) onto another (the destination). This can be
63 useful for linearizing *local* changes relative to a master
63 useful for linearizing *local* changes relative to a master
64 development tree.
64 development tree.
65
65
66 You should not rebase changesets that have already been shared
66 You should not rebase changesets that have already been shared
67 with others. Doing so will force everybody else to perform the
67 with others. Doing so will force everybody else to perform the
68 same rebase or they will end up with duplicated changesets after
68 same rebase or they will end up with duplicated changesets after
69 pulling in your rebased changesets.
69 pulling in your rebased changesets.
70
70
71 If you don't specify a destination changeset (``-d/--dest``),
71 If you don't specify a destination changeset (``-d/--dest``),
72 rebase uses the tipmost head of the current named branch as the
72 rebase uses the tipmost head of the current named branch as the
73 destination. (The destination changeset is not modified by
73 destination. (The destination changeset is not modified by
74 rebasing, but new changesets are added as its descendants.)
74 rebasing, but new changesets are added as its descendants.)
75
75
76 You can specify which changesets to rebase in two ways: as a
76 You can specify which changesets to rebase in two ways: as a
77 "source" changeset or as a "base" changeset. Both are shorthand
77 "source" changeset or as a "base" changeset. Both are shorthand
78 for a topologically related set of changesets (the "source
78 for a topologically related set of changesets (the "source
79 branch"). If you specify source (``-s/--source``), rebase will
79 branch"). If you specify source (``-s/--source``), rebase will
80 rebase that changeset and all of its descendants onto dest. If you
80 rebase that changeset and all of its descendants onto dest. If you
81 specify base (``-b/--base``), rebase will select ancestors of base
81 specify base (``-b/--base``), rebase will select ancestors of base
82 back to but not including the common ancestor with dest. Thus,
82 back to but not including the common ancestor with dest. Thus,
83 ``-b`` is less precise but more convenient than ``-s``: you can
83 ``-b`` is less precise but more convenient than ``-s``: you can
84 specify any changeset in the source branch, and rebase will select
84 specify any changeset in the source branch, and rebase will select
85 the whole branch. If you specify neither ``-s`` nor ``-b``, rebase
85 the whole branch. If you specify neither ``-s`` nor ``-b``, rebase
86 uses the parent of the working directory as the base.
86 uses the parent of the working directory as the base.
87
87
88 By default, rebase recreates the changesets in the source branch
88 By default, rebase recreates the changesets in the source branch
89 as descendants of dest and then destroys the originals. Use
89 as descendants of dest and then destroys the originals. Use
90 ``--keep`` to preserve the original source changesets. Some
90 ``--keep`` to preserve the original source changesets. Some
91 changesets in the source branch (e.g. merges from the destination
91 changesets in the source branch (e.g. merges from the destination
92 branch) may be dropped if they no longer contribute any change.
92 branch) may be dropped if they no longer contribute any change.
93
93
94 One result of the rules for selecting the destination changeset
94 One result of the rules for selecting the destination changeset
95 and source branch is that, unlike ``merge``, rebase will do
95 and source branch is that, unlike ``merge``, rebase will do
96 nothing if you are at the latest (tipmost) head of a named branch
96 nothing if you are at the latest (tipmost) head of a named branch
97 with two heads. You need to explicitly specify source and/or
97 with two heads. You need to explicitly specify source and/or
98 destination (or ``update`` to the other head, if it's the head of
98 destination (or ``update`` to the other head, if it's the head of
99 the intended source branch).
99 the intended source branch).
100
100
101 If a rebase is interrupted to manually resolve a merge, it can be
101 If a rebase is interrupted to manually resolve a merge, it can be
102 continued with --continue/-c or aborted with --abort/-a.
102 continued with --continue/-c or aborted with --abort/-a.
103
103
104 Returns 0 on success, 1 if nothing to rebase.
104 Returns 0 on success, 1 if nothing to rebase.
105 """
105 """
106 originalwd = target = None
106 originalwd = target = None
107 external = nullrev
107 external = nullrev
108 state = {}
108 state = {}
109 skipped = set()
109 skipped = set()
110 targetancestors = set()
110 targetancestors = set()
111
111
112 editor = None
112 editor = None
113 if opts.get('edit'):
113 if opts.get('edit'):
114 editor = cmdutil.commitforceeditor
114 editor = cmdutil.commitforceeditor
115
115
116 lock = wlock = None
116 lock = wlock = None
117 try:
117 try:
118 lock = repo.lock()
118 lock = repo.lock()
119 wlock = repo.wlock()
119 wlock = repo.wlock()
120
120
121 # Validate input and define rebasing points
121 # Validate input and define rebasing points
122 destf = opts.get('dest', None)
122 destf = opts.get('dest', None)
123 srcf = opts.get('source', None)
123 srcf = opts.get('source', None)
124 basef = opts.get('base', None)
124 basef = opts.get('base', None)
125 revf = opts.get('rev', [])
125 revf = opts.get('rev', [])
126 contf = opts.get('continue')
126 contf = opts.get('continue')
127 abortf = opts.get('abort')
127 abortf = opts.get('abort')
128 collapsef = opts.get('collapse', False)
128 collapsef = opts.get('collapse', False)
129 collapsemsg = cmdutil.logmessage(ui, opts)
129 collapsemsg = cmdutil.logmessage(ui, opts)
130 extrafn = opts.get('extrafn') # internal, used by e.g. hgsubversion
130 extrafn = opts.get('extrafn') # internal, used by e.g. hgsubversion
131 keepf = opts.get('keep', False)
131 keepf = opts.get('keep', False)
132 keepbranchesf = opts.get('keepbranches', False)
132 keepbranchesf = opts.get('keepbranches', False)
133 detachf = opts.get('detach', False)
133 detachf = opts.get('detach', False)
134 # keepopen is not meant for use on the command line, but by
134 # keepopen is not meant for use on the command line, but by
135 # other extensions
135 # other extensions
136 keepopen = opts.get('keepopen', False)
136 keepopen = opts.get('keepopen', False)
137
137
138 if collapsemsg and not collapsef:
138 if collapsemsg and not collapsef:
139 raise util.Abort(
139 raise util.Abort(
140 _('message can only be specified with collapse'))
140 _('message can only be specified with collapse'))
141
141
142 if contf or abortf:
142 if contf or abortf:
143 if contf and abortf:
143 if contf and abortf:
144 raise util.Abort(_('cannot use both abort and continue'))
144 raise util.Abort(_('cannot use both abort and continue'))
145 if collapsef:
145 if collapsef:
146 raise util.Abort(
146 raise util.Abort(
147 _('cannot use collapse with continue or abort'))
147 _('cannot use collapse with continue or abort'))
148 if detachf:
148 if detachf:
149 raise util.Abort(_('cannot use detach with continue or abort'))
149 raise util.Abort(_('cannot use detach with continue or abort'))
150 if srcf or basef or destf:
150 if srcf or basef or destf:
151 raise util.Abort(
151 raise util.Abort(
152 _('abort and continue do not allow specifying revisions'))
152 _('abort and continue do not allow specifying revisions'))
153 if opts.get('tool', False):
153 if opts.get('tool', False):
154 ui.warn(_('tool option will be ignored\n'))
154 ui.warn(_('tool option will be ignored\n'))
155
155
156 (originalwd, target, state, skipped, collapsef, keepf,
156 (originalwd, target, state, skipped, collapsef, keepf,
157 keepbranchesf, external) = restorestatus(repo)
157 keepbranchesf, external) = restorestatus(repo)
158 if abortf:
158 if abortf:
159 return abort(repo, originalwd, target, state)
159 return abort(repo, originalwd, target, state)
160 else:
160 else:
161 if srcf and basef:
161 if srcf and basef:
162 raise util.Abort(_('cannot specify both a '
162 raise util.Abort(_('cannot specify both a '
163 'source and a base'))
163 'source and a base'))
164 if revf and basef:
164 if revf and basef:
165 raise util.Abort(_('cannot specify both a '
165 raise util.Abort(_('cannot specify both a '
166 'revision and a base'))
166 'revision and a base'))
167 if revf and srcf:
167 if revf and srcf:
168 raise util.Abort(_('cannot specify both a '
168 raise util.Abort(_('cannot specify both a '
169 'revision and a source'))
169 'revision and a source'))
170 if detachf:
170 if detachf:
171 if not (srcf or revf):
171 if not (srcf or revf):
172 raise util.Abort(
172 raise util.Abort(
173 _('detach requires a revision to be specified'))
173 _('detach requires a revision to be specified'))
174 if basef:
174 if basef:
175 raise util.Abort(_('cannot specify a base with detach'))
175 raise util.Abort(_('cannot specify a base with detach'))
176
176
177 cmdutil.bailifchanged(repo)
177 cmdutil.bailifchanged(repo)
178
178
179 if not destf:
179 if not destf:
180 # Destination defaults to the latest revision in the
180 # Destination defaults to the latest revision in the
181 # current branch
181 # current branch
182 branch = repo[None].branch()
182 branch = repo[None].branch()
183 dest = repo[branch]
183 dest = repo[branch]
184 else:
184 else:
185 dest = repo[destf]
185 dest = repo[destf]
186
186
187 if revf:
187 if revf:
188 rebaseset = repo.revs('%lr', revf)
188 rebaseset = repo.revs('%lr', revf)
189 elif srcf:
189 elif srcf:
190 rebaseset = repo.revs('(%r)::', srcf)
190 rebaseset = repo.revs('(%r)::', srcf)
191 else:
191 else:
192 base = basef or '.'
192 base = basef or '.'
193 rebaseset = repo.revs('(children(ancestor(%r, %d)) & ::%r)::',
193 rebaseset = repo.revs('(children(ancestor(%r, %d)) & ::%r)::',
194 base, dest, base)
194 base, dest, base)
195
195
196 if rebaseset:
197 root = min(rebaseset)
198 else:
199 root = None
200
196 if not rebaseset:
201 if not rebaseset:
197 repo.ui.debug('base is ancestor of destination')
202 repo.ui.debug('base is ancestor of destination')
198 result = None
203 result = None
199 elif not keepf and list(repo.revs('first(children(%ld) - %ld)',
204 elif not keepf and list(repo.revs('first(children(%ld) - %ld)',
200 rebaseset, rebaseset)):
205 rebaseset, rebaseset)):
201 raise util.Abort(
206 raise util.Abort(
202 _("can't remove original changesets with"
207 _("can't remove original changesets with"
203 " unrebased descendants"),
208 " unrebased descendants"),
204 hint=_('use --keep to keep original changesets'))
209 hint=_('use --keep to keep original changesets'))
210 elif not keepf and not repo[root].mutable():
211 raise util.Abort(_("Can't rebase immutable changeset %s")
212 % repo[root],
213 hint=_('see hg help phases for details'))
205 else:
214 else:
206 result = buildstate(repo, dest, rebaseset, detachf)
215 result = buildstate(repo, dest, rebaseset, detachf)
207
216
208 if not result:
217 if not result:
209 # Empty state built, nothing to rebase
218 # Empty state built, nothing to rebase
210 ui.status(_('nothing to rebase\n'))
219 ui.status(_('nothing to rebase\n'))
211 return 1
220 return 1
212 else:
221 else:
213 originalwd, target, state = result
222 originalwd, target, state = result
214 if collapsef:
223 if collapsef:
215 targetancestors = set(repo.changelog.ancestors(target))
224 targetancestors = set(repo.changelog.ancestors(target))
216 targetancestors.add(target)
225 targetancestors.add(target)
217 external = checkexternal(repo, state, targetancestors)
226 external = checkexternal(repo, state, targetancestors)
218
227
219 if keepbranchesf:
228 if keepbranchesf:
220 assert not extrafn, 'cannot use both keepbranches and extrafn'
229 assert not extrafn, 'cannot use both keepbranches and extrafn'
221 def extrafn(ctx, extra):
230 def extrafn(ctx, extra):
222 extra['branch'] = ctx.branch()
231 extra['branch'] = ctx.branch()
223 if collapsef:
232 if collapsef:
224 branches = set()
233 branches = set()
225 for rev in state:
234 for rev in state:
226 branches.add(repo[rev].branch())
235 branches.add(repo[rev].branch())
227 if len(branches) > 1:
236 if len(branches) > 1:
228 raise util.Abort(_('cannot collapse multiple named '
237 raise util.Abort(_('cannot collapse multiple named '
229 'branches'))
238 'branches'))
230
239
231
240
232 # Rebase
241 # Rebase
233 if not targetancestors:
242 if not targetancestors:
234 targetancestors = set(repo.changelog.ancestors(target))
243 targetancestors = set(repo.changelog.ancestors(target))
235 targetancestors.add(target)
244 targetancestors.add(target)
236
245
237 # Keep track of the current bookmarks in order to reset them later
246 # Keep track of the current bookmarks in order to reset them later
238 currentbookmarks = repo._bookmarks.copy()
247 currentbookmarks = repo._bookmarks.copy()
239
248
240 sortedstate = sorted(state)
249 sortedstate = sorted(state)
241 total = len(sortedstate)
250 total = len(sortedstate)
242 pos = 0
251 pos = 0
243 for rev in sortedstate:
252 for rev in sortedstate:
244 pos += 1
253 pos += 1
245 if state[rev] == -1:
254 if state[rev] == -1:
246 ui.progress(_("rebasing"), pos, ("%d:%s" % (rev, repo[rev])),
255 ui.progress(_("rebasing"), pos, ("%d:%s" % (rev, repo[rev])),
247 _('changesets'), total)
256 _('changesets'), total)
248 storestatus(repo, originalwd, target, state, collapsef, keepf,
257 storestatus(repo, originalwd, target, state, collapsef, keepf,
249 keepbranchesf, external)
258 keepbranchesf, external)
250 p1, p2 = defineparents(repo, rev, target, state,
259 p1, p2 = defineparents(repo, rev, target, state,
251 targetancestors)
260 targetancestors)
252 if len(repo.parents()) == 2:
261 if len(repo.parents()) == 2:
253 repo.ui.debug('resuming interrupted rebase\n')
262 repo.ui.debug('resuming interrupted rebase\n')
254 else:
263 else:
255 try:
264 try:
256 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
265 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
257 stats = rebasenode(repo, rev, p1, state)
266 stats = rebasenode(repo, rev, p1, state)
258 if stats and stats[3] > 0:
267 if stats and stats[3] > 0:
259 raise util.Abort(_('unresolved conflicts (see hg '
268 raise util.Abort(_('unresolved conflicts (see hg '
260 'resolve, then hg rebase --continue)'))
269 'resolve, then hg rebase --continue)'))
261 finally:
270 finally:
262 ui.setconfig('ui', 'forcemerge', '')
271 ui.setconfig('ui', 'forcemerge', '')
263 cmdutil.duplicatecopies(repo, rev, target, p2)
272 cmdutil.duplicatecopies(repo, rev, target, p2)
264 if not collapsef:
273 if not collapsef:
265 newrev = concludenode(repo, rev, p1, p2, extrafn=extrafn,
274 newrev = concludenode(repo, rev, p1, p2, extrafn=extrafn,
266 editor=editor)
275 editor=editor)
267 else:
276 else:
268 # Skip commit if we are collapsing
277 # Skip commit if we are collapsing
269 repo.dirstate.setparents(repo[p1].node())
278 repo.dirstate.setparents(repo[p1].node())
270 newrev = None
279 newrev = None
271 # Update the state
280 # Update the state
272 if newrev is not None:
281 if newrev is not None:
273 state[rev] = repo[newrev].rev()
282 state[rev] = repo[newrev].rev()
274 else:
283 else:
275 if not collapsef:
284 if not collapsef:
276 ui.note(_('no changes, revision %d skipped\n') % rev)
285 ui.note(_('no changes, revision %d skipped\n') % rev)
277 ui.debug('next revision set to %s\n' % p1)
286 ui.debug('next revision set to %s\n' % p1)
278 skipped.add(rev)
287 skipped.add(rev)
279 state[rev] = p1
288 state[rev] = p1
280
289
281 ui.progress(_('rebasing'), None)
290 ui.progress(_('rebasing'), None)
282 ui.note(_('rebase merging completed\n'))
291 ui.note(_('rebase merging completed\n'))
283
292
284 if collapsef and not keepopen:
293 if collapsef and not keepopen:
285 p1, p2 = defineparents(repo, min(state), target,
294 p1, p2 = defineparents(repo, min(state), target,
286 state, targetancestors)
295 state, targetancestors)
287 if collapsemsg:
296 if collapsemsg:
288 commitmsg = collapsemsg
297 commitmsg = collapsemsg
289 else:
298 else:
290 commitmsg = 'Collapsed revision'
299 commitmsg = 'Collapsed revision'
291 for rebased in state:
300 for rebased in state:
292 if rebased not in skipped and state[rebased] != nullmerge:
301 if rebased not in skipped and state[rebased] != nullmerge:
293 commitmsg += '\n* %s' % repo[rebased].description()
302 commitmsg += '\n* %s' % repo[rebased].description()
294 commitmsg = ui.edit(commitmsg, repo.ui.username())
303 commitmsg = ui.edit(commitmsg, repo.ui.username())
295 newrev = concludenode(repo, rev, p1, external, commitmsg=commitmsg,
304 newrev = concludenode(repo, rev, p1, external, commitmsg=commitmsg,
296 extrafn=extrafn, editor=editor)
305 extrafn=extrafn, editor=editor)
297
306
298 if 'qtip' in repo.tags():
307 if 'qtip' in repo.tags():
299 updatemq(repo, state, skipped, **opts)
308 updatemq(repo, state, skipped, **opts)
300
309
301 if currentbookmarks:
310 if currentbookmarks:
302 # Nodeids are needed to reset bookmarks
311 # Nodeids are needed to reset bookmarks
303 nstate = {}
312 nstate = {}
304 for k, v in state.iteritems():
313 for k, v in state.iteritems():
305 if v != nullmerge:
314 if v != nullmerge:
306 nstate[repo[k].node()] = repo[v].node()
315 nstate[repo[k].node()] = repo[v].node()
307
316
308 if not keepf:
317 if not keepf:
309 # Remove no more useful revisions
318 # Remove no more useful revisions
310 rebased = [rev for rev in state if state[rev] != nullmerge]
319 rebased = [rev for rev in state if state[rev] != nullmerge]
311 if rebased:
320 if rebased:
312 if set(repo.changelog.descendants(min(rebased))) - set(state):
321 if set(repo.changelog.descendants(min(rebased))) - set(state):
313 ui.warn(_("warning: new changesets detected "
322 ui.warn(_("warning: new changesets detected "
314 "on source branch, not stripping\n"))
323 "on source branch, not stripping\n"))
315 else:
324 else:
316 # backup the old csets by default
325 # backup the old csets by default
317 repair.strip(ui, repo, repo[min(rebased)].node(), "all")
326 repair.strip(ui, repo, repo[min(rebased)].node(), "all")
318
327
319 if currentbookmarks:
328 if currentbookmarks:
320 updatebookmarks(repo, nstate, currentbookmarks, **opts)
329 updatebookmarks(repo, nstate, currentbookmarks, **opts)
321
330
322 clearstatus(repo)
331 clearstatus(repo)
323 ui.note(_("rebase completed\n"))
332 ui.note(_("rebase completed\n"))
324 if os.path.exists(repo.sjoin('undo')):
333 if os.path.exists(repo.sjoin('undo')):
325 util.unlinkpath(repo.sjoin('undo'))
334 util.unlinkpath(repo.sjoin('undo'))
326 if skipped:
335 if skipped:
327 ui.note(_("%d revisions have been skipped\n") % len(skipped))
336 ui.note(_("%d revisions have been skipped\n") % len(skipped))
328 finally:
337 finally:
329 release(lock, wlock)
338 release(lock, wlock)
330
339
331 def checkexternal(repo, state, targetancestors):
340 def checkexternal(repo, state, targetancestors):
332 """Check whether one or more external revisions need to be taken in
341 """Check whether one or more external revisions need to be taken in
333 consideration. In the latter case, abort.
342 consideration. In the latter case, abort.
334 """
343 """
335 external = nullrev
344 external = nullrev
336 source = min(state)
345 source = min(state)
337 for rev in state:
346 for rev in state:
338 if rev == source:
347 if rev == source:
339 continue
348 continue
340 # Check externals and fail if there are more than one
349 # Check externals and fail if there are more than one
341 for p in repo[rev].parents():
350 for p in repo[rev].parents():
342 if (p.rev() not in state
351 if (p.rev() not in state
343 and p.rev() not in targetancestors):
352 and p.rev() not in targetancestors):
344 if external != nullrev:
353 if external != nullrev:
345 raise util.Abort(_('unable to collapse, there is more '
354 raise util.Abort(_('unable to collapse, there is more '
346 'than one external parent'))
355 'than one external parent'))
347 external = p.rev()
356 external = p.rev()
348 return external
357 return external
349
358
350 def concludenode(repo, rev, p1, p2, commitmsg=None, editor=None, extrafn=None):
359 def concludenode(repo, rev, p1, p2, commitmsg=None, editor=None, extrafn=None):
351 'Commit the changes and store useful information in extra'
360 'Commit the changes and store useful information in extra'
352 try:
361 try:
353 repo.dirstate.setparents(repo[p1].node(), repo[p2].node())
362 repo.dirstate.setparents(repo[p1].node(), repo[p2].node())
354 ctx = repo[rev]
363 ctx = repo[rev]
355 if commitmsg is None:
364 if commitmsg is None:
356 commitmsg = ctx.description()
365 commitmsg = ctx.description()
357 extra = {'rebase_source': ctx.hex()}
366 extra = {'rebase_source': ctx.hex()}
358 if extrafn:
367 if extrafn:
359 extrafn(ctx, extra)
368 extrafn(ctx, extra)
360 # Commit might fail if unresolved files exist
369 # Commit might fail if unresolved files exist
361 newrev = repo.commit(text=commitmsg, user=ctx.user(),
370 newrev = repo.commit(text=commitmsg, user=ctx.user(),
362 date=ctx.date(), extra=extra, editor=editor)
371 date=ctx.date(), extra=extra, editor=editor)
363 repo.dirstate.setbranch(repo[newrev].branch())
372 repo.dirstate.setbranch(repo[newrev].branch())
364 return newrev
373 return newrev
365 except util.Abort:
374 except util.Abort:
366 # Invalidate the previous setparents
375 # Invalidate the previous setparents
367 repo.dirstate.invalidate()
376 repo.dirstate.invalidate()
368 raise
377 raise
369
378
370 def rebasenode(repo, rev, p1, state):
379 def rebasenode(repo, rev, p1, state):
371 'Rebase a single revision'
380 'Rebase a single revision'
372 # Merge phase
381 # Merge phase
373 # Update to target and merge it with local
382 # Update to target and merge it with local
374 if repo['.'].rev() != repo[p1].rev():
383 if repo['.'].rev() != repo[p1].rev():
375 repo.ui.debug(" update to %d:%s\n" % (repo[p1].rev(), repo[p1]))
384 repo.ui.debug(" update to %d:%s\n" % (repo[p1].rev(), repo[p1]))
376 merge.update(repo, p1, False, True, False)
385 merge.update(repo, p1, False, True, False)
377 else:
386 else:
378 repo.ui.debug(" already in target\n")
387 repo.ui.debug(" already in target\n")
379 repo.dirstate.write()
388 repo.dirstate.write()
380 repo.ui.debug(" merge against %d:%s\n" % (repo[rev].rev(), repo[rev]))
389 repo.ui.debug(" merge against %d:%s\n" % (repo[rev].rev(), repo[rev]))
381 base = None
390 base = None
382 if repo[rev].rev() != repo[min(state)].rev():
391 if repo[rev].rev() != repo[min(state)].rev():
383 base = repo[rev].p1().node()
392 base = repo[rev].p1().node()
384 return merge.update(repo, rev, True, True, False, base)
393 return merge.update(repo, rev, True, True, False, base)
385
394
386 def defineparents(repo, rev, target, state, targetancestors):
395 def defineparents(repo, rev, target, state, targetancestors):
387 'Return the new parent relationship of the revision that will be rebased'
396 'Return the new parent relationship of the revision that will be rebased'
388 parents = repo[rev].parents()
397 parents = repo[rev].parents()
389 p1 = p2 = nullrev
398 p1 = p2 = nullrev
390
399
391 P1n = parents[0].rev()
400 P1n = parents[0].rev()
392 if P1n in targetancestors:
401 if P1n in targetancestors:
393 p1 = target
402 p1 = target
394 elif P1n in state:
403 elif P1n in state:
395 if state[P1n] == nullmerge:
404 if state[P1n] == nullmerge:
396 p1 = target
405 p1 = target
397 else:
406 else:
398 p1 = state[P1n]
407 p1 = state[P1n]
399 else: # P1n external
408 else: # P1n external
400 p1 = target
409 p1 = target
401 p2 = P1n
410 p2 = P1n
402
411
403 if len(parents) == 2 and parents[1].rev() not in targetancestors:
412 if len(parents) == 2 and parents[1].rev() not in targetancestors:
404 P2n = parents[1].rev()
413 P2n = parents[1].rev()
405 # interesting second parent
414 # interesting second parent
406 if P2n in state:
415 if P2n in state:
407 if p1 == target: # P1n in targetancestors or external
416 if p1 == target: # P1n in targetancestors or external
408 p1 = state[P2n]
417 p1 = state[P2n]
409 else:
418 else:
410 p2 = state[P2n]
419 p2 = state[P2n]
411 else: # P2n external
420 else: # P2n external
412 if p2 != nullrev: # P1n external too => rev is a merged revision
421 if p2 != nullrev: # P1n external too => rev is a merged revision
413 raise util.Abort(_('cannot use revision %d as base, result '
422 raise util.Abort(_('cannot use revision %d as base, result '
414 'would have 3 parents') % rev)
423 'would have 3 parents') % rev)
415 p2 = P2n
424 p2 = P2n
416 repo.ui.debug(" future parents are %d and %d\n" %
425 repo.ui.debug(" future parents are %d and %d\n" %
417 (repo[p1].rev(), repo[p2].rev()))
426 (repo[p1].rev(), repo[p2].rev()))
418 return p1, p2
427 return p1, p2
419
428
420 def isagitpatch(repo, patchname):
429 def isagitpatch(repo, patchname):
421 'Return true if the given patch is in git format'
430 'Return true if the given patch is in git format'
422 mqpatch = os.path.join(repo.mq.path, patchname)
431 mqpatch = os.path.join(repo.mq.path, patchname)
423 for line in patch.linereader(file(mqpatch, 'rb')):
432 for line in patch.linereader(file(mqpatch, 'rb')):
424 if line.startswith('diff --git'):
433 if line.startswith('diff --git'):
425 return True
434 return True
426 return False
435 return False
427
436
428 def updatemq(repo, state, skipped, **opts):
437 def updatemq(repo, state, skipped, **opts):
429 'Update rebased mq patches - finalize and then import them'
438 'Update rebased mq patches - finalize and then import them'
430 mqrebase = {}
439 mqrebase = {}
431 mq = repo.mq
440 mq = repo.mq
432 original_series = mq.fullseries[:]
441 original_series = mq.fullseries[:]
433
442
434 for p in mq.applied:
443 for p in mq.applied:
435 rev = repo[p.node].rev()
444 rev = repo[p.node].rev()
436 if rev in state:
445 if rev in state:
437 repo.ui.debug('revision %d is an mq patch (%s), finalize it.\n' %
446 repo.ui.debug('revision %d is an mq patch (%s), finalize it.\n' %
438 (rev, p.name))
447 (rev, p.name))
439 mqrebase[rev] = (p.name, isagitpatch(repo, p.name))
448 mqrebase[rev] = (p.name, isagitpatch(repo, p.name))
440
449
441 if mqrebase:
450 if mqrebase:
442 mq.finish(repo, mqrebase.keys())
451 mq.finish(repo, mqrebase.keys())
443
452
444 # We must start import from the newest revision
453 # We must start import from the newest revision
445 for rev in sorted(mqrebase, reverse=True):
454 for rev in sorted(mqrebase, reverse=True):
446 if rev not in skipped:
455 if rev not in skipped:
447 name, isgit = mqrebase[rev]
456 name, isgit = mqrebase[rev]
448 repo.ui.debug('import mq patch %d (%s)\n' % (state[rev], name))
457 repo.ui.debug('import mq patch %d (%s)\n' % (state[rev], name))
449 mq.qimport(repo, (), patchname=name, git=isgit,
458 mq.qimport(repo, (), patchname=name, git=isgit,
450 rev=[str(state[rev])])
459 rev=[str(state[rev])])
451
460
452 # restore old series to preserve guards
461 # restore old series to preserve guards
453 mq.fullseries = original_series
462 mq.fullseries = original_series
454 mq.series_dirty = True
463 mq.series_dirty = True
455 mq.savedirty()
464 mq.savedirty()
456
465
457 def updatebookmarks(repo, nstate, originalbookmarks, **opts):
466 def updatebookmarks(repo, nstate, originalbookmarks, **opts):
458 'Move bookmarks to their correct changesets'
467 'Move bookmarks to their correct changesets'
459 current = repo._bookmarkcurrent
468 current = repo._bookmarkcurrent
460 for k, v in originalbookmarks.iteritems():
469 for k, v in originalbookmarks.iteritems():
461 if v in nstate:
470 if v in nstate:
462 if nstate[v] != nullmerge:
471 if nstate[v] != nullmerge:
463 # reset the pointer if the bookmark was moved incorrectly
472 # reset the pointer if the bookmark was moved incorrectly
464 if k != current:
473 if k != current:
465 repo._bookmarks[k] = nstate[v]
474 repo._bookmarks[k] = nstate[v]
466
475
467 bookmarks.write(repo)
476 bookmarks.write(repo)
468
477
469 def storestatus(repo, originalwd, target, state, collapse, keep, keepbranches,
478 def storestatus(repo, originalwd, target, state, collapse, keep, keepbranches,
470 external):
479 external):
471 'Store the current status to allow recovery'
480 'Store the current status to allow recovery'
472 f = repo.opener("rebasestate", "w")
481 f = repo.opener("rebasestate", "w")
473 f.write(repo[originalwd].hex() + '\n')
482 f.write(repo[originalwd].hex() + '\n')
474 f.write(repo[target].hex() + '\n')
483 f.write(repo[target].hex() + '\n')
475 f.write(repo[external].hex() + '\n')
484 f.write(repo[external].hex() + '\n')
476 f.write('%d\n' % int(collapse))
485 f.write('%d\n' % int(collapse))
477 f.write('%d\n' % int(keep))
486 f.write('%d\n' % int(keep))
478 f.write('%d\n' % int(keepbranches))
487 f.write('%d\n' % int(keepbranches))
479 for d, v in state.iteritems():
488 for d, v in state.iteritems():
480 oldrev = repo[d].hex()
489 oldrev = repo[d].hex()
481 if v != nullmerge:
490 if v != nullmerge:
482 newrev = repo[v].hex()
491 newrev = repo[v].hex()
483 else:
492 else:
484 newrev = v
493 newrev = v
485 f.write("%s:%s\n" % (oldrev, newrev))
494 f.write("%s:%s\n" % (oldrev, newrev))
486 f.close()
495 f.close()
487 repo.ui.debug('rebase status stored\n')
496 repo.ui.debug('rebase status stored\n')
488
497
489 def clearstatus(repo):
498 def clearstatus(repo):
490 'Remove the status files'
499 'Remove the status files'
491 if os.path.exists(repo.join("rebasestate")):
500 if os.path.exists(repo.join("rebasestate")):
492 util.unlinkpath(repo.join("rebasestate"))
501 util.unlinkpath(repo.join("rebasestate"))
493
502
494 def restorestatus(repo):
503 def restorestatus(repo):
495 'Restore a previously stored status'
504 'Restore a previously stored status'
496 try:
505 try:
497 target = None
506 target = None
498 collapse = False
507 collapse = False
499 external = nullrev
508 external = nullrev
500 state = {}
509 state = {}
501 f = repo.opener("rebasestate")
510 f = repo.opener("rebasestate")
502 for i, l in enumerate(f.read().splitlines()):
511 for i, l in enumerate(f.read().splitlines()):
503 if i == 0:
512 if i == 0:
504 originalwd = repo[l].rev()
513 originalwd = repo[l].rev()
505 elif i == 1:
514 elif i == 1:
506 target = repo[l].rev()
515 target = repo[l].rev()
507 elif i == 2:
516 elif i == 2:
508 external = repo[l].rev()
517 external = repo[l].rev()
509 elif i == 3:
518 elif i == 3:
510 collapse = bool(int(l))
519 collapse = bool(int(l))
511 elif i == 4:
520 elif i == 4:
512 keep = bool(int(l))
521 keep = bool(int(l))
513 elif i == 5:
522 elif i == 5:
514 keepbranches = bool(int(l))
523 keepbranches = bool(int(l))
515 else:
524 else:
516 oldrev, newrev = l.split(':')
525 oldrev, newrev = l.split(':')
517 if newrev != str(nullmerge):
526 if newrev != str(nullmerge):
518 state[repo[oldrev].rev()] = repo[newrev].rev()
527 state[repo[oldrev].rev()] = repo[newrev].rev()
519 else:
528 else:
520 state[repo[oldrev].rev()] = int(newrev)
529 state[repo[oldrev].rev()] = int(newrev)
521 skipped = set()
530 skipped = set()
522 # recompute the set of skipped revs
531 # recompute the set of skipped revs
523 if not collapse:
532 if not collapse:
524 seen = set([target])
533 seen = set([target])
525 for old, new in sorted(state.items()):
534 for old, new in sorted(state.items()):
526 if new != nullrev and new in seen:
535 if new != nullrev and new in seen:
527 skipped.add(old)
536 skipped.add(old)
528 seen.add(new)
537 seen.add(new)
529 repo.ui.debug('computed skipped revs: %s\n' % skipped)
538 repo.ui.debug('computed skipped revs: %s\n' % skipped)
530 repo.ui.debug('rebase status resumed\n')
539 repo.ui.debug('rebase status resumed\n')
531 return (originalwd, target, state, skipped,
540 return (originalwd, target, state, skipped,
532 collapse, keep, keepbranches, external)
541 collapse, keep, keepbranches, external)
533 except IOError, err:
542 except IOError, err:
534 if err.errno != errno.ENOENT:
543 if err.errno != errno.ENOENT:
535 raise
544 raise
536 raise util.Abort(_('no rebase in progress'))
545 raise util.Abort(_('no rebase in progress'))
537
546
538 def abort(repo, originalwd, target, state):
547 def abort(repo, originalwd, target, state):
539 'Restore the repository to its original state'
548 'Restore the repository to its original state'
540 if set(repo.changelog.descendants(target)) - set(state.values()):
549 if set(repo.changelog.descendants(target)) - set(state.values()):
541 repo.ui.warn(_("warning: new changesets detected on target branch, "
550 repo.ui.warn(_("warning: new changesets detected on target branch, "
542 "can't abort\n"))
551 "can't abort\n"))
543 return -1
552 return -1
544 else:
553 else:
545 # Strip from the first rebased revision
554 # Strip from the first rebased revision
546 merge.update(repo, repo[originalwd].rev(), False, True, False)
555 merge.update(repo, repo[originalwd].rev(), False, True, False)
547 rebased = filter(lambda x: x > -1 and x != target, state.values())
556 rebased = filter(lambda x: x > -1 and x != target, state.values())
548 if rebased:
557 if rebased:
549 strippoint = min(rebased)
558 strippoint = min(rebased)
550 # no backup of rebased cset versions needed
559 # no backup of rebased cset versions needed
551 repair.strip(repo.ui, repo, repo[strippoint].node())
560 repair.strip(repo.ui, repo, repo[strippoint].node())
552 clearstatus(repo)
561 clearstatus(repo)
553 repo.ui.warn(_('rebase aborted\n'))
562 repo.ui.warn(_('rebase aborted\n'))
554 return 0
563 return 0
555
564
556 def buildstate(repo, dest, rebaseset, detach):
565 def buildstate(repo, dest, rebaseset, detach):
557 '''Define which revisions are going to be rebased and where
566 '''Define which revisions are going to be rebased and where
558
567
559 repo: repo
568 repo: repo
560 dest: context
569 dest: context
561 rebaseset: set of rev
570 rebaseset: set of rev
562 detach: boolean'''
571 detach: boolean'''
563
572
564 # This check isn't strictly necessary, since mq detects commits over an
573 # This check isn't strictly necessary, since mq detects commits over an
565 # applied patch. But it prevents messing up the working directory when
574 # applied patch. But it prevents messing up the working directory when
566 # a partially completed rebase is blocked by mq.
575 # a partially completed rebase is blocked by mq.
567 if 'qtip' in repo.tags() and (dest.node() in
576 if 'qtip' in repo.tags() and (dest.node() in
568 [s.node for s in repo.mq.applied]):
577 [s.node for s in repo.mq.applied]):
569 raise util.Abort(_('cannot rebase onto an applied mq patch'))
578 raise util.Abort(_('cannot rebase onto an applied mq patch'))
570
579
571 detachset = set()
580 detachset = set()
572 roots = list(repo.set('roots(%ld)', rebaseset))
581 roots = list(repo.set('roots(%ld)', rebaseset))
573 if not roots:
582 if not roots:
574 raise util.Abort(_('no matching revisions'))
583 raise util.Abort(_('no matching revisions'))
575 if len(roots) > 1:
584 if len(roots) > 1:
576 raise util.Abort(_("can't rebase multiple roots"))
585 raise util.Abort(_("can't rebase multiple roots"))
577 root = roots[0]
586 root = roots[0]
578
587
579 commonbase = root.ancestor(dest)
588 commonbase = root.ancestor(dest)
580 if commonbase == root:
589 if commonbase == root:
581 raise util.Abort(_('source is ancestor of destination'))
590 raise util.Abort(_('source is ancestor of destination'))
582 if commonbase == dest:
591 if commonbase == dest:
583 samebranch = root.branch() == dest.branch()
592 samebranch = root.branch() == dest.branch()
584 if samebranch and root in dest.children():
593 if samebranch and root in dest.children():
585 repo.ui.debug('source is a child of destination')
594 repo.ui.debug('source is a child of destination')
586 return None
595 return None
587 # rebase on ancestor, force detach
596 # rebase on ancestor, force detach
588 detach = True
597 detach = True
589 if detach:
598 if detach:
590 detachset = repo.revs('::%d - ::%d - %d', root, commonbase, root)
599 detachset = repo.revs('::%d - ::%d - %d', root, commonbase, root)
591
600
592 repo.ui.debug('rebase onto %d starting from %d\n' % (dest, root))
601 repo.ui.debug('rebase onto %d starting from %d\n' % (dest, root))
593 state = dict.fromkeys(rebaseset, nullrev)
602 state = dict.fromkeys(rebaseset, nullrev)
594 state.update(dict.fromkeys(detachset, nullmerge))
603 state.update(dict.fromkeys(detachset, nullmerge))
595 return repo['.'].rev(), dest.rev(), state
604 return repo['.'].rev(), dest.rev(), state
596
605
597 def pullrebase(orig, ui, repo, *args, **opts):
606 def pullrebase(orig, ui, repo, *args, **opts):
598 'Call rebase after pull if the latter has been invoked with --rebase'
607 'Call rebase after pull if the latter has been invoked with --rebase'
599 if opts.get('rebase'):
608 if opts.get('rebase'):
600 if opts.get('update'):
609 if opts.get('update'):
601 del opts['update']
610 del opts['update']
602 ui.debug('--update and --rebase are not compatible, ignoring '
611 ui.debug('--update and --rebase are not compatible, ignoring '
603 'the update flag\n')
612 'the update flag\n')
604
613
605 cmdutil.bailifchanged(repo)
614 cmdutil.bailifchanged(repo)
606 revsprepull = len(repo)
615 revsprepull = len(repo)
607 origpostincoming = commands.postincoming
616 origpostincoming = commands.postincoming
608 def _dummy(*args, **kwargs):
617 def _dummy(*args, **kwargs):
609 pass
618 pass
610 commands.postincoming = _dummy
619 commands.postincoming = _dummy
611 try:
620 try:
612 orig(ui, repo, *args, **opts)
621 orig(ui, repo, *args, **opts)
613 finally:
622 finally:
614 commands.postincoming = origpostincoming
623 commands.postincoming = origpostincoming
615 revspostpull = len(repo)
624 revspostpull = len(repo)
616 if revspostpull > revsprepull:
625 if revspostpull > revsprepull:
617 rebase(ui, repo, **opts)
626 rebase(ui, repo, **opts)
618 branch = repo[None].branch()
627 branch = repo[None].branch()
619 dest = repo[branch].rev()
628 dest = repo[branch].rev()
620 if dest != repo['.'].rev():
629 if dest != repo['.'].rev():
621 # there was nothing to rebase we force an update
630 # there was nothing to rebase we force an update
622 hg.update(repo, dest)
631 hg.update(repo, dest)
623 else:
632 else:
624 if opts.get('tool'):
633 if opts.get('tool'):
625 raise util.Abort(_('--tool can only be used with --rebase'))
634 raise util.Abort(_('--tool can only be used with --rebase'))
626 orig(ui, repo, *args, **opts)
635 orig(ui, repo, *args, **opts)
627
636
628 def uisetup(ui):
637 def uisetup(ui):
629 'Replace pull with a decorator to provide --rebase option'
638 'Replace pull with a decorator to provide --rebase option'
630 entry = extensions.wrapcommand(commands.table, 'pull', pullrebase)
639 entry = extensions.wrapcommand(commands.table, 'pull', pullrebase)
631 entry[1].append(('', 'rebase', None,
640 entry[1].append(('', 'rebase', None,
632 _("rebase working directory to branch head")))
641 _("rebase working directory to branch head")))
633 entry[1].append(('t', 'tool', '',
642 entry[1].append(('t', 'tool', '',
634 _("specify merge tool for rebase")))
643 _("specify merge tool for rebase")))
@@ -1,427 +1,427 b''
1 # store.py - repository store handling for Mercurial
1 # store.py - repository store handling 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 i18n import _
8 from i18n import _
9 import osutil, scmutil, util
9 import osutil, scmutil, util
10 import os, stat
10 import os, stat
11
11
12 _sha = util.sha1
12 _sha = util.sha1
13
13
14 # This avoids a collision between a file named foo and a dir named
14 # This avoids a collision between a file named foo and a dir named
15 # foo.i or foo.d
15 # foo.i or foo.d
16 def encodedir(path):
16 def encodedir(path):
17 '''
17 '''
18 >>> encodedir('data/foo.i')
18 >>> encodedir('data/foo.i')
19 'data/foo.i'
19 'data/foo.i'
20 >>> encodedir('data/foo.i/bla.i')
20 >>> encodedir('data/foo.i/bla.i')
21 'data/foo.i.hg/bla.i'
21 'data/foo.i.hg/bla.i'
22 >>> encodedir('data/foo.i.hg/bla.i')
22 >>> encodedir('data/foo.i.hg/bla.i')
23 'data/foo.i.hg.hg/bla.i'
23 'data/foo.i.hg.hg/bla.i'
24 '''
24 '''
25 if not path.startswith('data/'):
25 if not path.startswith('data/'):
26 return path
26 return path
27 return (path
27 return (path
28 .replace(".hg/", ".hg.hg/")
28 .replace(".hg/", ".hg.hg/")
29 .replace(".i/", ".i.hg/")
29 .replace(".i/", ".i.hg/")
30 .replace(".d/", ".d.hg/"))
30 .replace(".d/", ".d.hg/"))
31
31
32 def decodedir(path):
32 def decodedir(path):
33 '''
33 '''
34 >>> decodedir('data/foo.i')
34 >>> decodedir('data/foo.i')
35 'data/foo.i'
35 'data/foo.i'
36 >>> decodedir('data/foo.i.hg/bla.i')
36 >>> decodedir('data/foo.i.hg/bla.i')
37 'data/foo.i/bla.i'
37 'data/foo.i/bla.i'
38 >>> decodedir('data/foo.i.hg.hg/bla.i')
38 >>> decodedir('data/foo.i.hg.hg/bla.i')
39 'data/foo.i.hg/bla.i'
39 'data/foo.i.hg/bla.i'
40 '''
40 '''
41 if not path.startswith('data/') or ".hg/" not in path:
41 if not path.startswith('data/') or ".hg/" not in path:
42 return path
42 return path
43 return (path
43 return (path
44 .replace(".d.hg/", ".d/")
44 .replace(".d.hg/", ".d/")
45 .replace(".i.hg/", ".i/")
45 .replace(".i.hg/", ".i/")
46 .replace(".hg.hg/", ".hg/"))
46 .replace(".hg.hg/", ".hg/"))
47
47
48 def _buildencodefun():
48 def _buildencodefun():
49 '''
49 '''
50 >>> enc, dec = _buildencodefun()
50 >>> enc, dec = _buildencodefun()
51
51
52 >>> enc('nothing/special.txt')
52 >>> enc('nothing/special.txt')
53 'nothing/special.txt'
53 'nothing/special.txt'
54 >>> dec('nothing/special.txt')
54 >>> dec('nothing/special.txt')
55 'nothing/special.txt'
55 'nothing/special.txt'
56
56
57 >>> enc('HELLO')
57 >>> enc('HELLO')
58 '_h_e_l_l_o'
58 '_h_e_l_l_o'
59 >>> dec('_h_e_l_l_o')
59 >>> dec('_h_e_l_l_o')
60 'HELLO'
60 'HELLO'
61
61
62 >>> enc('hello:world?')
62 >>> enc('hello:world?')
63 'hello~3aworld~3f'
63 'hello~3aworld~3f'
64 >>> dec('hello~3aworld~3f')
64 >>> dec('hello~3aworld~3f')
65 'hello:world?'
65 'hello:world?'
66
66
67 >>> enc('the\x07quick\xADshot')
67 >>> enc('the\x07quick\xADshot')
68 'the~07quick~adshot'
68 'the~07quick~adshot'
69 >>> dec('the~07quick~adshot')
69 >>> dec('the~07quick~adshot')
70 'the\\x07quick\\xadshot'
70 'the\\x07quick\\xadshot'
71 '''
71 '''
72 e = '_'
72 e = '_'
73 winreserved = [ord(x) for x in '\\:*?"<>|']
73 winreserved = [ord(x) for x in '\\:*?"<>|']
74 cmap = dict([(chr(x), chr(x)) for x in xrange(127)])
74 cmap = dict([(chr(x), chr(x)) for x in xrange(127)])
75 for x in (range(32) + range(126, 256) + winreserved):
75 for x in (range(32) + range(126, 256) + winreserved):
76 cmap[chr(x)] = "~%02x" % x
76 cmap[chr(x)] = "~%02x" % x
77 for x in range(ord("A"), ord("Z")+1) + [ord(e)]:
77 for x in range(ord("A"), ord("Z")+1) + [ord(e)]:
78 cmap[chr(x)] = e + chr(x).lower()
78 cmap[chr(x)] = e + chr(x).lower()
79 dmap = {}
79 dmap = {}
80 for k, v in cmap.iteritems():
80 for k, v in cmap.iteritems():
81 dmap[v] = k
81 dmap[v] = k
82 def decode(s):
82 def decode(s):
83 i = 0
83 i = 0
84 while i < len(s):
84 while i < len(s):
85 for l in xrange(1, 4):
85 for l in xrange(1, 4):
86 try:
86 try:
87 yield dmap[s[i:i + l]]
87 yield dmap[s[i:i + l]]
88 i += l
88 i += l
89 break
89 break
90 except KeyError:
90 except KeyError:
91 pass
91 pass
92 else:
92 else:
93 raise KeyError
93 raise KeyError
94 return (lambda s: "".join([cmap[c] for c in encodedir(s)]),
94 return (lambda s: "".join([cmap[c] for c in encodedir(s)]),
95 lambda s: decodedir("".join(list(decode(s)))))
95 lambda s: decodedir("".join(list(decode(s)))))
96
96
97 encodefilename, decodefilename = _buildencodefun()
97 encodefilename, decodefilename = _buildencodefun()
98
98
99 def _buildlowerencodefun():
99 def _buildlowerencodefun():
100 '''
100 '''
101 >>> f = _buildlowerencodefun()
101 >>> f = _buildlowerencodefun()
102 >>> f('nothing/special.txt')
102 >>> f('nothing/special.txt')
103 'nothing/special.txt'
103 'nothing/special.txt'
104 >>> f('HELLO')
104 >>> f('HELLO')
105 'hello'
105 'hello'
106 >>> f('hello:world?')
106 >>> f('hello:world?')
107 'hello~3aworld~3f'
107 'hello~3aworld~3f'
108 >>> f('the\x07quick\xADshot')
108 >>> f('the\x07quick\xADshot')
109 'the~07quick~adshot'
109 'the~07quick~adshot'
110 '''
110 '''
111 winreserved = [ord(x) for x in '\\:*?"<>|']
111 winreserved = [ord(x) for x in '\\:*?"<>|']
112 cmap = dict([(chr(x), chr(x)) for x in xrange(127)])
112 cmap = dict([(chr(x), chr(x)) for x in xrange(127)])
113 for x in (range(32) + range(126, 256) + winreserved):
113 for x in (range(32) + range(126, 256) + winreserved):
114 cmap[chr(x)] = "~%02x" % x
114 cmap[chr(x)] = "~%02x" % x
115 for x in range(ord("A"), ord("Z")+1):
115 for x in range(ord("A"), ord("Z")+1):
116 cmap[chr(x)] = chr(x).lower()
116 cmap[chr(x)] = chr(x).lower()
117 return lambda s: "".join([cmap[c] for c in s])
117 return lambda s: "".join([cmap[c] for c in s])
118
118
119 lowerencode = _buildlowerencodefun()
119 lowerencode = _buildlowerencodefun()
120
120
121 _winreservednames = '''con prn aux nul
121 _winreservednames = '''con prn aux nul
122 com1 com2 com3 com4 com5 com6 com7 com8 com9
122 com1 com2 com3 com4 com5 com6 com7 com8 com9
123 lpt1 lpt2 lpt3 lpt4 lpt5 lpt6 lpt7 lpt8 lpt9'''.split()
123 lpt1 lpt2 lpt3 lpt4 lpt5 lpt6 lpt7 lpt8 lpt9'''.split()
124 def _auxencode(path, dotencode):
124 def _auxencode(path, dotencode):
125 '''
125 '''
126 Encodes filenames containing names reserved by Windows or which end in
126 Encodes filenames containing names reserved by Windows or which end in
127 period or space. Does not touch other single reserved characters c.
127 period or space. Does not touch other single reserved characters c.
128 Specifically, c in '\\:*?"<>|' or ord(c) <= 31 are *not* encoded here.
128 Specifically, c in '\\:*?"<>|' or ord(c) <= 31 are *not* encoded here.
129 Additionally encodes space or period at the beginning, if dotencode is
129 Additionally encodes space or period at the beginning, if dotencode is
130 True.
130 True.
131 path is assumed to be all lowercase.
131 path is assumed to be all lowercase.
132
132
133 >>> _auxencode('.foo/aux.txt/txt.aux/con/prn/nul/foo.', True)
133 >>> _auxencode('.foo/aux.txt/txt.aux/con/prn/nul/foo.', True)
134 '~2efoo/au~78.txt/txt.aux/co~6e/pr~6e/nu~6c/foo~2e'
134 '~2efoo/au~78.txt/txt.aux/co~6e/pr~6e/nu~6c/foo~2e'
135 >>> _auxencode('.com1com2/lpt9.lpt4.lpt1/conprn/foo.', False)
135 >>> _auxencode('.com1com2/lpt9.lpt4.lpt1/conprn/foo.', False)
136 '.com1com2/lp~749.lpt4.lpt1/conprn/foo~2e'
136 '.com1com2/lp~749.lpt4.lpt1/conprn/foo~2e'
137 >>> _auxencode('foo. ', True)
137 >>> _auxencode('foo. ', True)
138 'foo.~20'
138 'foo.~20'
139 >>> _auxencode(' .foo', True)
139 >>> _auxencode(' .foo', True)
140 '~20.foo'
140 '~20.foo'
141 '''
141 '''
142 res = []
142 res = []
143 for n in path.split('/'):
143 for n in path.split('/'):
144 if n:
144 if n:
145 base = n.split('.')[0]
145 base = n.split('.')[0]
146 if base and (base in _winreservednames):
146 if base and (base in _winreservednames):
147 # encode third letter ('aux' -> 'au~78')
147 # encode third letter ('aux' -> 'au~78')
148 ec = "~%02x" % ord(n[2])
148 ec = "~%02x" % ord(n[2])
149 n = n[0:2] + ec + n[3:]
149 n = n[0:2] + ec + n[3:]
150 if n[-1] in '. ':
150 if n[-1] in '. ':
151 # encode last period or space ('foo...' -> 'foo..~2e')
151 # encode last period or space ('foo...' -> 'foo..~2e')
152 n = n[:-1] + "~%02x" % ord(n[-1])
152 n = n[:-1] + "~%02x" % ord(n[-1])
153 if dotencode and n[0] in '. ':
153 if dotencode and n[0] in '. ':
154 n = "~%02x" % ord(n[0]) + n[1:]
154 n = "~%02x" % ord(n[0]) + n[1:]
155 res.append(n)
155 res.append(n)
156 return '/'.join(res)
156 return '/'.join(res)
157
157
158 _maxstorepathlen = 120
158 _maxstorepathlen = 120
159 _dirprefixlen = 8
159 _dirprefixlen = 8
160 _maxshortdirslen = 8 * (_dirprefixlen + 1) - 4
160 _maxshortdirslen = 8 * (_dirprefixlen + 1) - 4
161 def _hybridencode(path, auxencode):
161 def _hybridencode(path, auxencode):
162 '''encodes path with a length limit
162 '''encodes path with a length limit
163
163
164 Encodes all paths that begin with 'data/', according to the following.
164 Encodes all paths that begin with 'data/', according to the following.
165
165
166 Default encoding (reversible):
166 Default encoding (reversible):
167
167
168 Encodes all uppercase letters 'X' as '_x'. All reserved or illegal
168 Encodes all uppercase letters 'X' as '_x'. All reserved or illegal
169 characters are encoded as '~xx', where xx is the two digit hex code
169 characters are encoded as '~xx', where xx is the two digit hex code
170 of the character (see encodefilename).
170 of the character (see encodefilename).
171 Relevant path components consisting of Windows reserved filenames are
171 Relevant path components consisting of Windows reserved filenames are
172 masked by encoding the third character ('aux' -> 'au~78', see auxencode).
172 masked by encoding the third character ('aux' -> 'au~78', see auxencode).
173
173
174 Hashed encoding (not reversible):
174 Hashed encoding (not reversible):
175
175
176 If the default-encoded path is longer than _maxstorepathlen, a
176 If the default-encoded path is longer than _maxstorepathlen, a
177 non-reversible hybrid hashing of the path is done instead.
177 non-reversible hybrid hashing of the path is done instead.
178 This encoding uses up to _dirprefixlen characters of all directory
178 This encoding uses up to _dirprefixlen characters of all directory
179 levels of the lowerencoded path, but not more levels than can fit into
179 levels of the lowerencoded path, but not more levels than can fit into
180 _maxshortdirslen.
180 _maxshortdirslen.
181 Then follows the filler followed by the sha digest of the full path.
181 Then follows the filler followed by the sha digest of the full path.
182 The filler is the beginning of the basename of the lowerencoded path
182 The filler is the beginning of the basename of the lowerencoded path
183 (the basename is everything after the last path separator). The filler
183 (the basename is everything after the last path separator). The filler
184 is as long as possible, filling in characters from the basename until
184 is as long as possible, filling in characters from the basename until
185 the encoded path has _maxstorepathlen characters (or all chars of the
185 the encoded path has _maxstorepathlen characters (or all chars of the
186 basename have been taken).
186 basename have been taken).
187 The extension (e.g. '.i' or '.d') is preserved.
187 The extension (e.g. '.i' or '.d') is preserved.
188
188
189 The string 'data/' at the beginning is replaced with 'dh/', if the hashed
189 The string 'data/' at the beginning is replaced with 'dh/', if the hashed
190 encoding was used.
190 encoding was used.
191 '''
191 '''
192 if not path.startswith('data/'):
192 if not path.startswith('data/'):
193 return path
193 return path
194 # escape directories ending with .i and .d
194 # escape directories ending with .i and .d
195 path = encodedir(path)
195 path = encodedir(path)
196 ndpath = path[len('data/'):]
196 ndpath = path[len('data/'):]
197 res = 'data/' + auxencode(encodefilename(ndpath))
197 res = 'data/' + auxencode(encodefilename(ndpath))
198 if len(res) > _maxstorepathlen:
198 if len(res) > _maxstorepathlen:
199 digest = _sha(path).hexdigest()
199 digest = _sha(path).hexdigest()
200 aep = auxencode(lowerencode(ndpath))
200 aep = auxencode(lowerencode(ndpath))
201 _root, ext = os.path.splitext(aep)
201 _root, ext = os.path.splitext(aep)
202 parts = aep.split('/')
202 parts = aep.split('/')
203 basename = parts[-1]
203 basename = parts[-1]
204 sdirs = []
204 sdirs = []
205 for p in parts[:-1]:
205 for p in parts[:-1]:
206 d = p[:_dirprefixlen]
206 d = p[:_dirprefixlen]
207 if d[-1] in '. ':
207 if d[-1] in '. ':
208 # Windows can't access dirs ending in period or space
208 # Windows can't access dirs ending in period or space
209 d = d[:-1] + '_'
209 d = d[:-1] + '_'
210 t = '/'.join(sdirs) + '/' + d
210 t = '/'.join(sdirs) + '/' + d
211 if len(t) > _maxshortdirslen:
211 if len(t) > _maxshortdirslen:
212 break
212 break
213 sdirs.append(d)
213 sdirs.append(d)
214 dirs = '/'.join(sdirs)
214 dirs = '/'.join(sdirs)
215 if len(dirs) > 0:
215 if len(dirs) > 0:
216 dirs += '/'
216 dirs += '/'
217 res = 'dh/' + dirs + digest + ext
217 res = 'dh/' + dirs + digest + ext
218 spaceleft = _maxstorepathlen - len(res)
218 spaceleft = _maxstorepathlen - len(res)
219 if spaceleft > 0:
219 if spaceleft > 0:
220 filler = basename[:spaceleft]
220 filler = basename[:spaceleft]
221 res = 'dh/' + dirs + filler + digest + ext
221 res = 'dh/' + dirs + filler + digest + ext
222 return res
222 return res
223
223
224 def _calcmode(path):
224 def _calcmode(path):
225 try:
225 try:
226 # files in .hg/ will be created using this mode
226 # files in .hg/ will be created using this mode
227 mode = os.stat(path).st_mode
227 mode = os.stat(path).st_mode
228 # avoid some useless chmods
228 # avoid some useless chmods
229 if (0777 & ~util.umask) == (0777 & mode):
229 if (0777 & ~util.umask) == (0777 & mode):
230 mode = None
230 mode = None
231 except OSError:
231 except OSError:
232 mode = None
232 mode = None
233 return mode
233 return mode
234
234
235 _data = 'data 00manifest.d 00manifest.i 00changelog.d 00changelog.i phaseroots'
235 _data = 'data 00manifest.d 00manifest.i 00changelog.d 00changelog.i phaseroots'
236
236
237 class basicstore(object):
237 class basicstore(object):
238 '''base class for local repository stores'''
238 '''base class for local repository stores'''
239 def __init__(self, path, openertype):
239 def __init__(self, path, openertype):
240 self.path = path
240 self.path = path
241 self.createmode = _calcmode(path)
241 self.createmode = _calcmode(path)
242 op = openertype(self.path)
242 op = openertype(self.path)
243 op.createmode = self.createmode
243 op.createmode = self.createmode
244 self.opener = scmutil.filteropener(op, encodedir)
244 self.opener = scmutil.filteropener(op, encodedir)
245
245
246 def join(self, f):
246 def join(self, f):
247 return self.path + '/' + encodedir(f)
247 return self.path + '/' + encodedir(f)
248
248
249 def _walk(self, relpath, recurse):
249 def _walk(self, relpath, recurse):
250 '''yields (unencoded, encoded, size)'''
250 '''yields (unencoded, encoded, size)'''
251 path = self.path
251 path = self.path
252 if relpath:
252 if relpath:
253 path += '/' + relpath
253 path += '/' + relpath
254 striplen = len(self.path) + 1
254 striplen = len(self.path) + 1
255 l = []
255 l = []
256 if os.path.isdir(path):
256 if os.path.isdir(path):
257 visit = [path]
257 visit = [path]
258 while visit:
258 while visit:
259 p = visit.pop()
259 p = visit.pop()
260 for f, kind, st in osutil.listdir(p, stat=True):
260 for f, kind, st in osutil.listdir(p, stat=True):
261 fp = p + '/' + f
261 fp = p + '/' + f
262 if kind == stat.S_IFREG and f[-2:] in ('.d', '.i'):
262 if kind == stat.S_IFREG and f[-2:] in ('.d', '.i'):
263 n = util.pconvert(fp[striplen:])
263 n = util.pconvert(fp[striplen:])
264 l.append((decodedir(n), n, st.st_size))
264 l.append((decodedir(n), n, st.st_size))
265 elif kind == stat.S_IFDIR and recurse:
265 elif kind == stat.S_IFDIR and recurse:
266 visit.append(fp)
266 visit.append(fp)
267 return sorted(l)
267 return sorted(l)
268
268
269 def datafiles(self):
269 def datafiles(self):
270 return self._walk('data', True)
270 return self._walk('data', True)
271
271
272 def walk(self):
272 def walk(self):
273 '''yields (unencoded, encoded, size)'''
273 '''yields (unencoded, encoded, size)'''
274 # yield data files first
274 # yield data files first
275 for x in self.datafiles():
275 for x in self.datafiles():
276 yield x
276 yield x
277 # yield manifest before changelog
277 # yield manifest before changelog
278 for x in reversed(self._walk('', False)):
278 for x in reversed(self._walk('', False)):
279 yield x
279 yield x
280
280
281 def copylist(self):
281 def copylist(self):
282 return ['requires'] + _data.split()
282 return ['requires'] + _data.split()
283
283
284 def write(self):
284 def write(self):
285 pass
285 pass
286
286
287 class encodedstore(basicstore):
287 class encodedstore(basicstore):
288 def __init__(self, path, openertype):
288 def __init__(self, path, openertype):
289 self.path = path + '/store'
289 self.path = path + '/store'
290 self.createmode = _calcmode(self.path)
290 self.createmode = _calcmode(self.path)
291 op = openertype(self.path)
291 op = openertype(self.path)
292 op.createmode = self.createmode
292 op.createmode = self.createmode
293 self.opener = scmutil.filteropener(op, encodefilename)
293 self.opener = scmutil.filteropener(op, encodefilename)
294
294
295 def datafiles(self):
295 def datafiles(self):
296 for a, b, size in self._walk('data', True):
296 for a, b, size in self._walk('data', True):
297 try:
297 try:
298 a = decodefilename(a)
298 a = decodefilename(a)
299 except KeyError:
299 except KeyError:
300 a = None
300 a = None
301 yield a, b, size
301 yield a, b, size
302
302
303 def join(self, f):
303 def join(self, f):
304 return self.path + '/' + encodefilename(f)
304 return self.path + '/' + encodefilename(f)
305
305
306 def copylist(self):
306 def copylist(self):
307 return (['requires', '00changelog.i'] +
307 return (['requires', '00changelog.i'] +
308 ['store/' + f for f in _data.split()])
308 ['store/' + f for f in _data.split()])
309
309
310 class fncache(object):
310 class fncache(object):
311 # the filename used to be partially encoded
311 # the filename used to be partially encoded
312 # hence the encodedir/decodedir dance
312 # hence the encodedir/decodedir dance
313 def __init__(self, opener):
313 def __init__(self, opener):
314 self.opener = opener
314 self.opener = opener
315 self.entries = None
315 self.entries = None
316 self._dirty = False
316 self._dirty = False
317
317
318 def _load(self):
318 def _load(self):
319 '''fill the entries from the fncache file'''
319 '''fill the entries from the fncache file'''
320 self.entries = set()
320 self.entries = set()
321 self._dirty = False
321 self._dirty = False
322 try:
322 try:
323 fp = self.opener('fncache', mode='rb')
323 fp = self.opener('fncache', mode='rb')
324 except IOError:
324 except IOError:
325 # skip nonexistent file
325 # skip nonexistent file
326 return
326 return
327 for n, line in enumerate(fp):
327 for n, line in enumerate(fp):
328 if (len(line) < 2) or (line[-1] != '\n'):
328 if (len(line) < 2) or (line[-1] != '\n'):
329 t = _('invalid entry in fncache, line %s') % (n + 1)
329 t = _('invalid entry in fncache, line %s') % (n + 1)
330 raise util.Abort(t)
330 raise util.Abort(t)
331 self.entries.add(decodedir(line[:-1]))
331 self.entries.add(decodedir(line[:-1]))
332 fp.close()
332 fp.close()
333
333
334 def rewrite(self, files):
334 def rewrite(self, files):
335 fp = self.opener('fncache', mode='wb')
335 fp = self.opener('fncache', mode='wb')
336 for p in files:
336 for p in files:
337 fp.write(encodedir(p) + '\n')
337 fp.write(encodedir(p) + '\n')
338 fp.close()
338 fp.close()
339 self.entries = set(files)
339 self.entries = set(files)
340 self._dirty = False
340 self._dirty = False
341
341
342 def write(self):
342 def write(self):
343 if not self._dirty:
343 if not self._dirty:
344 return
344 return
345 fp = self.opener('fncache', mode='wb', atomictemp=True)
345 fp = self.opener('fncache', mode='wb', atomictemp=True)
346 for p in self.entries:
346 for p in self.entries:
347 fp.write(encodedir(p) + '\n')
347 fp.write(encodedir(p) + '\n')
348 fp.close()
348 fp.close()
349 self._dirty = False
349 self._dirty = False
350
350
351 def add(self, fn):
351 def add(self, fn):
352 if self.entries is None:
352 if self.entries is None:
353 self._load()
353 self._load()
354 if fn not in self.entries:
354 if fn not in self.entries:
355 self._dirty = True
355 self._dirty = True
356 self.entries.add(fn)
356 self.entries.add(fn)
357
357
358 def __contains__(self, fn):
358 def __contains__(self, fn):
359 if self.entries is None:
359 if self.entries is None:
360 self._load()
360 self._load()
361 return fn in self.entries
361 return fn in self.entries
362
362
363 def __iter__(self):
363 def __iter__(self):
364 if self.entries is None:
364 if self.entries is None:
365 self._load()
365 self._load()
366 return iter(self.entries)
366 return iter(self.entries)
367
367
368 class _fncacheopener(scmutil.abstractopener):
368 class _fncacheopener(scmutil.abstractopener):
369 def __init__(self, op, fnc, encode):
369 def __init__(self, op, fnc, encode):
370 self.opener = op
370 self.opener = op
371 self.fncache = fnc
371 self.fncache = fnc
372 self.encode = encode
372 self.encode = encode
373
373
374 def __call__(self, path, mode='r', *args, **kw):
374 def __call__(self, path, mode='r', *args, **kw):
375 if mode not in ('r', 'rb') and path.startswith('data/'):
375 if mode not in ('r', 'rb') and path.startswith('data/'):
376 self.fncache.add(path)
376 self.fncache.add(path)
377 return self.opener(self.encode(path), mode, *args, **kw)
377 return self.opener(self.encode(path), mode, *args, **kw)
378
378
379 class fncachestore(basicstore):
379 class fncachestore(basicstore):
380 def __init__(self, path, openertype, encode):
380 def __init__(self, path, openertype, encode):
381 self.encode = encode
381 self.encode = encode
382 self.path = path + '/store'
382 self.path = path + '/store'
383 self.createmode = _calcmode(self.path)
383 self.createmode = _calcmode(self.path)
384 op = openertype(self.path)
384 op = openertype(self.path)
385 op.createmode = self.createmode
385 op.createmode = self.createmode
386 fnc = fncache(op)
386 fnc = fncache(op)
387 self.fncache = fnc
387 self.fncache = fnc
388 self.opener = _fncacheopener(op, fnc, encode)
388 self.opener = _fncacheopener(op, fnc, encode)
389
389
390 def join(self, f):
390 def join(self, f):
391 return self.path + '/' + self.encode(f)
391 return self.path + '/' + self.encode(f)
392
392
393 def datafiles(self):
393 def datafiles(self):
394 rewrite = False
394 rewrite = False
395 existing = []
395 existing = []
396 spath = self.path
396 spath = self.path
397 for f in self.fncache:
397 for f in self.fncache:
398 ef = self.encode(f)
398 ef = self.encode(f)
399 try:
399 try:
400 st = os.stat(spath + '/' + ef)
400 st = os.stat(spath + '/' + ef)
401 yield f, ef, st.st_size
401 yield f, ef, st.st_size
402 existing.append(f)
402 existing.append(f)
403 except OSError:
403 except OSError:
404 # nonexistent entry
404 # nonexistent entry
405 rewrite = True
405 rewrite = True
406 if rewrite:
406 if rewrite:
407 # rewrite fncache to remove nonexistent entries
407 # rewrite fncache to remove nonexistent entries
408 # (may be caused by rollback / strip)
408 # (may be caused by rollback / strip)
409 self.fncache.rewrite(existing)
409 self.fncache.rewrite(existing)
410
410
411 def copylist(self):
411 def copylist(self):
412 d = ('data dh fncache'
412 d = ('data dh fncache phaseroots'
413 ' 00manifest.d 00manifest.i 00changelog.d 00changelog.i phaseroots')
413 ' 00manifest.d 00manifest.i 00changelog.d 00changelog.i')
414 return (['requires', '00changelog.i'] +
414 return (['requires', '00changelog.i'] +
415 ['store/' + f for f in d.split()])
415 ['store/' + f for f in d.split()])
416
416
417 def write(self):
417 def write(self):
418 self.fncache.write()
418 self.fncache.write()
419
419
420 def store(requirements, path, openertype):
420 def store(requirements, path, openertype):
421 if 'store' in requirements:
421 if 'store' in requirements:
422 if 'fncache' in requirements:
422 if 'fncache' in requirements:
423 auxencode = lambda f: _auxencode(f, 'dotencode' in requirements)
423 auxencode = lambda f: _auxencode(f, 'dotencode' in requirements)
424 encode = lambda f: _hybridencode(f, auxencode)
424 encode = lambda f: _hybridencode(f, auxencode)
425 return fncachestore(path, openertype, encode)
425 return fncachestore(path, openertype, encode)
426 return encodedstore(path, openertype)
426 return encodedstore(path, openertype)
427 return basicstore(path, openertype)
427 return basicstore(path, openertype)
@@ -1,877 +1,879 b''
1 $ "$TESTDIR/hghave" symlink unix-permissions serve || exit 80
1 $ "$TESTDIR/hghave" symlink unix-permissions serve || exit 80
2
2
3 $ cat >> $HGRCPATH <<EOF
3 $ cat >> $HGRCPATH <<EOF
4 > [extensions]
4 > [extensions]
5 > largefiles=
5 > largefiles=
6 > purge=
6 > purge=
7 > rebase=
7 > rebase=
8 > transplant=
8 > transplant=
9 > [phases]
10 > publish=False
9 > [largefiles]
11 > [largefiles]
10 > minsize=2
12 > minsize=2
11 > patterns=glob:**.dat
13 > patterns=glob:**.dat
12 > EOF
14 > EOF
13
15
14 Create the repo with a couple of revisions of both large and normal
16 Create the repo with a couple of revisions of both large and normal
15 files, testing that status correctly shows largefiles.
17 files, testing that status correctly shows largefiles.
16
18
17 $ hg init a
19 $ hg init a
18 $ cd a
20 $ cd a
19 $ mkdir sub
21 $ mkdir sub
20 $ echo normal1 > normal1
22 $ echo normal1 > normal1
21 $ echo normal2 > sub/normal2
23 $ echo normal2 > sub/normal2
22 $ echo large1 > large1
24 $ echo large1 > large1
23 $ echo large2 > sub/large2
25 $ echo large2 > sub/large2
24 $ hg add normal1 sub/normal2
26 $ hg add normal1 sub/normal2
25 $ hg add --large large1 sub/large2
27 $ hg add --large large1 sub/large2
26 $ hg commit -m "add files"
28 $ hg commit -m "add files"
27 $ echo normal11 > normal1
29 $ echo normal11 > normal1
28 $ echo normal22 > sub/normal2
30 $ echo normal22 > sub/normal2
29 $ echo large11 > large1
31 $ echo large11 > large1
30 $ echo large22 > sub/large2
32 $ echo large22 > sub/large2
31 $ hg st
33 $ hg st
32 M large1
34 M large1
33 M normal1
35 M normal1
34 M sub/large2
36 M sub/large2
35 M sub/normal2
37 M sub/normal2
36 $ hg commit -m "edit files"
38 $ hg commit -m "edit files"
37
39
38 Commit preserved largefile contents.
40 Commit preserved largefile contents.
39
41
40 $ cat normal1
42 $ cat normal1
41 normal11
43 normal11
42 $ cat large1
44 $ cat large1
43 large11
45 large11
44 $ cat sub/normal2
46 $ cat sub/normal2
45 normal22
47 normal22
46 $ cat sub/large2
48 $ cat sub/large2
47 large22
49 large22
48
50
49 Remove both largefiles and normal files.
51 Remove both largefiles and normal files.
50
52
51 $ hg remove normal1 large1
53 $ hg remove normal1 large1
52 $ hg commit -m "remove files"
54 $ hg commit -m "remove files"
53 $ ls
55 $ ls
54 sub
56 sub
55
57
56 Copy both largefiles and normal files (testing that status output is correct).
58 Copy both largefiles and normal files (testing that status output is correct).
57
59
58 $ hg cp sub/normal2 normal1
60 $ hg cp sub/normal2 normal1
59 $ hg cp sub/large2 large1
61 $ hg cp sub/large2 large1
60 $ hg st
62 $ hg st
61 A large1
63 A large1
62 A normal1
64 A normal1
63 $ hg commit -m "copy files"
65 $ hg commit -m "copy files"
64 $ cat normal1
66 $ cat normal1
65 normal22
67 normal22
66 $ cat large1
68 $ cat large1
67 large22
69 large22
68
70
69 Test moving largefiles and verify that normal files are also unaffected.
71 Test moving largefiles and verify that normal files are also unaffected.
70
72
71 $ hg mv normal1 normal3
73 $ hg mv normal1 normal3
72 $ hg mv large1 large3
74 $ hg mv large1 large3
73 $ hg mv sub/normal2 sub/normal4
75 $ hg mv sub/normal2 sub/normal4
74 $ hg mv sub/large2 sub/large4
76 $ hg mv sub/large2 sub/large4
75 $ hg commit -m "move files"
77 $ hg commit -m "move files"
76 $ cat normal3
78 $ cat normal3
77 normal22
79 normal22
78 $ cat large3
80 $ cat large3
79 large22
81 large22
80 $ cat sub/normal4
82 $ cat sub/normal4
81 normal22
83 normal22
82 $ cat sub/large4
84 $ cat sub/large4
83 large22
85 large22
84
86
85 Test archiving the various revisions. These hit corner cases known with
87 Test archiving the various revisions. These hit corner cases known with
86 archiving.
88 archiving.
87
89
88 $ hg archive -r 0 ../archive0
90 $ hg archive -r 0 ../archive0
89 $ hg archive -r 1 ../archive1
91 $ hg archive -r 1 ../archive1
90 $ hg archive -r 2 ../archive2
92 $ hg archive -r 2 ../archive2
91 $ hg archive -r 3 ../archive3
93 $ hg archive -r 3 ../archive3
92 $ hg archive -r 4 ../archive4
94 $ hg archive -r 4 ../archive4
93 $ cd ../archive0
95 $ cd ../archive0
94 $ cat normal1
96 $ cat normal1
95 normal1
97 normal1
96 $ cat large1
98 $ cat large1
97 large1
99 large1
98 $ cat sub/normal2
100 $ cat sub/normal2
99 normal2
101 normal2
100 $ cat sub/large2
102 $ cat sub/large2
101 large2
103 large2
102 $ cd ../archive1
104 $ cd ../archive1
103 $ cat normal1
105 $ cat normal1
104 normal11
106 normal11
105 $ cat large1
107 $ cat large1
106 large11
108 large11
107 $ cat sub/normal2
109 $ cat sub/normal2
108 normal22
110 normal22
109 $ cat sub/large2
111 $ cat sub/large2
110 large22
112 large22
111 $ cd ../archive2
113 $ cd ../archive2
112 $ ls
114 $ ls
113 sub
115 sub
114 $ cat sub/normal2
116 $ cat sub/normal2
115 normal22
117 normal22
116 $ cat sub/large2
118 $ cat sub/large2
117 large22
119 large22
118 $ cd ../archive3
120 $ cd ../archive3
119 $ cat normal1
121 $ cat normal1
120 normal22
122 normal22
121 $ cat large1
123 $ cat large1
122 large22
124 large22
123 $ cat sub/normal2
125 $ cat sub/normal2
124 normal22
126 normal22
125 $ cat sub/large2
127 $ cat sub/large2
126 large22
128 large22
127 $ cd ../archive4
129 $ cd ../archive4
128 $ cat normal3
130 $ cat normal3
129 normal22
131 normal22
130 $ cat large3
132 $ cat large3
131 large22
133 large22
132 $ cat sub/normal4
134 $ cat sub/normal4
133 normal22
135 normal22
134 $ cat sub/large4
136 $ cat sub/large4
135 large22
137 large22
136
138
137 Commit corner case: specify files to commit.
139 Commit corner case: specify files to commit.
138
140
139 $ cd ../a
141 $ cd ../a
140 $ echo normal3 > normal3
142 $ echo normal3 > normal3
141 $ echo large3 > large3
143 $ echo large3 > large3
142 $ echo normal4 > sub/normal4
144 $ echo normal4 > sub/normal4
143 $ echo large4 > sub/large4
145 $ echo large4 > sub/large4
144 $ hg commit normal3 large3 sub/normal4 sub/large4 -m "edit files again"
146 $ hg commit normal3 large3 sub/normal4 sub/large4 -m "edit files again"
145 $ cat normal3
147 $ cat normal3
146 normal3
148 normal3
147 $ cat large3
149 $ cat large3
148 large3
150 large3
149 $ cat sub/normal4
151 $ cat sub/normal4
150 normal4
152 normal4
151 $ cat sub/large4
153 $ cat sub/large4
152 large4
154 large4
153
155
154 One more commit corner case: commit from a subdirectory.
156 One more commit corner case: commit from a subdirectory.
155
157
156 $ cd ../a
158 $ cd ../a
157 $ echo normal33 > normal3
159 $ echo normal33 > normal3
158 $ echo large33 > large3
160 $ echo large33 > large3
159 $ echo normal44 > sub/normal4
161 $ echo normal44 > sub/normal4
160 $ echo large44 > sub/large4
162 $ echo large44 > sub/large4
161 $ cd sub
163 $ cd sub
162 $ hg commit -m "edit files yet again"
164 $ hg commit -m "edit files yet again"
163 $ cat ../normal3
165 $ cat ../normal3
164 normal33
166 normal33
165 $ cat ../large3
167 $ cat ../large3
166 large33
168 large33
167 $ cat normal4
169 $ cat normal4
168 normal44
170 normal44
169 $ cat large4
171 $ cat large4
170 large44
172 large44
171
173
172 Committing standins is not allowed.
174 Committing standins is not allowed.
173
175
174 $ cd ..
176 $ cd ..
175 $ echo large3 > large3
177 $ echo large3 > large3
176 $ hg commit .hglf/large3 -m "try to commit standin"
178 $ hg commit .hglf/large3 -m "try to commit standin"
177 abort: file ".hglf/large3" is a largefile standin
179 abort: file ".hglf/large3" is a largefile standin
178 (commit the largefile itself instead)
180 (commit the largefile itself instead)
179 [255]
181 [255]
180
182
181 Corner cases for adding largefiles.
183 Corner cases for adding largefiles.
182
184
183 $ echo large5 > large5
185 $ echo large5 > large5
184 $ hg add --large large5
186 $ hg add --large large5
185 $ hg add --large large5
187 $ hg add --large large5
186 large5 already a largefile
188 large5 already a largefile
187 $ mkdir sub2
189 $ mkdir sub2
188 $ echo large6 > sub2/large6
190 $ echo large6 > sub2/large6
189 $ echo large7 > sub2/large7
191 $ echo large7 > sub2/large7
190 $ hg add --large sub2
192 $ hg add --large sub2
191 adding sub2/large6 as a largefile (glob)
193 adding sub2/large6 as a largefile (glob)
192 adding sub2/large7 as a largefile (glob)
194 adding sub2/large7 as a largefile (glob)
193 $ hg st
195 $ hg st
194 M large3
196 M large3
195 A large5
197 A large5
196 A sub2/large6
198 A sub2/large6
197 A sub2/large7
199 A sub2/large7
198
200
199 Config settings (pattern **.dat, minsize 2 MB) are respected.
201 Config settings (pattern **.dat, minsize 2 MB) are respected.
200
202
201 $ echo testdata > test.dat
203 $ echo testdata > test.dat
202 $ dd bs=1k count=2k if=/dev/zero of=reallylarge > /dev/null 2> /dev/null
204 $ dd bs=1k count=2k if=/dev/zero of=reallylarge > /dev/null 2> /dev/null
203 $ hg add
205 $ hg add
204 adding reallylarge as a largefile
206 adding reallylarge as a largefile
205 adding test.dat as a largefile
207 adding test.dat as a largefile
206
208
207 Test that minsize and --lfsize handle float values;
209 Test that minsize and --lfsize handle float values;
208 also tests that --lfsize overrides largefiles.minsize.
210 also tests that --lfsize overrides largefiles.minsize.
209 (0.250 MB = 256 kB = 262144 B)
211 (0.250 MB = 256 kB = 262144 B)
210
212
211 $ dd if=/dev/zero of=ratherlarge bs=1024 count=256 > /dev/null 2> /dev/null
213 $ dd if=/dev/zero of=ratherlarge bs=1024 count=256 > /dev/null 2> /dev/null
212 $ dd if=/dev/zero of=medium bs=1024 count=128 > /dev/null 2> /dev/null
214 $ dd if=/dev/zero of=medium bs=1024 count=128 > /dev/null 2> /dev/null
213 $ hg --config largefiles.minsize=.25 add
215 $ hg --config largefiles.minsize=.25 add
214 adding ratherlarge as a largefile
216 adding ratherlarge as a largefile
215 adding medium
217 adding medium
216 $ hg forget medium
218 $ hg forget medium
217 $ hg --config largefiles.minsize=.25 add --lfsize=.125
219 $ hg --config largefiles.minsize=.25 add --lfsize=.125
218 adding medium as a largefile
220 adding medium as a largefile
219 $ dd if=/dev/zero of=notlarge bs=1024 count=127 > /dev/null 2> /dev/null
221 $ dd if=/dev/zero of=notlarge bs=1024 count=127 > /dev/null 2> /dev/null
220 $ hg --config largefiles.minsize=.25 add --lfsize=.125
222 $ hg --config largefiles.minsize=.25 add --lfsize=.125
221 adding notlarge
223 adding notlarge
222 $ hg forget notlarge
224 $ hg forget notlarge
223
225
224 Test forget on largefiles.
226 Test forget on largefiles.
225
227
226 $ hg forget large3 large5 test.dat reallylarge ratherlarge medium
228 $ hg forget large3 large5 test.dat reallylarge ratherlarge medium
227 $ hg st
229 $ hg st
228 A sub2/large6
230 A sub2/large6
229 A sub2/large7
231 A sub2/large7
230 R large3
232 R large3
231 ? large5
233 ? large5
232 ? medium
234 ? medium
233 ? notlarge
235 ? notlarge
234 ? ratherlarge
236 ? ratherlarge
235 ? reallylarge
237 ? reallylarge
236 ? test.dat
238 ? test.dat
237 $ hg commit -m "add/edit more largefiles"
239 $ hg commit -m "add/edit more largefiles"
238 $ hg st
240 $ hg st
239 ? large3
241 ? large3
240 ? large5
242 ? large5
241 ? medium
243 ? medium
242 ? notlarge
244 ? notlarge
243 ? ratherlarge
245 ? ratherlarge
244 ? reallylarge
246 ? reallylarge
245 ? test.dat
247 ? test.dat
246
248
247 Purge with largefiles: verify that largefiles are still in the working
249 Purge with largefiles: verify that largefiles are still in the working
248 dir after a purge.
250 dir after a purge.
249
251
250 $ hg purge --all
252 $ hg purge --all
251 $ cat sub/large4
253 $ cat sub/large4
252 large44
254 large44
253 $ cat sub2/large6
255 $ cat sub2/large6
254 large6
256 large6
255 $ cat sub2/large7
257 $ cat sub2/large7
256 large7
258 large7
257
259
258 Clone a largefiles repo.
260 Clone a largefiles repo.
259
261
260 $ hg clone . ../b
262 $ hg clone . ../b
261 updating to branch default
263 updating to branch default
262 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
264 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
263 getting changed largefiles
265 getting changed largefiles
264 3 largefiles updated, 0 removed
266 3 largefiles updated, 0 removed
265 $ cd ../b
267 $ cd ../b
266 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
268 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
267 7:daea875e9014 add/edit more largefiles
269 7:daea875e9014 add/edit more largefiles
268 6:4355d653f84f edit files yet again
270 6:4355d653f84f edit files yet again
269 5:9d5af5072dbd edit files again
271 5:9d5af5072dbd edit files again
270 4:74c02385b94c move files
272 4:74c02385b94c move files
271 3:9e8fbc4bce62 copy files
273 3:9e8fbc4bce62 copy files
272 2:51a0ae4d5864 remove files
274 2:51a0ae4d5864 remove files
273 1:ce8896473775 edit files
275 1:ce8896473775 edit files
274 0:30d30fe6a5be add files
276 0:30d30fe6a5be add files
275 $ cat normal3
277 $ cat normal3
276 normal33
278 normal33
277 $ cat sub/normal4
279 $ cat sub/normal4
278 normal44
280 normal44
279 $ cat sub/large4
281 $ cat sub/large4
280 large44
282 large44
281 $ cat sub2/large6
283 $ cat sub2/large6
282 large6
284 large6
283 $ cat sub2/large7
285 $ cat sub2/large7
284 large7
286 large7
285 $ cd ..
287 $ cd ..
286 $ hg clone a -r 3 c
288 $ hg clone a -r 3 c
287 adding changesets
289 adding changesets
288 adding manifests
290 adding manifests
289 adding file changes
291 adding file changes
290 added 4 changesets with 10 changes to 4 files
292 added 4 changesets with 10 changes to 4 files
291 updating to branch default
293 updating to branch default
292 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
294 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
293 getting changed largefiles
295 getting changed largefiles
294 2 largefiles updated, 0 removed
296 2 largefiles updated, 0 removed
295 $ cd c
297 $ cd c
296 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
298 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
297 3:9e8fbc4bce62 copy files
299 3:9e8fbc4bce62 copy files
298 2:51a0ae4d5864 remove files
300 2:51a0ae4d5864 remove files
299 1:ce8896473775 edit files
301 1:ce8896473775 edit files
300 0:30d30fe6a5be add files
302 0:30d30fe6a5be add files
301 $ cat normal1
303 $ cat normal1
302 normal22
304 normal22
303 $ cat large1
305 $ cat large1
304 large22
306 large22
305 $ cat sub/normal2
307 $ cat sub/normal2
306 normal22
308 normal22
307 $ cat sub/large2
309 $ cat sub/large2
308 large22
310 large22
309
311
310 Old revisions of a clone have correct largefiles content (this also
312 Old revisions of a clone have correct largefiles content (this also
311 tests update).
313 tests update).
312
314
313 $ hg update -r 1
315 $ hg update -r 1
314 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
316 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
315 getting changed largefiles
317 getting changed largefiles
316 1 largefiles updated, 0 removed
318 1 largefiles updated, 0 removed
317 $ cat large1
319 $ cat large1
318 large11
320 large11
319 $ cat sub/large2
321 $ cat sub/large2
320 large22
322 large22
321
323
322 Rebasing between two repositories does not revert largefiles to old
324 Rebasing between two repositories does not revert largefiles to old
323 revisions (this was a very bad bug that took a lot of work to fix).
325 revisions (this was a very bad bug that took a lot of work to fix).
324
326
325 $ cd ..
327 $ cd ..
326 $ hg clone a d
328 $ hg clone a d
327 updating to branch default
329 updating to branch default
328 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
330 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
329 getting changed largefiles
331 getting changed largefiles
330 3 largefiles updated, 0 removed
332 3 largefiles updated, 0 removed
331 $ cd b
333 $ cd b
332 $ echo large4-modified > sub/large4
334 $ echo large4-modified > sub/large4
333 $ echo normal3-modified > normal3
335 $ echo normal3-modified > normal3
334 $ hg commit -m "modify normal file and largefile in repo b"
336 $ hg commit -m "modify normal file and largefile in repo b"
335 $ cd ../d
337 $ cd ../d
336 $ echo large6-modified > sub2/large6
338 $ echo large6-modified > sub2/large6
337 $ echo normal4-modified > sub/normal4
339 $ echo normal4-modified > sub/normal4
338 $ hg commit -m "modify normal file largefile in repo d"
340 $ hg commit -m "modify normal file largefile in repo d"
339 $ cd ..
341 $ cd ..
340 $ hg clone d e
342 $ hg clone d e
341 updating to branch default
343 updating to branch default
342 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
344 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
343 getting changed largefiles
345 getting changed largefiles
344 3 largefiles updated, 0 removed
346 3 largefiles updated, 0 removed
345 $ cd d
347 $ cd d
346 $ hg pull --rebase ../b
348 $ hg pull --rebase ../b
347 pulling from ../b
349 pulling from ../b
348 searching for changes
350 searching for changes
349 adding changesets
351 adding changesets
350 adding manifests
352 adding manifests
351 adding file changes
353 adding file changes
352 added 1 changesets with 2 changes to 2 files (+1 heads)
354 added 1 changesets with 2 changes to 2 files (+1 heads)
353 getting changed largefiles
355 getting changed largefiles
354 1 largefiles updated, 0 removed
356 1 largefiles updated, 0 removed
355 saved backup bundle to $TESTTMP/d/.hg/strip-backup/f574fb32bb45-backup.hg (glob)
357 saved backup bundle to $TESTTMP/d/.hg/strip-backup/f574fb32bb45-backup.hg (glob)
356 nothing to rebase
358 nothing to rebase
357 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
359 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
358 9:598410d3eb9a modify normal file largefile in repo d
360 9:598410d3eb9a modify normal file largefile in repo d
359 8:a381d2c8c80e modify normal file and largefile in repo b
361 8:a381d2c8c80e modify normal file and largefile in repo b
360 7:daea875e9014 add/edit more largefiles
362 7:daea875e9014 add/edit more largefiles
361 6:4355d653f84f edit files yet again
363 6:4355d653f84f edit files yet again
362 5:9d5af5072dbd edit files again
364 5:9d5af5072dbd edit files again
363 4:74c02385b94c move files
365 4:74c02385b94c move files
364 3:9e8fbc4bce62 copy files
366 3:9e8fbc4bce62 copy files
365 2:51a0ae4d5864 remove files
367 2:51a0ae4d5864 remove files
366 1:ce8896473775 edit files
368 1:ce8896473775 edit files
367 0:30d30fe6a5be add files
369 0:30d30fe6a5be add files
368 $ cat normal3
370 $ cat normal3
369 normal3-modified
371 normal3-modified
370 $ cat sub/normal4
372 $ cat sub/normal4
371 normal4-modified
373 normal4-modified
372 $ cat sub/large4
374 $ cat sub/large4
373 large4-modified
375 large4-modified
374 $ cat sub2/large6
376 $ cat sub2/large6
375 large6-modified
377 large6-modified
376 $ cat sub2/large7
378 $ cat sub2/large7
377 large7
379 large7
378 $ cd ../e
380 $ cd ../e
379 $ hg pull ../b
381 $ hg pull ../b
380 pulling from ../b
382 pulling from ../b
381 searching for changes
383 searching for changes
382 adding changesets
384 adding changesets
383 adding manifests
385 adding manifests
384 adding file changes
386 adding file changes
385 added 1 changesets with 2 changes to 2 files (+1 heads)
387 added 1 changesets with 2 changes to 2 files (+1 heads)
386 (run 'hg heads' to see heads, 'hg merge' to merge)
388 (run 'hg heads' to see heads, 'hg merge' to merge)
387 $ hg rebase
389 $ hg rebase
388 getting changed largefiles
390 getting changed largefiles
389 1 largefiles updated, 0 removed
391 1 largefiles updated, 0 removed
390 saved backup bundle to $TESTTMP/e/.hg/strip-backup/f574fb32bb45-backup.hg (glob)
392 saved backup bundle to $TESTTMP/e/.hg/strip-backup/f574fb32bb45-backup.hg (glob)
391 $ hg log
393 $ hg log
392 changeset: 9:598410d3eb9a
394 changeset: 9:598410d3eb9a
393 tag: tip
395 tag: tip
394 user: test
396 user: test
395 date: Thu Jan 01 00:00:00 1970 +0000
397 date: Thu Jan 01 00:00:00 1970 +0000
396 summary: modify normal file largefile in repo d
398 summary: modify normal file largefile in repo d
397
399
398 changeset: 8:a381d2c8c80e
400 changeset: 8:a381d2c8c80e
399 user: test
401 user: test
400 date: Thu Jan 01 00:00:00 1970 +0000
402 date: Thu Jan 01 00:00:00 1970 +0000
401 summary: modify normal file and largefile in repo b
403 summary: modify normal file and largefile in repo b
402
404
403 changeset: 7:daea875e9014
405 changeset: 7:daea875e9014
404 user: test
406 user: test
405 date: Thu Jan 01 00:00:00 1970 +0000
407 date: Thu Jan 01 00:00:00 1970 +0000
406 summary: add/edit more largefiles
408 summary: add/edit more largefiles
407
409
408 changeset: 6:4355d653f84f
410 changeset: 6:4355d653f84f
409 user: test
411 user: test
410 date: Thu Jan 01 00:00:00 1970 +0000
412 date: Thu Jan 01 00:00:00 1970 +0000
411 summary: edit files yet again
413 summary: edit files yet again
412
414
413 changeset: 5:9d5af5072dbd
415 changeset: 5:9d5af5072dbd
414 user: test
416 user: test
415 date: Thu Jan 01 00:00:00 1970 +0000
417 date: Thu Jan 01 00:00:00 1970 +0000
416 summary: edit files again
418 summary: edit files again
417
419
418 changeset: 4:74c02385b94c
420 changeset: 4:74c02385b94c
419 user: test
421 user: test
420 date: Thu Jan 01 00:00:00 1970 +0000
422 date: Thu Jan 01 00:00:00 1970 +0000
421 summary: move files
423 summary: move files
422
424
423 changeset: 3:9e8fbc4bce62
425 changeset: 3:9e8fbc4bce62
424 user: test
426 user: test
425 date: Thu Jan 01 00:00:00 1970 +0000
427 date: Thu Jan 01 00:00:00 1970 +0000
426 summary: copy files
428 summary: copy files
427
429
428 changeset: 2:51a0ae4d5864
430 changeset: 2:51a0ae4d5864
429 user: test
431 user: test
430 date: Thu Jan 01 00:00:00 1970 +0000
432 date: Thu Jan 01 00:00:00 1970 +0000
431 summary: remove files
433 summary: remove files
432
434
433 changeset: 1:ce8896473775
435 changeset: 1:ce8896473775
434 user: test
436 user: test
435 date: Thu Jan 01 00:00:00 1970 +0000
437 date: Thu Jan 01 00:00:00 1970 +0000
436 summary: edit files
438 summary: edit files
437
439
438 changeset: 0:30d30fe6a5be
440 changeset: 0:30d30fe6a5be
439 user: test
441 user: test
440 date: Thu Jan 01 00:00:00 1970 +0000
442 date: Thu Jan 01 00:00:00 1970 +0000
441 summary: add files
443 summary: add files
442
444
443 $ cat normal3
445 $ cat normal3
444 normal3-modified
446 normal3-modified
445 $ cat sub/normal4
447 $ cat sub/normal4
446 normal4-modified
448 normal4-modified
447 $ cat sub/large4
449 $ cat sub/large4
448 large4-modified
450 large4-modified
449 $ cat sub2/large6
451 $ cat sub2/large6
450 large6-modified
452 large6-modified
451 $ cat sub2/large7
453 $ cat sub2/large7
452 large7
454 large7
453
455
454 Rollback on largefiles.
456 Rollback on largefiles.
455
457
456 $ echo large4-modified-again > sub/large4
458 $ echo large4-modified-again > sub/large4
457 $ hg commit -m "Modify large4 again"
459 $ hg commit -m "Modify large4 again"
458 $ hg rollback
460 $ hg rollback
459 repository tip rolled back to revision 9 (undo commit)
461 repository tip rolled back to revision 9 (undo commit)
460 working directory now based on revision 9
462 working directory now based on revision 9
461 $ hg st
463 $ hg st
462 M sub/large4
464 M sub/large4
463 $ hg log
465 $ hg log
464 changeset: 9:598410d3eb9a
466 changeset: 9:598410d3eb9a
465 tag: tip
467 tag: tip
466 user: test
468 user: test
467 date: Thu Jan 01 00:00:00 1970 +0000
469 date: Thu Jan 01 00:00:00 1970 +0000
468 summary: modify normal file largefile in repo d
470 summary: modify normal file largefile in repo d
469
471
470 changeset: 8:a381d2c8c80e
472 changeset: 8:a381d2c8c80e
471 user: test
473 user: test
472 date: Thu Jan 01 00:00:00 1970 +0000
474 date: Thu Jan 01 00:00:00 1970 +0000
473 summary: modify normal file and largefile in repo b
475 summary: modify normal file and largefile in repo b
474
476
475 changeset: 7:daea875e9014
477 changeset: 7:daea875e9014
476 user: test
478 user: test
477 date: Thu Jan 01 00:00:00 1970 +0000
479 date: Thu Jan 01 00:00:00 1970 +0000
478 summary: add/edit more largefiles
480 summary: add/edit more largefiles
479
481
480 changeset: 6:4355d653f84f
482 changeset: 6:4355d653f84f
481 user: test
483 user: test
482 date: Thu Jan 01 00:00:00 1970 +0000
484 date: Thu Jan 01 00:00:00 1970 +0000
483 summary: edit files yet again
485 summary: edit files yet again
484
486
485 changeset: 5:9d5af5072dbd
487 changeset: 5:9d5af5072dbd
486 user: test
488 user: test
487 date: Thu Jan 01 00:00:00 1970 +0000
489 date: Thu Jan 01 00:00:00 1970 +0000
488 summary: edit files again
490 summary: edit files again
489
491
490 changeset: 4:74c02385b94c
492 changeset: 4:74c02385b94c
491 user: test
493 user: test
492 date: Thu Jan 01 00:00:00 1970 +0000
494 date: Thu Jan 01 00:00:00 1970 +0000
493 summary: move files
495 summary: move files
494
496
495 changeset: 3:9e8fbc4bce62
497 changeset: 3:9e8fbc4bce62
496 user: test
498 user: test
497 date: Thu Jan 01 00:00:00 1970 +0000
499 date: Thu Jan 01 00:00:00 1970 +0000
498 summary: copy files
500 summary: copy files
499
501
500 changeset: 2:51a0ae4d5864
502 changeset: 2:51a0ae4d5864
501 user: test
503 user: test
502 date: Thu Jan 01 00:00:00 1970 +0000
504 date: Thu Jan 01 00:00:00 1970 +0000
503 summary: remove files
505 summary: remove files
504
506
505 changeset: 1:ce8896473775
507 changeset: 1:ce8896473775
506 user: test
508 user: test
507 date: Thu Jan 01 00:00:00 1970 +0000
509 date: Thu Jan 01 00:00:00 1970 +0000
508 summary: edit files
510 summary: edit files
509
511
510 changeset: 0:30d30fe6a5be
512 changeset: 0:30d30fe6a5be
511 user: test
513 user: test
512 date: Thu Jan 01 00:00:00 1970 +0000
514 date: Thu Jan 01 00:00:00 1970 +0000
513 summary: add files
515 summary: add files
514
516
515 $ cat sub/large4
517 $ cat sub/large4
516 large4-modified-again
518 large4-modified-again
517
519
518 "update --check" refuses to update with uncommitted changes.
520 "update --check" refuses to update with uncommitted changes.
519 $ hg update --check 8
521 $ hg update --check 8
520 abort: uncommitted local changes
522 abort: uncommitted local changes
521 [255]
523 [255]
522
524
523 "update --clean" leaves correct largefiles in working copy.
525 "update --clean" leaves correct largefiles in working copy.
524
526
525 $ hg update --clean
527 $ hg update --clean
526 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
528 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
527 getting changed largefiles
529 getting changed largefiles
528 1 largefiles updated, 0 removed
530 1 largefiles updated, 0 removed
529 $ cat normal3
531 $ cat normal3
530 normal3-modified
532 normal3-modified
531 $ cat sub/normal4
533 $ cat sub/normal4
532 normal4-modified
534 normal4-modified
533 $ cat sub/large4
535 $ cat sub/large4
534 large4-modified
536 large4-modified
535 $ cat sub2/large6
537 $ cat sub2/large6
536 large6-modified
538 large6-modified
537 $ cat sub2/large7
539 $ cat sub2/large7
538 large7
540 large7
539
541
540 Now "update check" is happy.
542 Now "update check" is happy.
541 $ hg update --check 8
543 $ hg update --check 8
542 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
544 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
543 getting changed largefiles
545 getting changed largefiles
544 1 largefiles updated, 0 removed
546 1 largefiles updated, 0 removed
545 $ hg update --check
547 $ hg update --check
546 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
548 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
547 getting changed largefiles
549 getting changed largefiles
548 1 largefiles updated, 0 removed
550 1 largefiles updated, 0 removed
549
551
550 "revert" works on largefiles (and normal files too).
552 "revert" works on largefiles (and normal files too).
551 $ echo hack3 >> normal3
553 $ echo hack3 >> normal3
552 $ echo hack4 >> sub/normal4
554 $ echo hack4 >> sub/normal4
553 $ echo hack4 >> sub/large4
555 $ echo hack4 >> sub/large4
554 $ hg rm sub2/large6
556 $ hg rm sub2/large6
555 $ echo new >> sub2/large8
557 $ echo new >> sub2/large8
556 $ hg add --large sub2/large8
558 $ hg add --large sub2/large8
557 # XXX we don't really want to report that we're reverting the standin;
559 # XXX we don't really want to report that we're reverting the standin;
558 # that's just an implementation detail. But I don't see an obvious fix. ;-(
560 # that's just an implementation detail. But I don't see an obvious fix. ;-(
559 $ hg revert sub
561 $ hg revert sub
560 reverting .hglf/sub/large4 (glob)
562 reverting .hglf/sub/large4 (glob)
561 reverting sub/normal4 (glob)
563 reverting sub/normal4 (glob)
562 $ hg status
564 $ hg status
563 M normal3
565 M normal3
564 A sub2/large8
566 A sub2/large8
565 R sub2/large6
567 R sub2/large6
566 ? sub/large4.orig
568 ? sub/large4.orig
567 ? sub/normal4.orig
569 ? sub/normal4.orig
568 $ cat sub/normal4
570 $ cat sub/normal4
569 normal4-modified
571 normal4-modified
570 $ cat sub/large4
572 $ cat sub/large4
571 large4-modified
573 large4-modified
572 $ hg revert -a --no-backup
574 $ hg revert -a --no-backup
573 undeleting .hglf/sub2/large6 (glob)
575 undeleting .hglf/sub2/large6 (glob)
574 forgetting .hglf/sub2/large8 (glob)
576 forgetting .hglf/sub2/large8 (glob)
575 reverting normal3
577 reverting normal3
576 $ hg status
578 $ hg status
577 ? sub/large4.orig
579 ? sub/large4.orig
578 ? sub/normal4.orig
580 ? sub/normal4.orig
579 ? sub2/large8
581 ? sub2/large8
580 $ cat normal3
582 $ cat normal3
581 normal3-modified
583 normal3-modified
582 $ cat sub2/large6
584 $ cat sub2/large6
583 large6-modified
585 large6-modified
584 $ rm sub/*.orig sub2/large8
586 $ rm sub/*.orig sub2/large8
585
587
586 revert some files to an older revision
588 revert some files to an older revision
587 $ hg revert --no-backup -r 8 sub2
589 $ hg revert --no-backup -r 8 sub2
588 reverting .hglf/sub2/large6 (glob)
590 reverting .hglf/sub2/large6 (glob)
589 $ cat sub2/large6
591 $ cat sub2/large6
590 large6
592 large6
591 $ hg revert --no-backup sub2
593 $ hg revert --no-backup sub2
592 reverting .hglf/sub2/large6 (glob)
594 reverting .hglf/sub2/large6 (glob)
593 $ hg status
595 $ hg status
594
596
595 "verify --large" actually verifies largefiles
597 "verify --large" actually verifies largefiles
596
598
597 $ hg verify --large
599 $ hg verify --large
598 checking changesets
600 checking changesets
599 checking manifests
601 checking manifests
600 crosschecking files in changesets and manifests
602 crosschecking files in changesets and manifests
601 checking files
603 checking files
602 10 files, 10 changesets, 28 total revisions
604 10 files, 10 changesets, 28 total revisions
603 searching 1 changesets for largefiles
605 searching 1 changesets for largefiles
604 verified existence of 3 revisions of 3 largefiles
606 verified existence of 3 revisions of 3 largefiles
605
607
606 Merging does not revert to old versions of largefiles (this has also
608 Merging does not revert to old versions of largefiles (this has also
607 been very problematic).
609 been very problematic).
608
610
609 $ cd ..
611 $ cd ..
610 $ hg clone -r 7 e f
612 $ hg clone -r 7 e f
611 adding changesets
613 adding changesets
612 adding manifests
614 adding manifests
613 adding file changes
615 adding file changes
614 added 8 changesets with 24 changes to 10 files
616 added 8 changesets with 24 changes to 10 files
615 updating to branch default
617 updating to branch default
616 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
618 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
617 getting changed largefiles
619 getting changed largefiles
618 3 largefiles updated, 0 removed
620 3 largefiles updated, 0 removed
619 $ cd f
621 $ cd f
620 $ echo "large4-merge-test" > sub/large4
622 $ echo "large4-merge-test" > sub/large4
621 $ hg commit -m "Modify large4 to test merge"
623 $ hg commit -m "Modify large4 to test merge"
622 $ hg pull ../e
624 $ hg pull ../e
623 pulling from ../e
625 pulling from ../e
624 searching for changes
626 searching for changes
625 adding changesets
627 adding changesets
626 adding manifests
628 adding manifests
627 adding file changes
629 adding file changes
628 added 2 changesets with 4 changes to 4 files (+1 heads)
630 added 2 changesets with 4 changes to 4 files (+1 heads)
629 (run 'hg heads' to see heads, 'hg merge' to merge)
631 (run 'hg heads' to see heads, 'hg merge' to merge)
630 $ hg merge
632 $ hg merge
631 merging sub/large4
633 merging sub/large4
632 largefile sub/large4 has a merge conflict
634 largefile sub/large4 has a merge conflict
633 keep (l)ocal or take (o)ther? l
635 keep (l)ocal or take (o)ther? l
634 3 files updated, 1 files merged, 0 files removed, 0 files unresolved
636 3 files updated, 1 files merged, 0 files removed, 0 files unresolved
635 (branch merge, don't forget to commit)
637 (branch merge, don't forget to commit)
636 getting changed largefiles
638 getting changed largefiles
637 1 largefiles updated, 0 removed
639 1 largefiles updated, 0 removed
638 $ hg commit -m "Merge repos e and f"
640 $ hg commit -m "Merge repos e and f"
639 $ cat normal3
641 $ cat normal3
640 normal3-modified
642 normal3-modified
641 $ cat sub/normal4
643 $ cat sub/normal4
642 normal4-modified
644 normal4-modified
643 $ cat sub/large4
645 $ cat sub/large4
644 large4-merge-test
646 large4-merge-test
645 $ cat sub2/large6
647 $ cat sub2/large6
646 large6-modified
648 large6-modified
647 $ cat sub2/large7
649 $ cat sub2/large7
648 large7
650 large7
649
651
650 Test status after merging with a branch that introduces a new largefile:
652 Test status after merging with a branch that introduces a new largefile:
651
653
652 $ echo large > large
654 $ echo large > large
653 $ hg add --large large
655 $ hg add --large large
654 $ hg commit -m 'add largefile'
656 $ hg commit -m 'add largefile'
655 $ hg update -q ".^"
657 $ hg update -q ".^"
656 $ echo change >> normal3
658 $ echo change >> normal3
657 $ hg commit -m 'some change'
659 $ hg commit -m 'some change'
658 created new head
660 created new head
659 $ hg merge
661 $ hg merge
660 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
662 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
661 (branch merge, don't forget to commit)
663 (branch merge, don't forget to commit)
662 getting changed largefiles
664 getting changed largefiles
663 1 largefiles updated, 0 removed
665 1 largefiles updated, 0 removed
664 $ hg status
666 $ hg status
665 M large
667 M large
666
668
667 Test that a normal file and a largefile with the same name and path cannot
669 Test that a normal file and a largefile with the same name and path cannot
668 coexist.
670 coexist.
669
671
670 $ rm sub2/large7
672 $ rm sub2/large7
671 $ echo "largeasnormal" > sub2/large7
673 $ echo "largeasnormal" > sub2/large7
672 $ hg add sub2/large7
674 $ hg add sub2/large7
673 sub2/large7 already a largefile
675 sub2/large7 already a largefile
674
676
675 Test that transplanting a largefile change works correctly.
677 Test that transplanting a largefile change works correctly.
676
678
677 $ cd ..
679 $ cd ..
678 $ hg clone -r 8 d g
680 $ hg clone -r 8 d g
679 adding changesets
681 adding changesets
680 adding manifests
682 adding manifests
681 adding file changes
683 adding file changes
682 added 9 changesets with 26 changes to 10 files
684 added 9 changesets with 26 changes to 10 files
683 updating to branch default
685 updating to branch default
684 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
686 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
685 getting changed largefiles
687 getting changed largefiles
686 3 largefiles updated, 0 removed
688 3 largefiles updated, 0 removed
687 $ cd g
689 $ cd g
688 $ hg transplant -s ../d 598410d3eb9a
690 $ hg transplant -s ../d 598410d3eb9a
689 searching for changes
691 searching for changes
690 searching for changes
692 searching for changes
691 adding changesets
693 adding changesets
692 adding manifests
694 adding manifests
693 adding file changes
695 adding file changes
694 added 1 changesets with 2 changes to 2 files
696 added 1 changesets with 2 changes to 2 files
695 getting changed largefiles
697 getting changed largefiles
696 1 largefiles updated, 0 removed
698 1 largefiles updated, 0 removed
697 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
699 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
698 9:598410d3eb9a modify normal file largefile in repo d
700 9:598410d3eb9a modify normal file largefile in repo d
699 8:a381d2c8c80e modify normal file and largefile in repo b
701 8:a381d2c8c80e modify normal file and largefile in repo b
700 7:daea875e9014 add/edit more largefiles
702 7:daea875e9014 add/edit more largefiles
701 6:4355d653f84f edit files yet again
703 6:4355d653f84f edit files yet again
702 5:9d5af5072dbd edit files again
704 5:9d5af5072dbd edit files again
703 4:74c02385b94c move files
705 4:74c02385b94c move files
704 3:9e8fbc4bce62 copy files
706 3:9e8fbc4bce62 copy files
705 2:51a0ae4d5864 remove files
707 2:51a0ae4d5864 remove files
706 1:ce8896473775 edit files
708 1:ce8896473775 edit files
707 0:30d30fe6a5be add files
709 0:30d30fe6a5be add files
708 $ cat normal3
710 $ cat normal3
709 normal3-modified
711 normal3-modified
710 $ cat sub/normal4
712 $ cat sub/normal4
711 normal4-modified
713 normal4-modified
712 $ cat sub/large4
714 $ cat sub/large4
713 large4-modified
715 large4-modified
714 $ cat sub2/large6
716 $ cat sub2/large6
715 large6-modified
717 large6-modified
716 $ cat sub2/large7
718 $ cat sub2/large7
717 large7
719 large7
718
720
719 Test that renaming a largefile results in correct output for status
721 Test that renaming a largefile results in correct output for status
720
722
721 $ hg rename sub/large4 large4-renamed
723 $ hg rename sub/large4 large4-renamed
722 $ hg st
724 $ hg st
723 A large4-renamed
725 A large4-renamed
724 R sub/large4
726 R sub/large4
725 $ hg commit -m "test rename output"
727 $ hg commit -m "test rename output"
726 $ cat large4-renamed
728 $ cat large4-renamed
727 large4-modified
729 large4-modified
728 $ cd sub2
730 $ cd sub2
729 $ hg rename large6 large6-renamed
731 $ hg rename large6 large6-renamed
730 $ hg st
732 $ hg st
731 A sub2/large6-renamed
733 A sub2/large6-renamed
732 R sub2/large6
734 R sub2/large6
733 $ cd ../..
735 $ cd ../..
734
736
735 vanilla clients not locked out from largefiles servers on vanilla repos
737 vanilla clients not locked out from largefiles servers on vanilla repos
736 $ mkdir r1
738 $ mkdir r1
737 $ cd r1
739 $ cd r1
738 $ hg init
740 $ hg init
739 $ echo c1 > f1
741 $ echo c1 > f1
740 $ hg add f1
742 $ hg add f1
741 $ hg com -m "m1"
743 $ hg com -m "m1"
742 $ cd ..
744 $ cd ..
743 $ hg serve -R r1 -d -p $HGPORT --pid-file hg.pid
745 $ hg serve -R r1 -d -p $HGPORT --pid-file hg.pid
744 $ cat hg.pid >> $DAEMON_PIDS
746 $ cat hg.pid >> $DAEMON_PIDS
745 $ hg --config extensions.largefiles=! clone http://localhost:$HGPORT r2
747 $ hg --config extensions.largefiles=! clone http://localhost:$HGPORT r2
746 requesting all changes
748 requesting all changes
747 adding changesets
749 adding changesets
748 adding manifests
750 adding manifests
749 adding file changes
751 adding file changes
750 added 1 changesets with 1 changes to 1 files
752 added 1 changesets with 1 changes to 1 files
751 updating to branch default
753 updating to branch default
752 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
754 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
753
755
754 largefiles clients still work with vanilla servers
756 largefiles clients still work with vanilla servers
755 $ hg --config extensions.largefiles=! serve -R r1 -d -p $HGPORT1 --pid-file hg.pid
757 $ hg --config extensions.largefiles=! serve -R r1 -d -p $HGPORT1 --pid-file hg.pid
756 $ cat hg.pid >> $DAEMON_PIDS
758 $ cat hg.pid >> $DAEMON_PIDS
757 $ hg clone http://localhost:$HGPORT1 r3
759 $ hg clone http://localhost:$HGPORT1 r3
758 requesting all changes
760 requesting all changes
759 adding changesets
761 adding changesets
760 adding manifests
762 adding manifests
761 adding file changes
763 adding file changes
762 added 1 changesets with 1 changes to 1 files
764 added 1 changesets with 1 changes to 1 files
763 updating to branch default
765 updating to branch default
764 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
766 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
765
767
766 vanilla clients locked out from largefiles http repos
768 vanilla clients locked out from largefiles http repos
767 $ mkdir r4
769 $ mkdir r4
768 $ cd r4
770 $ cd r4
769 $ hg init
771 $ hg init
770 $ echo c1 > f1
772 $ echo c1 > f1
771 $ hg add --large f1
773 $ hg add --large f1
772 $ hg com -m "m1"
774 $ hg com -m "m1"
773 $ cd ..
775 $ cd ..
774 $ hg serve -R r4 -d -p $HGPORT2 --pid-file hg.pid
776 $ hg serve -R r4 -d -p $HGPORT2 --pid-file hg.pid
775 $ cat hg.pid >> $DAEMON_PIDS
777 $ cat hg.pid >> $DAEMON_PIDS
776 $ hg --config extensions.largefiles=! clone http://localhost:$HGPORT2 r5
778 $ hg --config extensions.largefiles=! clone http://localhost:$HGPORT2 r5
777 abort: remote error:
779 abort: remote error:
778
780
779 This repository uses the largefiles extension.
781 This repository uses the largefiles extension.
780
782
781 Please enable it in your Mercurial config file.
783 Please enable it in your Mercurial config file.
782 [255]
784 [255]
783
785
784 used all HGPORTs, kill all daemons
786 used all HGPORTs, kill all daemons
785 $ "$TESTDIR/killdaemons.py"
787 $ "$TESTDIR/killdaemons.py"
786
788
787 vanilla clients locked out from largefiles ssh repos
789 vanilla clients locked out from largefiles ssh repos
788 $ hg --config extensions.largefiles=! clone -e "python $TESTDIR/dummyssh" ssh://user@dummy/r4 r5
790 $ hg --config extensions.largefiles=! clone -e "python $TESTDIR/dummyssh" ssh://user@dummy/r4 r5
789 abort: remote error:
791 abort: remote error:
790
792
791 This repository uses the largefiles extension.
793 This repository uses the largefiles extension.
792
794
793 Please enable it in your Mercurial config file.
795 Please enable it in your Mercurial config file.
794 [255]
796 [255]
795
797
796 largefiles clients refuse to push largefiles repos to vanilla servers
798 largefiles clients refuse to push largefiles repos to vanilla servers
797 $ mkdir r6
799 $ mkdir r6
798 $ cd r6
800 $ cd r6
799 $ hg init
801 $ hg init
800 $ echo c1 > f1
802 $ echo c1 > f1
801 $ hg add f1
803 $ hg add f1
802 $ hg com -m "m1"
804 $ hg com -m "m1"
803 $ cat >> .hg/hgrc <<!
805 $ cat >> .hg/hgrc <<!
804 > [web]
806 > [web]
805 > push_ssl = false
807 > push_ssl = false
806 > allow_push = *
808 > allow_push = *
807 > !
809 > !
808 $ cd ..
810 $ cd ..
809 $ hg clone r6 r7
811 $ hg clone r6 r7
810 updating to branch default
812 updating to branch default
811 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
813 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
812 $ cd r7
814 $ cd r7
813 $ echo c2 > f2
815 $ echo c2 > f2
814 $ hg add --large f2
816 $ hg add --large f2
815 $ hg com -m "m2"
817 $ hg com -m "m2"
816 $ hg --config extensions.largefiles=! -R ../r6 serve -d -p $HGPORT --pid-file ../hg.pid
818 $ hg --config extensions.largefiles=! -R ../r6 serve -d -p $HGPORT --pid-file ../hg.pid
817 $ cat ../hg.pid >> $DAEMON_PIDS
819 $ cat ../hg.pid >> $DAEMON_PIDS
818 $ hg push http://localhost:$HGPORT
820 $ hg push http://localhost:$HGPORT
819 pushing to http://localhost:$HGPORT/
821 pushing to http://localhost:$HGPORT/
820 searching for changes
822 searching for changes
821 abort: http://localhost:$HGPORT/ does not appear to be a largefile store
823 abort: http://localhost:$HGPORT/ does not appear to be a largefile store
822 [255]
824 [255]
823 $ cd ..
825 $ cd ..
824
826
825 Clone a local repository owned by another user
827 Clone a local repository owned by another user
826 We have to simulate that here by setting $HOME and removing write permissions
828 We have to simulate that here by setting $HOME and removing write permissions
827 $ ORIGHOME="$HOME"
829 $ ORIGHOME="$HOME"
828 $ mkdir alice
830 $ mkdir alice
829 $ HOME="`pwd`/alice"
831 $ HOME="`pwd`/alice"
830 $ cd alice
832 $ cd alice
831 $ hg init pubrepo
833 $ hg init pubrepo
832 $ cd pubrepo
834 $ cd pubrepo
833 $ dd if=/dev/urandom bs=1k count=11k > a-large-file 2> /dev/null
835 $ dd if=/dev/urandom bs=1k count=11k > a-large-file 2> /dev/null
834 $ hg add --large a-large-file
836 $ hg add --large a-large-file
835 $ hg commit -m "Add a large file"
837 $ hg commit -m "Add a large file"
836 $ cd ..
838 $ cd ..
837 $ chmod -R a-w pubrepo
839 $ chmod -R a-w pubrepo
838 $ cd ..
840 $ cd ..
839 $ mkdir bob
841 $ mkdir bob
840 $ HOME="`pwd`/bob"
842 $ HOME="`pwd`/bob"
841 $ cd bob
843 $ cd bob
842 $ hg clone --pull ../alice/pubrepo pubrepo
844 $ hg clone --pull ../alice/pubrepo pubrepo
843 requesting all changes
845 requesting all changes
844 adding changesets
846 adding changesets
845 adding manifests
847 adding manifests
846 adding file changes
848 adding file changes
847 added 1 changesets with 1 changes to 1 files
849 added 1 changesets with 1 changes to 1 files
848 updating to branch default
850 updating to branch default
849 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
851 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
850 getting changed largefiles
852 getting changed largefiles
851 1 largefiles updated, 0 removed
853 1 largefiles updated, 0 removed
852 $ cd ..
854 $ cd ..
853 $ chmod -R u+w alice/pubrepo
855 $ chmod -R u+w alice/pubrepo
854 $ HOME="$ORIGHOME"
856 $ HOME="$ORIGHOME"
855
857
856 Symlink to a large largefile should behave the same as a symlink to a normal file
858 Symlink to a large largefile should behave the same as a symlink to a normal file
857 $ hg init largesymlink
859 $ hg init largesymlink
858 $ cd largesymlink
860 $ cd largesymlink
859 $ dd if=/dev/zero bs=1k count=10k of=largefile 2>/dev/null
861 $ dd if=/dev/zero bs=1k count=10k of=largefile 2>/dev/null
860 $ hg add --large largefile
862 $ hg add --large largefile
861 $ hg commit -m "commit a large file"
863 $ hg commit -m "commit a large file"
862 $ ln -s largefile largelink
864 $ ln -s largefile largelink
863 $ hg add largelink
865 $ hg add largelink
864 $ hg commit -m "commit a large symlink"
866 $ hg commit -m "commit a large symlink"
865 $ rm -f largelink
867 $ rm -f largelink
866 $ hg up >/dev/null
868 $ hg up >/dev/null
867 $ test -f largelink
869 $ test -f largelink
868 [1]
870 [1]
869 $ test -L largelink
871 $ test -L largelink
870 [1]
872 [1]
871 $ rm -f largelink # make next part of the test independent of the previous
873 $ rm -f largelink # make next part of the test independent of the previous
872 $ hg up -C >/dev/null
874 $ hg up -C >/dev/null
873 $ test -f largelink
875 $ test -f largelink
874 $ test -L largelink
876 $ test -L largelink
875 $ cd ..
877 $ cd ..
876
878
877
879
@@ -1,148 +1,151 b''
1 $ cat >> $HGRCPATH <<EOF
1 $ cat >> $HGRCPATH <<EOF
2 > [extensions]
2 > [extensions]
3 > graphlog=
3 > graphlog=
4 > rebase=
4 > rebase=
5 >
5 >
6 > [phases]
7 > publish=False
8 >
6 > [alias]
9 > [alias]
7 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
10 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
8 > EOF
11 > EOF
9
12
10
13
11 $ hg init a
14 $ hg init a
12 $ cd a
15 $ cd a
13
16
14 $ echo c1 > common
17 $ echo c1 > common
15 $ hg add common
18 $ hg add common
16 $ hg ci -m C1
19 $ hg ci -m C1
17
20
18 $ echo c2 >> common
21 $ echo c2 >> common
19 $ hg ci -m C2
22 $ hg ci -m C2
20
23
21 $ echo c3 >> common
24 $ echo c3 >> common
22 $ hg ci -m C3
25 $ hg ci -m C3
23
26
24 $ hg up -q -C 1
27 $ hg up -q -C 1
25
28
26 $ echo l1 >> extra
29 $ echo l1 >> extra
27 $ hg add extra
30 $ hg add extra
28 $ hg ci -m L1
31 $ hg ci -m L1
29 created new head
32 created new head
30
33
31 $ sed -e 's/c2/l2/' common > common.new
34 $ sed -e 's/c2/l2/' common > common.new
32 $ mv common.new common
35 $ mv common.new common
33 $ hg ci -m L2
36 $ hg ci -m L2
34
37
35 $ hg tglog
38 $ hg tglog
36 @ 4: 'L2'
39 @ 4: 'L2'
37 |
40 |
38 o 3: 'L1'
41 o 3: 'L1'
39 |
42 |
40 | o 2: 'C3'
43 | o 2: 'C3'
41 |/
44 |/
42 o 1: 'C2'
45 o 1: 'C2'
43 |
46 |
44 o 0: 'C1'
47 o 0: 'C1'
45
48
46
49
47 Conflicting rebase:
50 Conflicting rebase:
48
51
49 $ hg rebase -s 3 -d 2
52 $ hg rebase -s 3 -d 2
50 merging common
53 merging common
51 warning: conflicts during merge.
54 warning: conflicts during merge.
52 merging common incomplete! (edit conflicts, then use 'hg resolve --mark')
55 merging common incomplete! (edit conflicts, then use 'hg resolve --mark')
53 abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
56 abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
54 [255]
57 [255]
55
58
56 Abort:
59 Abort:
57
60
58 $ hg rebase --abort
61 $ hg rebase --abort
59 saved backup bundle to $TESTTMP/a/.hg/strip-backup/*-backup.hg (glob)
62 saved backup bundle to $TESTTMP/a/.hg/strip-backup/*-backup.hg (glob)
60 rebase aborted
63 rebase aborted
61
64
62 $ hg tglog
65 $ hg tglog
63 @ 4: 'L2'
66 @ 4: 'L2'
64 |
67 |
65 o 3: 'L1'
68 o 3: 'L1'
66 |
69 |
67 | o 2: 'C3'
70 | o 2: 'C3'
68 |/
71 |/
69 o 1: 'C2'
72 o 1: 'C2'
70 |
73 |
71 o 0: 'C1'
74 o 0: 'C1'
72
75
73 $ cd ..
76 $ cd ..
74
77
75
78
76 Constrcut new repo:
79 Constrcut new repo:
77
80
78 $ hg init b
81 $ hg init b
79 $ cd b
82 $ cd b
80
83
81 $ echo a > a
84 $ echo a > a
82 $ hg ci -Am A
85 $ hg ci -Am A
83 adding a
86 adding a
84
87
85 $ echo b > b
88 $ echo b > b
86 $ hg ci -Am B
89 $ hg ci -Am B
87 adding b
90 adding b
88
91
89 $ echo c > c
92 $ echo c > c
90 $ hg ci -Am C
93 $ hg ci -Am C
91 adding c
94 adding c
92
95
93 $ hg up -q 0
96 $ hg up -q 0
94
97
95 $ echo b > b
98 $ echo b > b
96 $ hg ci -Am 'B bis'
99 $ hg ci -Am 'B bis'
97 adding b
100 adding b
98 created new head
101 created new head
99
102
100 $ echo c1 > c
103 $ echo c1 > c
101 $ hg ci -Am C1
104 $ hg ci -Am C1
102 adding c
105 adding c
103
106
104 Rebase and abort without generating new changesets:
107 Rebase and abort without generating new changesets:
105
108
106 $ hg tglog
109 $ hg tglog
107 @ 4: 'C1'
110 @ 4: 'C1'
108 |
111 |
109 o 3: 'B bis'
112 o 3: 'B bis'
110 |
113 |
111 | o 2: 'C'
114 | o 2: 'C'
112 | |
115 | |
113 | o 1: 'B'
116 | o 1: 'B'
114 |/
117 |/
115 o 0: 'A'
118 o 0: 'A'
116
119
117 $ hg rebase -b 4 -d 2
120 $ hg rebase -b 4 -d 2
118 merging c
121 merging c
119 warning: conflicts during merge.
122 warning: conflicts during merge.
120 merging c incomplete! (edit conflicts, then use 'hg resolve --mark')
123 merging c incomplete! (edit conflicts, then use 'hg resolve --mark')
121 abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
124 abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
122 [255]
125 [255]
123
126
124 $ hg tglog
127 $ hg tglog
125 @ 4: 'C1'
128 @ 4: 'C1'
126 |
129 |
127 o 3: 'B bis'
130 o 3: 'B bis'
128 |
131 |
129 | @ 2: 'C'
132 | @ 2: 'C'
130 | |
133 | |
131 | o 1: 'B'
134 | o 1: 'B'
132 |/
135 |/
133 o 0: 'A'
136 o 0: 'A'
134
137
135 $ hg rebase -a
138 $ hg rebase -a
136 rebase aborted
139 rebase aborted
137
140
138 $ hg tglog
141 $ hg tglog
139 @ 4: 'C1'
142 @ 4: 'C1'
140 |
143 |
141 o 3: 'B bis'
144 o 3: 'B bis'
142 |
145 |
143 | o 2: 'C'
146 | o 2: 'C'
144 | |
147 | |
145 | o 1: 'B'
148 | o 1: 'B'
146 |/
149 |/
147 o 0: 'A'
150 o 0: 'A'
148
151
@@ -1,85 +1,88 b''
1 $ cat >> $HGRCPATH <<EOF
1 $ cat >> $HGRCPATH <<EOF
2 > [extensions]
2 > [extensions]
3 > graphlog=
3 > graphlog=
4 > rebase=
4 > rebase=
5 >
5 >
6 > [phases]
7 > publish=False
8 >
6 > [alias]
9 > [alias]
7 > tglog = log -G --template "{rev}: '{desc}' bookmarks: {bookmarks}\n"
10 > tglog = log -G --template "{rev}: '{desc}' bookmarks: {bookmarks}\n"
8 > EOF
11 > EOF
9
12
10 Create a repo with several bookmarks
13 Create a repo with several bookmarks
11 $ hg init a
14 $ hg init a
12 $ cd a
15 $ cd a
13
16
14 $ echo a > a
17 $ echo a > a
15 $ hg ci -Am A
18 $ hg ci -Am A
16 adding a
19 adding a
17
20
18 $ echo b > b
21 $ echo b > b
19 $ hg ci -Am B
22 $ hg ci -Am B
20 adding b
23 adding b
21 $ hg book 'X'
24 $ hg book 'X'
22 $ hg book 'Y'
25 $ hg book 'Y'
23
26
24 $ echo c > c
27 $ echo c > c
25 $ hg ci -Am C
28 $ hg ci -Am C
26 adding c
29 adding c
27 $ hg book 'Z'
30 $ hg book 'Z'
28
31
29 $ hg up -q 0
32 $ hg up -q 0
30
33
31 $ echo d > d
34 $ echo d > d
32 $ hg ci -Am D
35 $ hg ci -Am D
33 adding d
36 adding d
34 created new head
37 created new head
35
38
36 $ hg tglog
39 $ hg tglog
37 @ 3: 'D' bookmarks:
40 @ 3: 'D' bookmarks:
38 |
41 |
39 | o 2: 'C' bookmarks: Y Z
42 | o 2: 'C' bookmarks: Y Z
40 | |
43 | |
41 | o 1: 'B' bookmarks: X
44 | o 1: 'B' bookmarks: X
42 |/
45 |/
43 o 0: 'A' bookmarks:
46 o 0: 'A' bookmarks:
44
47
45
48
46 Move only rebased bookmarks
49 Move only rebased bookmarks
47
50
48 $ cd ..
51 $ cd ..
49 $ hg clone -q a a1
52 $ hg clone -q a a1
50
53
51 $ cd a1
54 $ cd a1
52 $ hg up -q Z
55 $ hg up -q Z
53
56
54 $ hg rebase --detach -s Y -d 3
57 $ hg rebase --detach -s Y -d 3
55 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
58 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
56
59
57 $ hg tglog
60 $ hg tglog
58 @ 3: 'C' bookmarks: Y Z
61 @ 3: 'C' bookmarks: Y Z
59 |
62 |
60 o 2: 'D' bookmarks:
63 o 2: 'D' bookmarks:
61 |
64 |
62 | o 1: 'B' bookmarks: X
65 | o 1: 'B' bookmarks: X
63 |/
66 |/
64 o 0: 'A' bookmarks:
67 o 0: 'A' bookmarks:
65
68
66 Keep bookmarks to the correct rebased changeset
69 Keep bookmarks to the correct rebased changeset
67
70
68 $ cd ..
71 $ cd ..
69 $ hg clone -q a a2
72 $ hg clone -q a a2
70
73
71 $ cd a2
74 $ cd a2
72 $ hg up -q Z
75 $ hg up -q Z
73
76
74 $ hg rebase -s 1 -d 3
77 $ hg rebase -s 1 -d 3
75 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
78 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
76
79
77 $ hg tglog
80 $ hg tglog
78 @ 3: 'C' bookmarks: Y Z
81 @ 3: 'C' bookmarks: Y Z
79 |
82 |
80 o 2: 'B' bookmarks: X
83 o 2: 'B' bookmarks: X
81 |
84 |
82 o 1: 'D' bookmarks:
85 o 1: 'D' bookmarks:
83 |
86 |
84 o 0: 'A' bookmarks:
87 o 0: 'A' bookmarks:
85
88
@@ -1,261 +1,264 b''
1 $ cat >> $HGRCPATH <<EOF
1 $ cat >> $HGRCPATH <<EOF
2 > [extensions]
2 > [extensions]
3 > graphlog=
3 > graphlog=
4 > rebase=
4 > rebase=
5 >
5 >
6 > [phases]
7 > publish=False
8 >
6 > [alias]
9 > [alias]
7 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
10 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
8 > theads = heads --template "{rev}: '{desc}' {branches}\n"
11 > theads = heads --template "{rev}: '{desc}' {branches}\n"
9 > EOF
12 > EOF
10
13
11 $ hg init a
14 $ hg init a
12 $ cd a
15 $ cd a
13
16
14 $ echo a > a
17 $ echo a > a
15 $ hg ci -Am A
18 $ hg ci -Am A
16 adding a
19 adding a
17
20
18 $ hg branch branch1
21 $ hg branch branch1
19 marked working directory as branch branch1
22 marked working directory as branch branch1
20 (branches are permanent and global, did you want a bookmark?)
23 (branches are permanent and global, did you want a bookmark?)
21 $ hg ci -m 'branch1'
24 $ hg ci -m 'branch1'
22
25
23 $ echo b > b
26 $ echo b > b
24 $ hg ci -Am B
27 $ hg ci -Am B
25 adding b
28 adding b
26
29
27 $ hg up -q 0
30 $ hg up -q 0
28
31
29 $ hg branch branch2
32 $ hg branch branch2
30 marked working directory as branch branch2
33 marked working directory as branch branch2
31 (branches are permanent and global, did you want a bookmark?)
34 (branches are permanent and global, did you want a bookmark?)
32 $ hg ci -m 'branch2'
35 $ hg ci -m 'branch2'
33
36
34 $ echo c > C
37 $ echo c > C
35 $ hg ci -Am C
38 $ hg ci -Am C
36 adding C
39 adding C
37
40
38 $ hg up -q 2
41 $ hg up -q 2
39
42
40 $ hg branch -f branch2
43 $ hg branch -f branch2
41 marked working directory as branch branch2
44 marked working directory as branch branch2
42 (branches are permanent and global, did you want a bookmark?)
45 (branches are permanent and global, did you want a bookmark?)
43 $ echo d > d
46 $ echo d > d
44 $ hg ci -Am D
47 $ hg ci -Am D
45 adding d
48 adding d
46 created new head
49 created new head
47
50
48 $ echo e > e
51 $ echo e > e
49 $ hg ci -Am E
52 $ hg ci -Am E
50 adding e
53 adding e
51
54
52 $ hg update default
55 $ hg update default
53 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
56 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
54
57
55 $ hg branch branch3
58 $ hg branch branch3
56 marked working directory as branch branch3
59 marked working directory as branch branch3
57 (branches are permanent and global, did you want a bookmark?)
60 (branches are permanent and global, did you want a bookmark?)
58 $ hg ci -m 'branch3'
61 $ hg ci -m 'branch3'
59
62
60 $ echo f > f
63 $ echo f > f
61 $ hg ci -Am F
64 $ hg ci -Am F
62 adding f
65 adding f
63
66
64 $ cd ..
67 $ cd ..
65
68
66
69
67 Rebase part of branch2 (5-6) onto branch3 (8):
70 Rebase part of branch2 (5-6) onto branch3 (8):
68
71
69 $ hg clone -q -u . a a1
72 $ hg clone -q -u . a a1
70 $ cd a1
73 $ cd a1
71
74
72 $ hg tglog
75 $ hg tglog
73 @ 8: 'F' branch3
76 @ 8: 'F' branch3
74 |
77 |
75 o 7: 'branch3' branch3
78 o 7: 'branch3' branch3
76 |
79 |
77 | o 6: 'E' branch2
80 | o 6: 'E' branch2
78 | |
81 | |
79 | o 5: 'D' branch2
82 | o 5: 'D' branch2
80 | |
83 | |
81 | | o 4: 'C' branch2
84 | | o 4: 'C' branch2
82 | | |
85 | | |
83 +---o 3: 'branch2' branch2
86 +---o 3: 'branch2' branch2
84 | |
87 | |
85 | o 2: 'B' branch1
88 | o 2: 'B' branch1
86 | |
89 | |
87 | o 1: 'branch1' branch1
90 | o 1: 'branch1' branch1
88 |/
91 |/
89 o 0: 'A'
92 o 0: 'A'
90
93
91 $ hg branches
94 $ hg branches
92 branch3 8:4666b71e8e32
95 branch3 8:4666b71e8e32
93 branch2 6:5097051d331d
96 branch2 6:5097051d331d
94 branch1 2:0a03079c47fd (inactive)
97 branch1 2:0a03079c47fd (inactive)
95 default 0:1994f17a630e (inactive)
98 default 0:1994f17a630e (inactive)
96
99
97 $ hg theads
100 $ hg theads
98 8: 'F' branch3
101 8: 'F' branch3
99 6: 'E' branch2
102 6: 'E' branch2
100 4: 'C' branch2
103 4: 'C' branch2
101 2: 'B' branch1
104 2: 'B' branch1
102 0: 'A'
105 0: 'A'
103
106
104 $ hg rebase --detach -s 5 -d 8
107 $ hg rebase --detach -s 5 -d 8
105 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
108 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
106
109
107 $ hg branches
110 $ hg branches
108 branch3 8:466cdfb14b62
111 branch3 8:466cdfb14b62
109 branch2 4:e4fdb121d036
112 branch2 4:e4fdb121d036
110 branch1 2:0a03079c47fd
113 branch1 2:0a03079c47fd
111 default 0:1994f17a630e (inactive)
114 default 0:1994f17a630e (inactive)
112
115
113 $ hg theads
116 $ hg theads
114 8: 'E' branch3
117 8: 'E' branch3
115 4: 'C' branch2
118 4: 'C' branch2
116 2: 'B' branch1
119 2: 'B' branch1
117 0: 'A'
120 0: 'A'
118
121
119 $ hg tglog
122 $ hg tglog
120 @ 8: 'E' branch3
123 @ 8: 'E' branch3
121 |
124 |
122 o 7: 'D' branch3
125 o 7: 'D' branch3
123 |
126 |
124 o 6: 'F' branch3
127 o 6: 'F' branch3
125 |
128 |
126 o 5: 'branch3' branch3
129 o 5: 'branch3' branch3
127 |
130 |
128 | o 4: 'C' branch2
131 | o 4: 'C' branch2
129 | |
132 | |
130 | o 3: 'branch2' branch2
133 | o 3: 'branch2' branch2
131 |/
134 |/
132 | o 2: 'B' branch1
135 | o 2: 'B' branch1
133 | |
136 | |
134 | o 1: 'branch1' branch1
137 | o 1: 'branch1' branch1
135 |/
138 |/
136 o 0: 'A'
139 o 0: 'A'
137
140
138 $ cd ..
141 $ cd ..
139
142
140
143
141 Rebase head of branch3 (8) onto branch2 (6):
144 Rebase head of branch3 (8) onto branch2 (6):
142
145
143 $ hg clone -q -u . a a2
146 $ hg clone -q -u . a a2
144 $ cd a2
147 $ cd a2
145
148
146 $ hg tglog
149 $ hg tglog
147 @ 8: 'F' branch3
150 @ 8: 'F' branch3
148 |
151 |
149 o 7: 'branch3' branch3
152 o 7: 'branch3' branch3
150 |
153 |
151 | o 6: 'E' branch2
154 | o 6: 'E' branch2
152 | |
155 | |
153 | o 5: 'D' branch2
156 | o 5: 'D' branch2
154 | |
157 | |
155 | | o 4: 'C' branch2
158 | | o 4: 'C' branch2
156 | | |
159 | | |
157 +---o 3: 'branch2' branch2
160 +---o 3: 'branch2' branch2
158 | |
161 | |
159 | o 2: 'B' branch1
162 | o 2: 'B' branch1
160 | |
163 | |
161 | o 1: 'branch1' branch1
164 | o 1: 'branch1' branch1
162 |/
165 |/
163 o 0: 'A'
166 o 0: 'A'
164
167
165 $ hg rebase --detach -s 8 -d 6
168 $ hg rebase --detach -s 8 -d 6
166 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
169 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
167
170
168 $ hg branches
171 $ hg branches
169 branch2 8:6b4bdc1b5ac0
172 branch2 8:6b4bdc1b5ac0
170 branch3 7:653b9feb4616
173 branch3 7:653b9feb4616
171 branch1 2:0a03079c47fd (inactive)
174 branch1 2:0a03079c47fd (inactive)
172 default 0:1994f17a630e (inactive)
175 default 0:1994f17a630e (inactive)
173
176
174 $ hg theads
177 $ hg theads
175 8: 'F' branch2
178 8: 'F' branch2
176 7: 'branch3' branch3
179 7: 'branch3' branch3
177 4: 'C' branch2
180 4: 'C' branch2
178 2: 'B' branch1
181 2: 'B' branch1
179 0: 'A'
182 0: 'A'
180
183
181 $ hg tglog
184 $ hg tglog
182 @ 8: 'F' branch2
185 @ 8: 'F' branch2
183 |
186 |
184 | o 7: 'branch3' branch3
187 | o 7: 'branch3' branch3
185 | |
188 | |
186 o | 6: 'E' branch2
189 o | 6: 'E' branch2
187 | |
190 | |
188 o | 5: 'D' branch2
191 o | 5: 'D' branch2
189 | |
192 | |
190 | | o 4: 'C' branch2
193 | | o 4: 'C' branch2
191 | | |
194 | | |
192 | | o 3: 'branch2' branch2
195 | | o 3: 'branch2' branch2
193 | |/
196 | |/
194 o | 2: 'B' branch1
197 o | 2: 'B' branch1
195 | |
198 | |
196 o | 1: 'branch1' branch1
199 o | 1: 'branch1' branch1
197 |/
200 |/
198 o 0: 'A'
201 o 0: 'A'
199
202
200 $ hg verify -q
203 $ hg verify -q
201
204
202 $ cd ..
205 $ cd ..
203
206
204
207
205 Rebase entire branch3 (7-8) onto branch2 (6):
208 Rebase entire branch3 (7-8) onto branch2 (6):
206
209
207 $ hg clone -q -u . a a3
210 $ hg clone -q -u . a a3
208 $ cd a3
211 $ cd a3
209
212
210 $ hg tglog
213 $ hg tglog
211 @ 8: 'F' branch3
214 @ 8: 'F' branch3
212 |
215 |
213 o 7: 'branch3' branch3
216 o 7: 'branch3' branch3
214 |
217 |
215 | o 6: 'E' branch2
218 | o 6: 'E' branch2
216 | |
219 | |
217 | o 5: 'D' branch2
220 | o 5: 'D' branch2
218 | |
221 | |
219 | | o 4: 'C' branch2
222 | | o 4: 'C' branch2
220 | | |
223 | | |
221 +---o 3: 'branch2' branch2
224 +---o 3: 'branch2' branch2
222 | |
225 | |
223 | o 2: 'B' branch1
226 | o 2: 'B' branch1
224 | |
227 | |
225 | o 1: 'branch1' branch1
228 | o 1: 'branch1' branch1
226 |/
229 |/
227 o 0: 'A'
230 o 0: 'A'
228
231
229 $ hg rebase --detach -s 7 -d 6
232 $ hg rebase --detach -s 7 -d 6
230 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
233 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
231
234
232 $ hg branches
235 $ hg branches
233 branch2 7:6b4bdc1b5ac0
236 branch2 7:6b4bdc1b5ac0
234 branch1 2:0a03079c47fd (inactive)
237 branch1 2:0a03079c47fd (inactive)
235 default 0:1994f17a630e (inactive)
238 default 0:1994f17a630e (inactive)
236
239
237 $ hg theads
240 $ hg theads
238 7: 'F' branch2
241 7: 'F' branch2
239 4: 'C' branch2
242 4: 'C' branch2
240 2: 'B' branch1
243 2: 'B' branch1
241 0: 'A'
244 0: 'A'
242
245
243 $ hg tglog
246 $ hg tglog
244 @ 7: 'F' branch2
247 @ 7: 'F' branch2
245 |
248 |
246 o 6: 'E' branch2
249 o 6: 'E' branch2
247 |
250 |
248 o 5: 'D' branch2
251 o 5: 'D' branch2
249 |
252 |
250 | o 4: 'C' branch2
253 | o 4: 'C' branch2
251 | |
254 | |
252 | o 3: 'branch2' branch2
255 | o 3: 'branch2' branch2
253 | |
256 | |
254 o | 2: 'B' branch1
257 o | 2: 'B' branch1
255 | |
258 | |
256 o | 1: 'branch1' branch1
259 o | 1: 'branch1' branch1
257 |/
260 |/
258 o 0: 'A'
261 o 0: 'A'
259
262
260 $ hg verify -q
263 $ hg verify -q
261
264
@@ -1,143 +1,146 b''
1 $ cat >> $HGRCPATH <<EOF
1 $ cat >> $HGRCPATH <<EOF
2 > [extensions]
2 > [extensions]
3 > graphlog=
3 > graphlog=
4 > rebase=
4 > rebase=
5 >
5 >
6 > [phases]
7 > publish=False
8 >
6 > [alias]
9 > [alias]
7 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
10 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
8 > EOF
11 > EOF
9
12
10
13
11 $ hg init a
14 $ hg init a
12 $ cd a
15 $ cd a
13
16
14 $ echo A > A
17 $ echo A > A
15 $ hg add A
18 $ hg add A
16 $ hg ci -m A
19 $ hg ci -m A
17
20
18 $ echo 'B' > B
21 $ echo 'B' > B
19 $ hg add B
22 $ hg add B
20 $ hg ci -m B
23 $ hg ci -m B
21
24
22 $ echo C >> A
25 $ echo C >> A
23 $ hg ci -m C
26 $ hg ci -m C
24
27
25 $ hg up -q -C 0
28 $ hg up -q -C 0
26
29
27 $ echo D >> A
30 $ echo D >> A
28 $ hg ci -m D
31 $ hg ci -m D
29 created new head
32 created new head
30
33
31 $ echo E > E
34 $ echo E > E
32 $ hg add E
35 $ hg add E
33 $ hg ci -m E
36 $ hg ci -m E
34
37
35 $ hg up -q -C 0
38 $ hg up -q -C 0
36
39
37 $ hg branch 'notdefault'
40 $ hg branch 'notdefault'
38 marked working directory as branch notdefault
41 marked working directory as branch notdefault
39 (branches are permanent and global, did you want a bookmark?)
42 (branches are permanent and global, did you want a bookmark?)
40 $ echo F >> A
43 $ echo F >> A
41 $ hg ci -m F
44 $ hg ci -m F
42
45
43 $ cd ..
46 $ cd ..
44
47
45
48
46 Rebasing B onto E - check keep:
49 Rebasing B onto E - check keep:
47
50
48 $ hg clone -q -u . a a1
51 $ hg clone -q -u . a a1
49 $ cd a1
52 $ cd a1
50
53
51 $ hg tglog
54 $ hg tglog
52 @ 5: 'F' notdefault
55 @ 5: 'F' notdefault
53 |
56 |
54 | o 4: 'E'
57 | o 4: 'E'
55 | |
58 | |
56 | o 3: 'D'
59 | o 3: 'D'
57 |/
60 |/
58 | o 2: 'C'
61 | o 2: 'C'
59 | |
62 | |
60 | o 1: 'B'
63 | o 1: 'B'
61 |/
64 |/
62 o 0: 'A'
65 o 0: 'A'
63
66
64 $ hg rebase -s 1 -d 4 --keep
67 $ hg rebase -s 1 -d 4 --keep
65 merging A
68 merging A
66 warning: conflicts during merge.
69 warning: conflicts during merge.
67 merging A incomplete! (edit conflicts, then use 'hg resolve --mark')
70 merging A incomplete! (edit conflicts, then use 'hg resolve --mark')
68 abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
71 abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
69 [255]
72 [255]
70
73
71 Solve the conflict and go on:
74 Solve the conflict and go on:
72
75
73 $ echo 'conflict solved' > A
76 $ echo 'conflict solved' > A
74 $ rm A.orig
77 $ rm A.orig
75 $ hg resolve -m A
78 $ hg resolve -m A
76 $ hg rebase --continue
79 $ hg rebase --continue
77
80
78 $ hg tglog
81 $ hg tglog
79 @ 7: 'C'
82 @ 7: 'C'
80 |
83 |
81 o 6: 'B'
84 o 6: 'B'
82 |
85 |
83 | o 5: 'F' notdefault
86 | o 5: 'F' notdefault
84 | |
87 | |
85 o | 4: 'E'
88 o | 4: 'E'
86 | |
89 | |
87 o | 3: 'D'
90 o | 3: 'D'
88 |/
91 |/
89 | o 2: 'C'
92 | o 2: 'C'
90 | |
93 | |
91 | o 1: 'B'
94 | o 1: 'B'
92 |/
95 |/
93 o 0: 'A'
96 o 0: 'A'
94
97
95 $ cd ..
98 $ cd ..
96
99
97
100
98 Rebase F onto E - check keepbranches:
101 Rebase F onto E - check keepbranches:
99
102
100 $ hg clone -q -u . a a2
103 $ hg clone -q -u . a a2
101 $ cd a2
104 $ cd a2
102
105
103 $ hg tglog
106 $ hg tglog
104 @ 5: 'F' notdefault
107 @ 5: 'F' notdefault
105 |
108 |
106 | o 4: 'E'
109 | o 4: 'E'
107 | |
110 | |
108 | o 3: 'D'
111 | o 3: 'D'
109 |/
112 |/
110 | o 2: 'C'
113 | o 2: 'C'
111 | |
114 | |
112 | o 1: 'B'
115 | o 1: 'B'
113 |/
116 |/
114 o 0: 'A'
117 o 0: 'A'
115
118
116 $ hg rebase -s 5 -d 4 --keepbranches
119 $ hg rebase -s 5 -d 4 --keepbranches
117 merging A
120 merging A
118 warning: conflicts during merge.
121 warning: conflicts during merge.
119 merging A incomplete! (edit conflicts, then use 'hg resolve --mark')
122 merging A incomplete! (edit conflicts, then use 'hg resolve --mark')
120 abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
123 abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
121 [255]
124 [255]
122
125
123 Solve the conflict and go on:
126 Solve the conflict and go on:
124
127
125 $ echo 'conflict solved' > A
128 $ echo 'conflict solved' > A
126 $ rm A.orig
129 $ rm A.orig
127 $ hg resolve -m A
130 $ hg resolve -m A
128 $ hg rebase --continue
131 $ hg rebase --continue
129 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
132 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
130
133
131 $ hg tglog
134 $ hg tglog
132 @ 5: 'F' notdefault
135 @ 5: 'F' notdefault
133 |
136 |
134 o 4: 'E'
137 o 4: 'E'
135 |
138 |
136 o 3: 'D'
139 o 3: 'D'
137 |
140 |
138 | o 2: 'C'
141 | o 2: 'C'
139 | |
142 | |
140 | o 1: 'B'
143 | o 1: 'B'
141 |/
144 |/
142 o 0: 'A'
145 o 0: 'A'
143
146
@@ -1,484 +1,487 b''
1 $ cat >> $HGRCPATH <<EOF
1 $ cat >> $HGRCPATH <<EOF
2 > [extensions]
2 > [extensions]
3 > graphlog=
3 > graphlog=
4 > rebase=
4 > rebase=
5 >
5 >
6 > [phases]
7 > publish=False
8 >
6 > [alias]
9 > [alias]
7 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
10 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
8 > EOF
11 > EOF
9
12
10 Create repo a:
13 Create repo a:
11
14
12 $ hg init a
15 $ hg init a
13 $ cd a
16 $ cd a
14 $ hg unbundle $TESTDIR/bundles/rebase.hg
17 $ hg unbundle $TESTDIR/bundles/rebase.hg
15 adding changesets
18 adding changesets
16 adding manifests
19 adding manifests
17 adding file changes
20 adding file changes
18 added 8 changesets with 7 changes to 7 files (+2 heads)
21 added 8 changesets with 7 changes to 7 files (+2 heads)
19 (run 'hg heads' to see heads, 'hg merge' to merge)
22 (run 'hg heads' to see heads, 'hg merge' to merge)
20 $ hg up tip
23 $ hg up tip
21 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
24 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
22
25
23 $ hg tglog
26 $ hg tglog
24 @ 7: 'H'
27 @ 7: 'H'
25 |
28 |
26 | o 6: 'G'
29 | o 6: 'G'
27 |/|
30 |/|
28 o | 5: 'F'
31 o | 5: 'F'
29 | |
32 | |
30 | o 4: 'E'
33 | o 4: 'E'
31 |/
34 |/
32 | o 3: 'D'
35 | o 3: 'D'
33 | |
36 | |
34 | o 2: 'C'
37 | o 2: 'C'
35 | |
38 | |
36 | o 1: 'B'
39 | o 1: 'B'
37 |/
40 |/
38 o 0: 'A'
41 o 0: 'A'
39
42
40 $ cd ..
43 $ cd ..
41
44
42
45
43 Rebasing B onto H:
46 Rebasing B onto H:
44
47
45 $ hg clone -q -u 3 a a1
48 $ hg clone -q -u 3 a a1
46 $ cd a1
49 $ cd a1
47
50
48 $ hg rebase --collapse --keepbranches
51 $ hg rebase --collapse --keepbranches
49 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
52 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
50
53
51 $ hg tglog
54 $ hg tglog
52 @ 5: 'Collapsed revision
55 @ 5: 'Collapsed revision
53 | * B
56 | * B
54 | * C
57 | * C
55 | * D'
58 | * D'
56 o 4: 'H'
59 o 4: 'H'
57 |
60 |
58 | o 3: 'G'
61 | o 3: 'G'
59 |/|
62 |/|
60 o | 2: 'F'
63 o | 2: 'F'
61 | |
64 | |
62 | o 1: 'E'
65 | o 1: 'E'
63 |/
66 |/
64 o 0: 'A'
67 o 0: 'A'
65
68
66 $ hg manifest
69 $ hg manifest
67 A
70 A
68 B
71 B
69 C
72 C
70 D
73 D
71 F
74 F
72 H
75 H
73
76
74 $ cd ..
77 $ cd ..
75
78
76
79
77 Rebasing E onto H:
80 Rebasing E onto H:
78
81
79 $ hg clone -q -u . a a2
82 $ hg clone -q -u . a a2
80 $ cd a2
83 $ cd a2
81
84
82 $ hg rebase --source 4 --collapse
85 $ hg rebase --source 4 --collapse
83 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
86 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
84
87
85 $ hg tglog
88 $ hg tglog
86 @ 6: 'Collapsed revision
89 @ 6: 'Collapsed revision
87 | * E
90 | * E
88 | * G'
91 | * G'
89 o 5: 'H'
92 o 5: 'H'
90 |
93 |
91 o 4: 'F'
94 o 4: 'F'
92 |
95 |
93 | o 3: 'D'
96 | o 3: 'D'
94 | |
97 | |
95 | o 2: 'C'
98 | o 2: 'C'
96 | |
99 | |
97 | o 1: 'B'
100 | o 1: 'B'
98 |/
101 |/
99 o 0: 'A'
102 o 0: 'A'
100
103
101 $ hg manifest
104 $ hg manifest
102 A
105 A
103 E
106 E
104 F
107 F
105 H
108 H
106
109
107 $ cd ..
110 $ cd ..
108
111
109 Rebasing G onto H with custom message:
112 Rebasing G onto H with custom message:
110
113
111 $ hg clone -q -u . a a3
114 $ hg clone -q -u . a a3
112 $ cd a3
115 $ cd a3
113
116
114 $ hg rebase --base 6 -m 'custom message'
117 $ hg rebase --base 6 -m 'custom message'
115 abort: message can only be specified with collapse
118 abort: message can only be specified with collapse
116 [255]
119 [255]
117
120
118 $ hg rebase --source 4 --collapse -m 'custom message'
121 $ hg rebase --source 4 --collapse -m 'custom message'
119 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
122 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
120
123
121 $ hg tglog
124 $ hg tglog
122 @ 6: 'custom message'
125 @ 6: 'custom message'
123 |
126 |
124 o 5: 'H'
127 o 5: 'H'
125 |
128 |
126 o 4: 'F'
129 o 4: 'F'
127 |
130 |
128 | o 3: 'D'
131 | o 3: 'D'
129 | |
132 | |
130 | o 2: 'C'
133 | o 2: 'C'
131 | |
134 | |
132 | o 1: 'B'
135 | o 1: 'B'
133 |/
136 |/
134 o 0: 'A'
137 o 0: 'A'
135
138
136 $ hg manifest
139 $ hg manifest
137 A
140 A
138 E
141 E
139 F
142 F
140 H
143 H
141
144
142 $ cd ..
145 $ cd ..
143
146
144 Create repo b:
147 Create repo b:
145
148
146 $ hg init b
149 $ hg init b
147 $ cd b
150 $ cd b
148
151
149 $ echo A > A
152 $ echo A > A
150 $ hg ci -Am A
153 $ hg ci -Am A
151 adding A
154 adding A
152 $ echo B > B
155 $ echo B > B
153 $ hg ci -Am B
156 $ hg ci -Am B
154 adding B
157 adding B
155
158
156 $ hg up -q 0
159 $ hg up -q 0
157
160
158 $ echo C > C
161 $ echo C > C
159 $ hg ci -Am C
162 $ hg ci -Am C
160 adding C
163 adding C
161 created new head
164 created new head
162
165
163 $ hg merge
166 $ hg merge
164 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
167 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
165 (branch merge, don't forget to commit)
168 (branch merge, don't forget to commit)
166
169
167 $ echo D > D
170 $ echo D > D
168 $ hg ci -Am D
171 $ hg ci -Am D
169 adding D
172 adding D
170
173
171 $ hg up -q 1
174 $ hg up -q 1
172
175
173 $ echo E > E
176 $ echo E > E
174 $ hg ci -Am E
177 $ hg ci -Am E
175 adding E
178 adding E
176 created new head
179 created new head
177
180
178 $ echo F > F
181 $ echo F > F
179 $ hg ci -Am F
182 $ hg ci -Am F
180 adding F
183 adding F
181
184
182 $ hg merge
185 $ hg merge
183 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
186 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
184 (branch merge, don't forget to commit)
187 (branch merge, don't forget to commit)
185 $ hg ci -m G
188 $ hg ci -m G
186
189
187 $ hg up -q 0
190 $ hg up -q 0
188
191
189 $ echo H > H
192 $ echo H > H
190 $ hg ci -Am H
193 $ hg ci -Am H
191 adding H
194 adding H
192 created new head
195 created new head
193
196
194 $ hg tglog
197 $ hg tglog
195 @ 7: 'H'
198 @ 7: 'H'
196 |
199 |
197 | o 6: 'G'
200 | o 6: 'G'
198 | |\
201 | |\
199 | | o 5: 'F'
202 | | o 5: 'F'
200 | | |
203 | | |
201 | | o 4: 'E'
204 | | o 4: 'E'
202 | | |
205 | | |
203 | o | 3: 'D'
206 | o | 3: 'D'
204 | |\|
207 | |\|
205 | o | 2: 'C'
208 | o | 2: 'C'
206 |/ /
209 |/ /
207 | o 1: 'B'
210 | o 1: 'B'
208 |/
211 |/
209 o 0: 'A'
212 o 0: 'A'
210
213
211 $ cd ..
214 $ cd ..
212
215
213
216
214 Rebase and collapse - more than one external (fail):
217 Rebase and collapse - more than one external (fail):
215
218
216 $ hg clone -q -u . b b1
219 $ hg clone -q -u . b b1
217 $ cd b1
220 $ cd b1
218
221
219 $ hg rebase -s 2 --collapse
222 $ hg rebase -s 2 --collapse
220 abort: unable to collapse, there is more than one external parent
223 abort: unable to collapse, there is more than one external parent
221 [255]
224 [255]
222
225
223 Rebase and collapse - E onto H:
226 Rebase and collapse - E onto H:
224
227
225 $ hg rebase -s 4 --collapse
228 $ hg rebase -s 4 --collapse
226 saved backup bundle to $TESTTMP/b1/.hg/strip-backup/*-backup.hg (glob)
229 saved backup bundle to $TESTTMP/b1/.hg/strip-backup/*-backup.hg (glob)
227
230
228 $ hg tglog
231 $ hg tglog
229 @ 5: 'Collapsed revision
232 @ 5: 'Collapsed revision
230 |\ * E
233 |\ * E
231 | | * F
234 | | * F
232 | | * G'
235 | | * G'
233 | o 4: 'H'
236 | o 4: 'H'
234 | |
237 | |
235 o | 3: 'D'
238 o | 3: 'D'
236 |\ \
239 |\ \
237 | o | 2: 'C'
240 | o | 2: 'C'
238 | |/
241 | |/
239 o / 1: 'B'
242 o / 1: 'B'
240 |/
243 |/
241 o 0: 'A'
244 o 0: 'A'
242
245
243 $ hg manifest
246 $ hg manifest
244 A
247 A
245 B
248 B
246 C
249 C
247 D
250 D
248 E
251 E
249 F
252 F
250 H
253 H
251
254
252 $ cd ..
255 $ cd ..
253
256
254
257
255 Create repo c:
258 Create repo c:
256
259
257 $ hg init c
260 $ hg init c
258 $ cd c
261 $ cd c
259
262
260 $ echo A > A
263 $ echo A > A
261 $ hg ci -Am A
264 $ hg ci -Am A
262 adding A
265 adding A
263 $ echo B > B
266 $ echo B > B
264 $ hg ci -Am B
267 $ hg ci -Am B
265 adding B
268 adding B
266
269
267 $ hg up -q 0
270 $ hg up -q 0
268
271
269 $ echo C > C
272 $ echo C > C
270 $ hg ci -Am C
273 $ hg ci -Am C
271 adding C
274 adding C
272 created new head
275 created new head
273
276
274 $ hg merge
277 $ hg merge
275 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
278 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
276 (branch merge, don't forget to commit)
279 (branch merge, don't forget to commit)
277
280
278 $ echo D > D
281 $ echo D > D
279 $ hg ci -Am D
282 $ hg ci -Am D
280 adding D
283 adding D
281
284
282 $ hg up -q 1
285 $ hg up -q 1
283
286
284 $ echo E > E
287 $ echo E > E
285 $ hg ci -Am E
288 $ hg ci -Am E
286 adding E
289 adding E
287 created new head
290 created new head
288 $ echo F > E
291 $ echo F > E
289 $ hg ci -m 'F'
292 $ hg ci -m 'F'
290
293
291 $ echo G > G
294 $ echo G > G
292 $ hg ci -Am G
295 $ hg ci -Am G
293 adding G
296 adding G
294
297
295 $ hg merge
298 $ hg merge
296 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
299 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
297 (branch merge, don't forget to commit)
300 (branch merge, don't forget to commit)
298
301
299 $ hg ci -m H
302 $ hg ci -m H
300
303
301 $ hg up -q 0
304 $ hg up -q 0
302
305
303 $ echo I > I
306 $ echo I > I
304 $ hg ci -Am I
307 $ hg ci -Am I
305 adding I
308 adding I
306 created new head
309 created new head
307
310
308 $ hg tglog
311 $ hg tglog
309 @ 8: 'I'
312 @ 8: 'I'
310 |
313 |
311 | o 7: 'H'
314 | o 7: 'H'
312 | |\
315 | |\
313 | | o 6: 'G'
316 | | o 6: 'G'
314 | | |
317 | | |
315 | | o 5: 'F'
318 | | o 5: 'F'
316 | | |
319 | | |
317 | | o 4: 'E'
320 | | o 4: 'E'
318 | | |
321 | | |
319 | o | 3: 'D'
322 | o | 3: 'D'
320 | |\|
323 | |\|
321 | o | 2: 'C'
324 | o | 2: 'C'
322 |/ /
325 |/ /
323 | o 1: 'B'
326 | o 1: 'B'
324 |/
327 |/
325 o 0: 'A'
328 o 0: 'A'
326
329
327 $ cd ..
330 $ cd ..
328
331
329
332
330 Rebase and collapse - E onto I:
333 Rebase and collapse - E onto I:
331
334
332 $ hg clone -q -u . c c1
335 $ hg clone -q -u . c c1
333 $ cd c1
336 $ cd c1
334
337
335 $ hg rebase -s 4 --collapse
338 $ hg rebase -s 4 --collapse
336 merging E
339 merging E
337 saved backup bundle to $TESTTMP/c1/.hg/strip-backup/*-backup.hg (glob)
340 saved backup bundle to $TESTTMP/c1/.hg/strip-backup/*-backup.hg (glob)
338
341
339 $ hg tglog
342 $ hg tglog
340 @ 5: 'Collapsed revision
343 @ 5: 'Collapsed revision
341 |\ * E
344 |\ * E
342 | | * F
345 | | * F
343 | | * G
346 | | * G
344 | | * H'
347 | | * H'
345 | o 4: 'I'
348 | o 4: 'I'
346 | |
349 | |
347 o | 3: 'D'
350 o | 3: 'D'
348 |\ \
351 |\ \
349 | o | 2: 'C'
352 | o | 2: 'C'
350 | |/
353 | |/
351 o / 1: 'B'
354 o / 1: 'B'
352 |/
355 |/
353 o 0: 'A'
356 o 0: 'A'
354
357
355 $ hg manifest
358 $ hg manifest
356 A
359 A
357 B
360 B
358 C
361 C
359 D
362 D
360 E
363 E
361 G
364 G
362 I
365 I
363
366
364 $ cat E
367 $ cat E
365 F
368 F
366
369
367 $ cd ..
370 $ cd ..
368
371
369
372
370 Create repo d:
373 Create repo d:
371
374
372 $ hg init d
375 $ hg init d
373 $ cd d
376 $ cd d
374
377
375 $ echo A > A
378 $ echo A > A
376 $ hg ci -Am A
379 $ hg ci -Am A
377 adding A
380 adding A
378 $ echo B > B
381 $ echo B > B
379 $ hg ci -Am B
382 $ hg ci -Am B
380 adding B
383 adding B
381 $ echo C > C
384 $ echo C > C
382 $ hg ci -Am C
385 $ hg ci -Am C
383 adding C
386 adding C
384
387
385 $ hg up -q 1
388 $ hg up -q 1
386
389
387 $ echo D > D
390 $ echo D > D
388 $ hg ci -Am D
391 $ hg ci -Am D
389 adding D
392 adding D
390 created new head
393 created new head
391 $ hg merge
394 $ hg merge
392 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
395 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
393 (branch merge, don't forget to commit)
396 (branch merge, don't forget to commit)
394
397
395 $ hg ci -m E
398 $ hg ci -m E
396
399
397 $ hg up -q 0
400 $ hg up -q 0
398
401
399 $ echo F > F
402 $ echo F > F
400 $ hg ci -Am F
403 $ hg ci -Am F
401 adding F
404 adding F
402 created new head
405 created new head
403
406
404 $ hg tglog
407 $ hg tglog
405 @ 5: 'F'
408 @ 5: 'F'
406 |
409 |
407 | o 4: 'E'
410 | o 4: 'E'
408 | |\
411 | |\
409 | | o 3: 'D'
412 | | o 3: 'D'
410 | | |
413 | | |
411 | o | 2: 'C'
414 | o | 2: 'C'
412 | |/
415 | |/
413 | o 1: 'B'
416 | o 1: 'B'
414 |/
417 |/
415 o 0: 'A'
418 o 0: 'A'
416
419
417 $ cd ..
420 $ cd ..
418
421
419
422
420 Rebase and collapse - B onto F:
423 Rebase and collapse - B onto F:
421
424
422 $ hg clone -q -u . d d1
425 $ hg clone -q -u . d d1
423 $ cd d1
426 $ cd d1
424
427
425 $ hg rebase -s 1 --collapse
428 $ hg rebase -s 1 --collapse
426 saved backup bundle to $TESTTMP/d1/.hg/strip-backup/*-backup.hg (glob)
429 saved backup bundle to $TESTTMP/d1/.hg/strip-backup/*-backup.hg (glob)
427
430
428 $ hg tglog
431 $ hg tglog
429 @ 2: 'Collapsed revision
432 @ 2: 'Collapsed revision
430 | * B
433 | * B
431 | * C
434 | * C
432 | * D
435 | * D
433 | * E'
436 | * E'
434 o 1: 'F'
437 o 1: 'F'
435 |
438 |
436 o 0: 'A'
439 o 0: 'A'
437
440
438 $ hg manifest
441 $ hg manifest
439 A
442 A
440 B
443 B
441 C
444 C
442 D
445 D
443 F
446 F
444
447
445 Interactions between collapse and keepbranches
448 Interactions between collapse and keepbranches
446 $ cd ..
449 $ cd ..
447 $ hg init e
450 $ hg init e
448 $ cd e
451 $ cd e
449 $ echo 'a' > a
452 $ echo 'a' > a
450 $ hg ci -Am 'A'
453 $ hg ci -Am 'A'
451 adding a
454 adding a
452
455
453 $ hg branch '1'
456 $ hg branch '1'
454 marked working directory as branch 1
457 marked working directory as branch 1
455 (branches are permanent and global, did you want a bookmark?)
458 (branches are permanent and global, did you want a bookmark?)
456 $ echo 'b' > b
459 $ echo 'b' > b
457 $ hg ci -Am 'B'
460 $ hg ci -Am 'B'
458 adding b
461 adding b
459
462
460 $ hg branch '2'
463 $ hg branch '2'
461 marked working directory as branch 2
464 marked working directory as branch 2
462 (branches are permanent and global, did you want a bookmark?)
465 (branches are permanent and global, did you want a bookmark?)
463 $ echo 'c' > c
466 $ echo 'c' > c
464 $ hg ci -Am 'C'
467 $ hg ci -Am 'C'
465 adding c
468 adding c
466
469
467 $ hg up -q 0
470 $ hg up -q 0
468 $ echo 'd' > d
471 $ echo 'd' > d
469 $ hg ci -Am 'D'
472 $ hg ci -Am 'D'
470 adding d
473 adding d
471
474
472 $ hg tglog
475 $ hg tglog
473 @ 3: 'D'
476 @ 3: 'D'
474 |
477 |
475 | o 2: 'C' 2
478 | o 2: 'C' 2
476 | |
479 | |
477 | o 1: 'B' 1
480 | o 1: 'B' 1
478 |/
481 |/
479 o 0: 'A'
482 o 0: 'A'
480
483
481 $ hg rebase --keepbranches --collapse -s 1 -d 3
484 $ hg rebase --keepbranches --collapse -s 1 -d 3
482 abort: cannot collapse multiple named branches
485 abort: cannot collapse multiple named branches
483 [255]
486 [255]
484
487
@@ -1,115 +1,118 b''
1 $ cat >> $HGRCPATH <<EOF
1 $ cat >> $HGRCPATH <<EOF
2 > [extensions]
2 > [extensions]
3 > graphlog=
3 > graphlog=
4 > rebase=
4 > rebase=
5 >
5 >
6 > [phases]
7 > publish=False
8 >
6 > [alias]
9 > [alias]
7 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
10 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
8 > EOF
11 > EOF
9
12
10 $ hg init a
13 $ hg init a
11 $ cd a
14 $ cd a
12 $ echo c1 >common
15 $ echo c1 >common
13 $ hg add common
16 $ hg add common
14 $ hg ci -m C1
17 $ hg ci -m C1
15
18
16 $ echo c2 >>common
19 $ echo c2 >>common
17 $ hg ci -m C2
20 $ hg ci -m C2
18
21
19 $ echo c3 >>common
22 $ echo c3 >>common
20 $ hg ci -m C3
23 $ hg ci -m C3
21
24
22 $ hg up -q -C 1
25 $ hg up -q -C 1
23
26
24 $ echo l1 >>extra
27 $ echo l1 >>extra
25 $ hg add extra
28 $ hg add extra
26 $ hg ci -m L1
29 $ hg ci -m L1
27 created new head
30 created new head
28
31
29 $ sed -e 's/c2/l2/' common > common.new
32 $ sed -e 's/c2/l2/' common > common.new
30 $ mv common.new common
33 $ mv common.new common
31 $ hg ci -m L2
34 $ hg ci -m L2
32
35
33 $ echo l3 >> extra2
36 $ echo l3 >> extra2
34 $ hg add extra2
37 $ hg add extra2
35 $ hg ci -m L3
38 $ hg ci -m L3
36
39
37 $ hg tglog
40 $ hg tglog
38 @ 5: 'L3'
41 @ 5: 'L3'
39 |
42 |
40 o 4: 'L2'
43 o 4: 'L2'
41 |
44 |
42 o 3: 'L1'
45 o 3: 'L1'
43 |
46 |
44 | o 2: 'C3'
47 | o 2: 'C3'
45 |/
48 |/
46 o 1: 'C2'
49 o 1: 'C2'
47 |
50 |
48 o 0: 'C1'
51 o 0: 'C1'
49
52
50 Try to call --continue:
53 Try to call --continue:
51
54
52 $ hg rebase --continue
55 $ hg rebase --continue
53 abort: no rebase in progress
56 abort: no rebase in progress
54 [255]
57 [255]
55
58
56 Conflicting rebase:
59 Conflicting rebase:
57
60
58 $ hg rebase -s 3 -d 2
61 $ hg rebase -s 3 -d 2
59 merging common
62 merging common
60 warning: conflicts during merge.
63 warning: conflicts during merge.
61 merging common incomplete! (edit conflicts, then use 'hg resolve --mark')
64 merging common incomplete! (edit conflicts, then use 'hg resolve --mark')
62 abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
65 abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
63 [255]
66 [255]
64
67
65 Try to continue without solving the conflict:
68 Try to continue without solving the conflict:
66
69
67 $ hg rebase --continue
70 $ hg rebase --continue
68 abort: unresolved merge conflicts (see hg help resolve)
71 abort: unresolved merge conflicts (see hg help resolve)
69 [255]
72 [255]
70
73
71 Conclude rebase:
74 Conclude rebase:
72
75
73 $ echo 'resolved merge' >common
76 $ echo 'resolved merge' >common
74 $ hg resolve -m common
77 $ hg resolve -m common
75 $ hg rebase --continue
78 $ hg rebase --continue
76 saved backup bundle to $TESTTMP/a/.hg/strip-backup/*-backup.hg (glob)
79 saved backup bundle to $TESTTMP/a/.hg/strip-backup/*-backup.hg (glob)
77
80
78 $ hg tglog
81 $ hg tglog
79 @ 5: 'L3'
82 @ 5: 'L3'
80 |
83 |
81 o 4: 'L2'
84 o 4: 'L2'
82 |
85 |
83 o 3: 'L1'
86 o 3: 'L1'
84 |
87 |
85 o 2: 'C3'
88 o 2: 'C3'
86 |
89 |
87 o 1: 'C2'
90 o 1: 'C2'
88 |
91 |
89 o 0: 'C1'
92 o 0: 'C1'
90
93
91 Check correctness:
94 Check correctness:
92
95
93 $ hg cat -r 0 common
96 $ hg cat -r 0 common
94 c1
97 c1
95
98
96 $ hg cat -r 1 common
99 $ hg cat -r 1 common
97 c1
100 c1
98 c2
101 c2
99
102
100 $ hg cat -r 2 common
103 $ hg cat -r 2 common
101 c1
104 c1
102 c2
105 c2
103 c3
106 c3
104
107
105 $ hg cat -r 3 common
108 $ hg cat -r 3 common
106 c1
109 c1
107 c2
110 c2
108 c3
111 c3
109
112
110 $ hg cat -r 4 common
113 $ hg cat -r 4 common
111 resolved merge
114 resolved merge
112
115
113 $ hg cat -r 5 common
116 $ hg cat -r 5 common
114 resolved merge
117 resolved merge
115
118
@@ -1,395 +1,398 b''
1 $ cat >> $HGRCPATH <<EOF
1 $ cat >> $HGRCPATH <<EOF
2 > [extensions]
2 > [extensions]
3 > graphlog=
3 > graphlog=
4 > rebase=
4 > rebase=
5 >
5 >
6 > [phases]
7 > publish=False
8 >
6 > [alias]
9 > [alias]
7 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
10 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
8 > EOF
11 > EOF
9
12
10
13
11 $ hg init a
14 $ hg init a
12 $ cd a
15 $ cd a
13 $ hg unbundle $TESTDIR/bundles/rebase.hg
16 $ hg unbundle $TESTDIR/bundles/rebase.hg
14 adding changesets
17 adding changesets
15 adding manifests
18 adding manifests
16 adding file changes
19 adding file changes
17 added 8 changesets with 7 changes to 7 files (+2 heads)
20 added 8 changesets with 7 changes to 7 files (+2 heads)
18 (run 'hg heads' to see heads, 'hg merge' to merge)
21 (run 'hg heads' to see heads, 'hg merge' to merge)
19 $ hg up tip
22 $ hg up tip
20 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
23 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
21
24
22 $ cd ..
25 $ cd ..
23
26
24
27
25 Rebasing D onto H detaching from C:
28 Rebasing D onto H detaching from C:
26
29
27 $ hg clone -q -u . a a1
30 $ hg clone -q -u . a a1
28 $ cd a1
31 $ cd a1
29
32
30 $ hg tglog
33 $ hg tglog
31 @ 7: 'H'
34 @ 7: 'H'
32 |
35 |
33 | o 6: 'G'
36 | o 6: 'G'
34 |/|
37 |/|
35 o | 5: 'F'
38 o | 5: 'F'
36 | |
39 | |
37 | o 4: 'E'
40 | o 4: 'E'
38 |/
41 |/
39 | o 3: 'D'
42 | o 3: 'D'
40 | |
43 | |
41 | o 2: 'C'
44 | o 2: 'C'
42 | |
45 | |
43 | o 1: 'B'
46 | o 1: 'B'
44 |/
47 |/
45 o 0: 'A'
48 o 0: 'A'
46
49
47 $ hg rebase --detach -s 3 -d 7
50 $ hg rebase --detach -s 3 -d 7
48 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
51 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
49
52
50 $ hg tglog
53 $ hg tglog
51 @ 7: 'D'
54 @ 7: 'D'
52 |
55 |
53 o 6: 'H'
56 o 6: 'H'
54 |
57 |
55 | o 5: 'G'
58 | o 5: 'G'
56 |/|
59 |/|
57 o | 4: 'F'
60 o | 4: 'F'
58 | |
61 | |
59 | o 3: 'E'
62 | o 3: 'E'
60 |/
63 |/
61 | o 2: 'C'
64 | o 2: 'C'
62 | |
65 | |
63 | o 1: 'B'
66 | o 1: 'B'
64 |/
67 |/
65 o 0: 'A'
68 o 0: 'A'
66
69
67 $ hg manifest
70 $ hg manifest
68 A
71 A
69 D
72 D
70 F
73 F
71 H
74 H
72
75
73 $ cd ..
76 $ cd ..
74
77
75
78
76 Rebasing C onto H detaching from B:
79 Rebasing C onto H detaching from B:
77
80
78 $ hg clone -q -u . a a2
81 $ hg clone -q -u . a a2
79 $ cd a2
82 $ cd a2
80
83
81 $ hg tglog
84 $ hg tglog
82 @ 7: 'H'
85 @ 7: 'H'
83 |
86 |
84 | o 6: 'G'
87 | o 6: 'G'
85 |/|
88 |/|
86 o | 5: 'F'
89 o | 5: 'F'
87 | |
90 | |
88 | o 4: 'E'
91 | o 4: 'E'
89 |/
92 |/
90 | o 3: 'D'
93 | o 3: 'D'
91 | |
94 | |
92 | o 2: 'C'
95 | o 2: 'C'
93 | |
96 | |
94 | o 1: 'B'
97 | o 1: 'B'
95 |/
98 |/
96 o 0: 'A'
99 o 0: 'A'
97
100
98 $ hg rebase --detach -s 2 -d 7
101 $ hg rebase --detach -s 2 -d 7
99 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
102 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
100
103
101 $ hg tglog
104 $ hg tglog
102 @ 7: 'D'
105 @ 7: 'D'
103 |
106 |
104 o 6: 'C'
107 o 6: 'C'
105 |
108 |
106 o 5: 'H'
109 o 5: 'H'
107 |
110 |
108 | o 4: 'G'
111 | o 4: 'G'
109 |/|
112 |/|
110 o | 3: 'F'
113 o | 3: 'F'
111 | |
114 | |
112 | o 2: 'E'
115 | o 2: 'E'
113 |/
116 |/
114 | o 1: 'B'
117 | o 1: 'B'
115 |/
118 |/
116 o 0: 'A'
119 o 0: 'A'
117
120
118 $ hg manifest
121 $ hg manifest
119 A
122 A
120 C
123 C
121 D
124 D
122 F
125 F
123 H
126 H
124
127
125 $ cd ..
128 $ cd ..
126
129
127
130
128 Rebasing B onto H using detach (same as not using it):
131 Rebasing B onto H using detach (same as not using it):
129
132
130 $ hg clone -q -u . a a3
133 $ hg clone -q -u . a a3
131 $ cd a3
134 $ cd a3
132
135
133 $ hg tglog
136 $ hg tglog
134 @ 7: 'H'
137 @ 7: 'H'
135 |
138 |
136 | o 6: 'G'
139 | o 6: 'G'
137 |/|
140 |/|
138 o | 5: 'F'
141 o | 5: 'F'
139 | |
142 | |
140 | o 4: 'E'
143 | o 4: 'E'
141 |/
144 |/
142 | o 3: 'D'
145 | o 3: 'D'
143 | |
146 | |
144 | o 2: 'C'
147 | o 2: 'C'
145 | |
148 | |
146 | o 1: 'B'
149 | o 1: 'B'
147 |/
150 |/
148 o 0: 'A'
151 o 0: 'A'
149
152
150 $ hg rebase --detach -s 1 -d 7
153 $ hg rebase --detach -s 1 -d 7
151 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
154 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
152
155
153 $ hg tglog
156 $ hg tglog
154 @ 7: 'D'
157 @ 7: 'D'
155 |
158 |
156 o 6: 'C'
159 o 6: 'C'
157 |
160 |
158 o 5: 'B'
161 o 5: 'B'
159 |
162 |
160 o 4: 'H'
163 o 4: 'H'
161 |
164 |
162 | o 3: 'G'
165 | o 3: 'G'
163 |/|
166 |/|
164 o | 2: 'F'
167 o | 2: 'F'
165 | |
168 | |
166 | o 1: 'E'
169 | o 1: 'E'
167 |/
170 |/
168 o 0: 'A'
171 o 0: 'A'
169
172
170 $ hg manifest
173 $ hg manifest
171 A
174 A
172 B
175 B
173 C
176 C
174 D
177 D
175 F
178 F
176 H
179 H
177
180
178 $ cd ..
181 $ cd ..
179
182
180
183
181 Rebasing C onto H detaching from B and collapsing:
184 Rebasing C onto H detaching from B and collapsing:
182
185
183 $ hg clone -q -u . a a4
186 $ hg clone -q -u . a a4
184 $ cd a4
187 $ cd a4
185
188
186 $ hg tglog
189 $ hg tglog
187 @ 7: 'H'
190 @ 7: 'H'
188 |
191 |
189 | o 6: 'G'
192 | o 6: 'G'
190 |/|
193 |/|
191 o | 5: 'F'
194 o | 5: 'F'
192 | |
195 | |
193 | o 4: 'E'
196 | o 4: 'E'
194 |/
197 |/
195 | o 3: 'D'
198 | o 3: 'D'
196 | |
199 | |
197 | o 2: 'C'
200 | o 2: 'C'
198 | |
201 | |
199 | o 1: 'B'
202 | o 1: 'B'
200 |/
203 |/
201 o 0: 'A'
204 o 0: 'A'
202
205
203 $ hg rebase --detach --collapse -s 2 -d 7
206 $ hg rebase --detach --collapse -s 2 -d 7
204 saved backup bundle to $TESTTMP/a4/.hg/strip-backup/*-backup.hg (glob)
207 saved backup bundle to $TESTTMP/a4/.hg/strip-backup/*-backup.hg (glob)
205
208
206 $ hg tglog
209 $ hg tglog
207 @ 6: 'Collapsed revision
210 @ 6: 'Collapsed revision
208 | * C
211 | * C
209 | * D'
212 | * D'
210 o 5: 'H'
213 o 5: 'H'
211 |
214 |
212 | o 4: 'G'
215 | o 4: 'G'
213 |/|
216 |/|
214 o | 3: 'F'
217 o | 3: 'F'
215 | |
218 | |
216 | o 2: 'E'
219 | o 2: 'E'
217 |/
220 |/
218 | o 1: 'B'
221 | o 1: 'B'
219 |/
222 |/
220 o 0: 'A'
223 o 0: 'A'
221
224
222 $ hg manifest
225 $ hg manifest
223 A
226 A
224 C
227 C
225 D
228 D
226 F
229 F
227 H
230 H
228
231
229 $ cd ..
232 $ cd ..
230
233
231 Rebasing across null as ancestor
234 Rebasing across null as ancestor
232 $ hg clone -q -U a a5
235 $ hg clone -q -U a a5
233
236
234 $ cd a5
237 $ cd a5
235
238
236 $ echo x > x
239 $ echo x > x
237
240
238 $ hg add x
241 $ hg add x
239
242
240 $ hg ci -m "extra branch"
243 $ hg ci -m "extra branch"
241 created new head
244 created new head
242
245
243 $ hg tglog
246 $ hg tglog
244 @ 8: 'extra branch'
247 @ 8: 'extra branch'
245
248
246 o 7: 'H'
249 o 7: 'H'
247 |
250 |
248 | o 6: 'G'
251 | o 6: 'G'
249 |/|
252 |/|
250 o | 5: 'F'
253 o | 5: 'F'
251 | |
254 | |
252 | o 4: 'E'
255 | o 4: 'E'
253 |/
256 |/
254 | o 3: 'D'
257 | o 3: 'D'
255 | |
258 | |
256 | o 2: 'C'
259 | o 2: 'C'
257 | |
260 | |
258 | o 1: 'B'
261 | o 1: 'B'
259 |/
262 |/
260 o 0: 'A'
263 o 0: 'A'
261
264
262 $ hg rebase --detach -s 1 -d tip
265 $ hg rebase --detach -s 1 -d tip
263 saved backup bundle to $TESTTMP/a5/.hg/strip-backup/*-backup.hg (glob)
266 saved backup bundle to $TESTTMP/a5/.hg/strip-backup/*-backup.hg (glob)
264
267
265 $ hg tglog
268 $ hg tglog
266 @ 8: 'D'
269 @ 8: 'D'
267 |
270 |
268 o 7: 'C'
271 o 7: 'C'
269 |
272 |
270 o 6: 'B'
273 o 6: 'B'
271 |
274 |
272 o 5: 'extra branch'
275 o 5: 'extra branch'
273
276
274 o 4: 'H'
277 o 4: 'H'
275 |
278 |
276 | o 3: 'G'
279 | o 3: 'G'
277 |/|
280 |/|
278 o | 2: 'F'
281 o | 2: 'F'
279 | |
282 | |
280 | o 1: 'E'
283 | o 1: 'E'
281 |/
284 |/
282 o 0: 'A'
285 o 0: 'A'
283
286
284
287
285 $ hg rebase -d 5 -s 7
288 $ hg rebase -d 5 -s 7
286 saved backup bundle to $TESTTMP/a5/.hg/strip-backup/13547172c9c0-backup.hg (glob)
289 saved backup bundle to $TESTTMP/a5/.hg/strip-backup/13547172c9c0-backup.hg (glob)
287 $ hg tglog
290 $ hg tglog
288 @ 8: 'D'
291 @ 8: 'D'
289 |
292 |
290 o 7: 'C'
293 o 7: 'C'
291 |
294 |
292 | o 6: 'B'
295 | o 6: 'B'
293 |/
296 |/
294 o 5: 'extra branch'
297 o 5: 'extra branch'
295
298
296 o 4: 'H'
299 o 4: 'H'
297 |
300 |
298 | o 3: 'G'
301 | o 3: 'G'
299 |/|
302 |/|
300 o | 2: 'F'
303 o | 2: 'F'
301 | |
304 | |
302 | o 1: 'E'
305 | o 1: 'E'
303 |/
306 |/
304 o 0: 'A'
307 o 0: 'A'
305
308
306 $ cd ..
309 $ cd ..
307
310
308 Verify that target is not selected as external rev (issue3085)
311 Verify that target is not selected as external rev (issue3085)
309
312
310 $ hg clone -q -U a a6
313 $ hg clone -q -U a a6
311 $ cd a6
314 $ cd a6
312 $ hg up -q 6
315 $ hg up -q 6
313
316
314 $ echo "I" >> E
317 $ echo "I" >> E
315 $ hg ci -m "I"
318 $ hg ci -m "I"
316 $ hg merge 7
319 $ hg merge 7
317 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
320 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
318 (branch merge, don't forget to commit)
321 (branch merge, don't forget to commit)
319 $ hg ci -m "Merge"
322 $ hg ci -m "Merge"
320 $ echo "J" >> F
323 $ echo "J" >> F
321 $ hg ci -m "J"
324 $ hg ci -m "J"
322
325
323 $ hg rebase -s 8 -d 7 --collapse --detach --config ui.merge=internal:other
326 $ hg rebase -s 8 -d 7 --collapse --detach --config ui.merge=internal:other
324 remote changed E which local deleted
327 remote changed E which local deleted
325 use (c)hanged version or leave (d)eleted? c
328 use (c)hanged version or leave (d)eleted? c
326 saved backup bundle to $TESTTMP/a6/.hg/strip-backup/*-backup.hg (glob)
329 saved backup bundle to $TESTTMP/a6/.hg/strip-backup/*-backup.hg (glob)
327
330
328 $ hg tglog
331 $ hg tglog
329 @ 8: 'Collapsed revision
332 @ 8: 'Collapsed revision
330 | * I
333 | * I
331 | * Merge
334 | * Merge
332 | * J'
335 | * J'
333 o 7: 'H'
336 o 7: 'H'
334 |
337 |
335 | o 6: 'G'
338 | o 6: 'G'
336 |/|
339 |/|
337 o | 5: 'F'
340 o | 5: 'F'
338 | |
341 | |
339 | o 4: 'E'
342 | o 4: 'E'
340 |/
343 |/
341 | o 3: 'D'
344 | o 3: 'D'
342 | |
345 | |
343 | o 2: 'C'
346 | o 2: 'C'
344 | |
347 | |
345 | o 1: 'B'
348 | o 1: 'B'
346 |/
349 |/
347 o 0: 'A'
350 o 0: 'A'
348
351
349
352
350 $ hg parents
353 $ hg parents
351 changeset: 8:9472f4b1d736
354 changeset: 8:9472f4b1d736
352 tag: tip
355 tag: tip
353 user: test
356 user: test
354 date: Thu Jan 01 00:00:00 1970 +0000
357 date: Thu Jan 01 00:00:00 1970 +0000
355 summary: Collapsed revision
358 summary: Collapsed revision
356
359
357
360
358 $ cd ..
361 $ cd ..
359
362
360 Ensure --continue restores a correct state (issue3046):
363 Ensure --continue restores a correct state (issue3046):
361 $ hg clone -q a a7
364 $ hg clone -q a a7
362 $ cd a7
365 $ cd a7
363 $ hg up -q 3
366 $ hg up -q 3
364 $ echo 'H2' > H
367 $ echo 'H2' > H
365 $ hg ci -A -m 'H2'
368 $ hg ci -A -m 'H2'
366 adding H
369 adding H
367 $ hg rebase -s 8 -d 7 --detach --config ui.merge=internal:fail
370 $ hg rebase -s 8 -d 7 --detach --config ui.merge=internal:fail
368 merging H
371 merging H
369 warning: conflicts during merge.
372 warning: conflicts during merge.
370 merging H incomplete! (edit conflicts, then use 'hg resolve --mark')
373 merging H incomplete! (edit conflicts, then use 'hg resolve --mark')
371 abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
374 abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
372 [255]
375 [255]
373 $ hg resolve --all -t internal:local
376 $ hg resolve --all -t internal:local
374 $ hg rebase -c
377 $ hg rebase -c
375 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/6215fafa5447-backup.hg (glob)
378 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/6215fafa5447-backup.hg (glob)
376 $ hg tglog
379 $ hg tglog
377 @ 8: 'H2'
380 @ 8: 'H2'
378 |
381 |
379 o 7: 'H'
382 o 7: 'H'
380 |
383 |
381 | o 6: 'G'
384 | o 6: 'G'
382 |/|
385 |/|
383 o | 5: 'F'
386 o | 5: 'F'
384 | |
387 | |
385 | o 4: 'E'
388 | o 4: 'E'
386 |/
389 |/
387 | o 3: 'D'
390 | o 3: 'D'
388 | |
391 | |
389 | o 2: 'C'
392 | o 2: 'C'
390 | |
393 | |
391 | o 1: 'B'
394 | o 1: 'B'
392 |/
395 |/
393 o 0: 'A'
396 o 0: 'A'
394
397
395
398
@@ -1,194 +1,197 b''
1 $ cat >> $HGRCPATH <<EOF
1 $ cat >> $HGRCPATH <<EOF
2 > [extensions]
2 > [extensions]
3 > graphlog=
3 > graphlog=
4 > rebase=
4 > rebase=
5 >
5 >
6 > [phases]
7 > publish=False
8 >
6 > [alias]
9 > [alias]
7 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
10 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
8 > EOF
11 > EOF
9
12
10
13
11 $ hg init a
14 $ hg init a
12 $ cd a
15 $ cd a
13
16
14 $ echo A > A
17 $ echo A > A
15 $ hg ci -Am A
18 $ hg ci -Am A
16 adding A
19 adding A
17
20
18 $ echo B > B
21 $ echo B > B
19 $ hg ci -Am B
22 $ hg ci -Am B
20 adding B
23 adding B
21
24
22 $ echo C >> A
25 $ echo C >> A
23 $ hg ci -m C
26 $ hg ci -m C
24
27
25 $ hg up -q -C 0
28 $ hg up -q -C 0
26
29
27 $ echo D >> A
30 $ echo D >> A
28 $ hg ci -m D
31 $ hg ci -m D
29 created new head
32 created new head
30
33
31 $ echo E > E
34 $ echo E > E
32 $ hg ci -Am E
35 $ hg ci -Am E
33 adding E
36 adding E
34
37
35 $ cd ..
38 $ cd ..
36
39
37
40
38 Changes during an interruption - continue:
41 Changes during an interruption - continue:
39
42
40 $ hg clone -q -u . a a1
43 $ hg clone -q -u . a a1
41 $ cd a1
44 $ cd a1
42
45
43 $ hg tglog
46 $ hg tglog
44 @ 4: 'E'
47 @ 4: 'E'
45 |
48 |
46 o 3: 'D'
49 o 3: 'D'
47 |
50 |
48 | o 2: 'C'
51 | o 2: 'C'
49 | |
52 | |
50 | o 1: 'B'
53 | o 1: 'B'
51 |/
54 |/
52 o 0: 'A'
55 o 0: 'A'
53
56
54 Rebasing B onto E:
57 Rebasing B onto E:
55
58
56 $ hg rebase -s 1 -d 4
59 $ hg rebase -s 1 -d 4
57 merging A
60 merging A
58 warning: conflicts during merge.
61 warning: conflicts during merge.
59 merging A incomplete! (edit conflicts, then use 'hg resolve --mark')
62 merging A incomplete! (edit conflicts, then use 'hg resolve --mark')
60 abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
63 abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
61 [255]
64 [255]
62
65
63 Force a commit on C during the interruption:
66 Force a commit on C during the interruption:
64
67
65 $ hg up -q -C 2
68 $ hg up -q -C 2
66
69
67 $ echo 'Extra' > Extra
70 $ echo 'Extra' > Extra
68 $ hg add Extra
71 $ hg add Extra
69 $ hg ci -m 'Extra'
72 $ hg ci -m 'Extra'
70
73
71 $ hg tglog
74 $ hg tglog
72 @ 6: 'Extra'
75 @ 6: 'Extra'
73 |
76 |
74 | o 5: 'B'
77 | o 5: 'B'
75 | |
78 | |
76 | o 4: 'E'
79 | o 4: 'E'
77 | |
80 | |
78 | o 3: 'D'
81 | o 3: 'D'
79 | |
82 | |
80 o | 2: 'C'
83 o | 2: 'C'
81 | |
84 | |
82 o | 1: 'B'
85 o | 1: 'B'
83 |/
86 |/
84 o 0: 'A'
87 o 0: 'A'
85
88
86 Resume the rebasing:
89 Resume the rebasing:
87
90
88 $ hg rebase --continue
91 $ hg rebase --continue
89 merging A
92 merging A
90 warning: conflicts during merge.
93 warning: conflicts during merge.
91 merging A incomplete! (edit conflicts, then use 'hg resolve --mark')
94 merging A incomplete! (edit conflicts, then use 'hg resolve --mark')
92 abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
95 abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
93 [255]
96 [255]
94
97
95 Solve the conflict and go on:
98 Solve the conflict and go on:
96
99
97 $ echo 'conflict solved' > A
100 $ echo 'conflict solved' > A
98 $ rm A.orig
101 $ rm A.orig
99 $ hg resolve -m A
102 $ hg resolve -m A
100
103
101 $ hg rebase --continue
104 $ hg rebase --continue
102 warning: new changesets detected on source branch, not stripping
105 warning: new changesets detected on source branch, not stripping
103
106
104 $ hg tglog
107 $ hg tglog
105 @ 7: 'C'
108 @ 7: 'C'
106 |
109 |
107 | o 6: 'Extra'
110 | o 6: 'Extra'
108 | |
111 | |
109 o | 5: 'B'
112 o | 5: 'B'
110 | |
113 | |
111 o | 4: 'E'
114 o | 4: 'E'
112 | |
115 | |
113 o | 3: 'D'
116 o | 3: 'D'
114 | |
117 | |
115 | o 2: 'C'
118 | o 2: 'C'
116 | |
119 | |
117 | o 1: 'B'
120 | o 1: 'B'
118 |/
121 |/
119 o 0: 'A'
122 o 0: 'A'
120
123
121 $ cd ..
124 $ cd ..
122
125
123
126
124 Changes during an interruption - abort:
127 Changes during an interruption - abort:
125
128
126 $ hg clone -q -u . a a2
129 $ hg clone -q -u . a a2
127 $ cd a2
130 $ cd a2
128
131
129 $ hg tglog
132 $ hg tglog
130 @ 4: 'E'
133 @ 4: 'E'
131 |
134 |
132 o 3: 'D'
135 o 3: 'D'
133 |
136 |
134 | o 2: 'C'
137 | o 2: 'C'
135 | |
138 | |
136 | o 1: 'B'
139 | o 1: 'B'
137 |/
140 |/
138 o 0: 'A'
141 o 0: 'A'
139
142
140 Rebasing B onto E:
143 Rebasing B onto E:
141
144
142 $ hg rebase -s 1 -d 4
145 $ hg rebase -s 1 -d 4
143 merging A
146 merging A
144 warning: conflicts during merge.
147 warning: conflicts during merge.
145 merging A incomplete! (edit conflicts, then use 'hg resolve --mark')
148 merging A incomplete! (edit conflicts, then use 'hg resolve --mark')
146 abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
149 abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
147 [255]
150 [255]
148
151
149 Force a commit on B' during the interruption:
152 Force a commit on B' during the interruption:
150
153
151 $ hg up -q -C 5
154 $ hg up -q -C 5
152
155
153 $ echo 'Extra' > Extra
156 $ echo 'Extra' > Extra
154 $ hg add Extra
157 $ hg add Extra
155 $ hg ci -m 'Extra'
158 $ hg ci -m 'Extra'
156
159
157 $ hg tglog
160 $ hg tglog
158 @ 6: 'Extra'
161 @ 6: 'Extra'
159 |
162 |
160 o 5: 'B'
163 o 5: 'B'
161 |
164 |
162 o 4: 'E'
165 o 4: 'E'
163 |
166 |
164 o 3: 'D'
167 o 3: 'D'
165 |
168 |
166 | o 2: 'C'
169 | o 2: 'C'
167 | |
170 | |
168 | o 1: 'B'
171 | o 1: 'B'
169 |/
172 |/
170 o 0: 'A'
173 o 0: 'A'
171
174
172 Abort the rebasing:
175 Abort the rebasing:
173
176
174 $ hg rebase --abort
177 $ hg rebase --abort
175 warning: new changesets detected on target branch, can't abort
178 warning: new changesets detected on target branch, can't abort
176 [255]
179 [255]
177
180
178 $ hg tglog
181 $ hg tglog
179 @ 6: 'Extra'
182 @ 6: 'Extra'
180 |
183 |
181 o 5: 'B'
184 o 5: 'B'
182 |
185 |
183 o 4: 'E'
186 o 4: 'E'
184 |
187 |
185 o 3: 'D'
188 o 3: 'D'
186 |
189 |
187 | o 2: 'C'
190 | o 2: 'C'
188 | |
191 | |
189 | o 1: 'B'
192 | o 1: 'B'
190 |/
193 |/
191 o 0: 'A'
194 o 0: 'A'
192
195
193 $ cd ..
196 $ cd ..
194
197
@@ -1,123 +1,126 b''
1 $ cat >> $HGRCPATH <<EOF
1 $ cat >> $HGRCPATH <<EOF
2 > [extensions]
2 > [extensions]
3 > graphlog=
3 > graphlog=
4 > rebase=
4 > rebase=
5 >
5 >
6 > [phases]
7 > publish=False
8 >
6 > [alias]
9 > [alias]
7 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
10 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
8 > EOF
11 > EOF
9
12
10
13
11 $ hg init a
14 $ hg init a
12 $ cd a
15 $ cd a
13
16
14 $ echo c1 > c1
17 $ echo c1 > c1
15 $ hg ci -Am c1
18 $ hg ci -Am c1
16 adding c1
19 adding c1
17
20
18 $ echo c2 > c2
21 $ echo c2 > c2
19 $ hg ci -Am c2
22 $ hg ci -Am c2
20 adding c2
23 adding c2
21
24
22 $ echo l1 > l1
25 $ echo l1 > l1
23 $ hg ci -Am l1
26 $ hg ci -Am l1
24 adding l1
27 adding l1
25
28
26 $ hg up -q -C 1
29 $ hg up -q -C 1
27
30
28 $ echo r1 > r1
31 $ echo r1 > r1
29 $ hg ci -Am r1
32 $ hg ci -Am r1
30 adding r1
33 adding r1
31 created new head
34 created new head
32
35
33 $ echo r2 > r2
36 $ echo r2 > r2
34 $ hg ci -Am r2
37 $ hg ci -Am r2
35 adding r2
38 adding r2
36
39
37 $ hg tglog
40 $ hg tglog
38 @ 4: 'r2'
41 @ 4: 'r2'
39 |
42 |
40 o 3: 'r1'
43 o 3: 'r1'
41 |
44 |
42 | o 2: 'l1'
45 | o 2: 'l1'
43 |/
46 |/
44 o 1: 'c2'
47 o 1: 'c2'
45 |
48 |
46 o 0: 'c1'
49 o 0: 'c1'
47
50
48 Rebase with no arguments - single revision in source branch:
51 Rebase with no arguments - single revision in source branch:
49
52
50 $ hg up -q -C 2
53 $ hg up -q -C 2
51
54
52 $ hg rebase
55 $ hg rebase
53 saved backup bundle to $TESTTMP/a/.hg/strip-backup/*-backup.hg (glob)
56 saved backup bundle to $TESTTMP/a/.hg/strip-backup/*-backup.hg (glob)
54
57
55 $ hg tglog
58 $ hg tglog
56 @ 4: 'l1'
59 @ 4: 'l1'
57 |
60 |
58 o 3: 'r2'
61 o 3: 'r2'
59 |
62 |
60 o 2: 'r1'
63 o 2: 'r1'
61 |
64 |
62 o 1: 'c2'
65 o 1: 'c2'
63 |
66 |
64 o 0: 'c1'
67 o 0: 'c1'
65
68
66 $ cd ..
69 $ cd ..
67
70
68
71
69 $ hg init b
72 $ hg init b
70 $ cd b
73 $ cd b
71
74
72 $ echo c1 > c1
75 $ echo c1 > c1
73 $ hg ci -Am c1
76 $ hg ci -Am c1
74 adding c1
77 adding c1
75
78
76 $ echo c2 > c2
79 $ echo c2 > c2
77 $ hg ci -Am c2
80 $ hg ci -Am c2
78 adding c2
81 adding c2
79
82
80 $ echo l1 > l1
83 $ echo l1 > l1
81 $ hg ci -Am l1
84 $ hg ci -Am l1
82 adding l1
85 adding l1
83
86
84 $ echo l2 > l2
87 $ echo l2 > l2
85 $ hg ci -Am l2
88 $ hg ci -Am l2
86 adding l2
89 adding l2
87
90
88 $ hg up -q -C 1
91 $ hg up -q -C 1
89
92
90 $ echo r1 > r1
93 $ echo r1 > r1
91 $ hg ci -Am r1
94 $ hg ci -Am r1
92 adding r1
95 adding r1
93 created new head
96 created new head
94
97
95 $ hg tglog
98 $ hg tglog
96 @ 4: 'r1'
99 @ 4: 'r1'
97 |
100 |
98 | o 3: 'l2'
101 | o 3: 'l2'
99 | |
102 | |
100 | o 2: 'l1'
103 | o 2: 'l1'
101 |/
104 |/
102 o 1: 'c2'
105 o 1: 'c2'
103 |
106 |
104 o 0: 'c1'
107 o 0: 'c1'
105
108
106 Rebase with no arguments - single revision in target branch:
109 Rebase with no arguments - single revision in target branch:
107
110
108 $ hg up -q -C 3
111 $ hg up -q -C 3
109
112
110 $ hg rebase
113 $ hg rebase
111 saved backup bundle to $TESTTMP/b/.hg/strip-backup/*-backup.hg (glob)
114 saved backup bundle to $TESTTMP/b/.hg/strip-backup/*-backup.hg (glob)
112
115
113 $ hg tglog
116 $ hg tglog
114 @ 4: 'l2'
117 @ 4: 'l2'
115 |
118 |
116 o 3: 'l1'
119 o 3: 'l1'
117 |
120 |
118 o 2: 'r1'
121 o 2: 'r1'
119 |
122 |
120 o 1: 'c2'
123 o 1: 'c2'
121 |
124 |
122 o 0: 'c1'
125 o 0: 'c1'
123
126
@@ -1,136 +1,139 b''
1 This emulates the effects of an hg pull --rebase in which the remote repo
1 This emulates the effects of an hg pull --rebase in which the remote repo
2 already has one local mq patch
2 already has one local mq patch
3
3
4 $ cat >> $HGRCPATH <<EOF
4 $ cat >> $HGRCPATH <<EOF
5 > [extensions]
5 > [extensions]
6 > graphlog=
6 > graphlog=
7 > rebase=
7 > rebase=
8 > mq=
8 > mq=
9 >
9 >
10 > [phases]
11 > publish=False
12 >
10 > [alias]
13 > [alias]
11 > tglog = log -G --template "{rev}: '{desc}' tags: {tags}\n"
14 > tglog = log -G --template "{rev}: '{desc}' tags: {tags}\n"
12 > EOF
15 > EOF
13
16
14
17
15 $ hg init a
18 $ hg init a
16 $ cd a
19 $ cd a
17 $ hg qinit -c
20 $ hg qinit -c
18
21
19 $ echo c1 > c1
22 $ echo c1 > c1
20 $ hg add c1
23 $ hg add c1
21 $ hg ci -m C1
24 $ hg ci -m C1
22
25
23 $ echo r1 > r1
26 $ echo r1 > r1
24 $ hg add r1
27 $ hg add r1
25 $ hg ci -m R1
28 $ hg ci -m R1
26
29
27 $ hg up -q 0
30 $ hg up -q 0
28
31
29 $ hg qnew p0.patch
32 $ hg qnew p0.patch
30 $ echo p0 > p0
33 $ echo p0 > p0
31 $ hg add p0
34 $ hg add p0
32 $ hg qref -m P0
35 $ hg qref -m P0
33
36
34 $ hg qnew p1.patch
37 $ hg qnew p1.patch
35 $ echo p1 > p1
38 $ echo p1 > p1
36 $ hg add p1
39 $ hg add p1
37 $ hg qref -m P1
40 $ hg qref -m P1
38
41
39 $ hg export qtip > p1.patch
42 $ hg export qtip > p1.patch
40
43
41 $ hg up -q -C 1
44 $ hg up -q -C 1
42
45
43 $ hg import p1.patch
46 $ hg import p1.patch
44 applying p1.patch
47 applying p1.patch
45
48
46 $ rm p1.patch
49 $ rm p1.patch
47
50
48 $ hg up -q -C qtip
51 $ hg up -q -C qtip
49
52
50 $ hg rebase
53 $ hg rebase
51 saved backup bundle to $TESTTMP/a/.hg/strip-backup/*-backup.hg (glob)
54 saved backup bundle to $TESTTMP/a/.hg/strip-backup/*-backup.hg (glob)
52
55
53 $ hg tglog
56 $ hg tglog
54 @ 3: 'P0' tags: p0.patch qbase qtip tip
57 @ 3: 'P0' tags: p0.patch qbase qtip tip
55 |
58 |
56 o 2: 'P1' tags: qparent
59 o 2: 'P1' tags: qparent
57 |
60 |
58 o 1: 'R1' tags:
61 o 1: 'R1' tags:
59 |
62 |
60 o 0: 'C1' tags:
63 o 0: 'C1' tags:
61
64
62 $ cd ..
65 $ cd ..
63
66
64
67
65 $ hg init b
68 $ hg init b
66 $ cd b
69 $ cd b
67 $ hg qinit -c
70 $ hg qinit -c
68
71
69 $ for i in r0 r1 r2 r3 r4 r5 r6;
72 $ for i in r0 r1 r2 r3 r4 r5 r6;
70 > do
73 > do
71 > echo $i > $i
74 > echo $i > $i
72 > hg ci -Am $i
75 > hg ci -Am $i
73 > done
76 > done
74 adding r0
77 adding r0
75 adding r1
78 adding r1
76 adding r2
79 adding r2
77 adding r3
80 adding r3
78 adding r4
81 adding r4
79 adding r5
82 adding r5
80 adding r6
83 adding r6
81
84
82 $ hg qimport -r 1:tip
85 $ hg qimport -r 1:tip
83
86
84 $ hg up -q 0
87 $ hg up -q 0
85
88
86 $ for i in r1 r3 r7 r8;
89 $ for i in r1 r3 r7 r8;
87 > do
90 > do
88 > echo $i > $i
91 > echo $i > $i
89 > hg ci -Am branch2-$i
92 > hg ci -Am branch2-$i
90 > done
93 > done
91 adding r1
94 adding r1
92 created new head
95 created new head
93 adding r3
96 adding r3
94 adding r7
97 adding r7
95 adding r8
98 adding r8
96
99
97 $ echo somethingelse > r4
100 $ echo somethingelse > r4
98 $ hg ci -Am branch2-r4
101 $ hg ci -Am branch2-r4
99 adding r4
102 adding r4
100
103
101 $ echo r6 > r6
104 $ echo r6 > r6
102 $ hg ci -Am branch2-r6
105 $ hg ci -Am branch2-r6
103 adding r6
106 adding r6
104
107
105 $ hg up -q qtip
108 $ hg up -q qtip
106
109
107 $ HGMERGE=internal:fail hg rebase
110 $ HGMERGE=internal:fail hg rebase
108 abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
111 abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
109 [255]
112 [255]
110
113
111 $ HGMERGE=internal:local hg resolve --all
114 $ HGMERGE=internal:local hg resolve --all
112
115
113 $ hg rebase --continue
116 $ hg rebase --continue
114 saved backup bundle to $TESTTMP/b/.hg/strip-backup/*-backup.hg (glob)
117 saved backup bundle to $TESTTMP/b/.hg/strip-backup/*-backup.hg (glob)
115
118
116 $ hg tglog
119 $ hg tglog
117 @ 9: 'r5' tags: 5.diff qtip tip
120 @ 9: 'r5' tags: 5.diff qtip tip
118 |
121 |
119 o 8: 'r4' tags: 4.diff
122 o 8: 'r4' tags: 4.diff
120 |
123 |
121 o 7: 'r2' tags: 2.diff qbase
124 o 7: 'r2' tags: 2.diff qbase
122 |
125 |
123 o 6: 'branch2-r6' tags: qparent
126 o 6: 'branch2-r6' tags: qparent
124 |
127 |
125 o 5: 'branch2-r4' tags:
128 o 5: 'branch2-r4' tags:
126 |
129 |
127 o 4: 'branch2-r8' tags:
130 o 4: 'branch2-r8' tags:
128 |
131 |
129 o 3: 'branch2-r7' tags:
132 o 3: 'branch2-r7' tags:
130 |
133 |
131 o 2: 'branch2-r3' tags:
134 o 2: 'branch2-r3' tags:
132 |
135 |
133 o 1: 'branch2-r1' tags:
136 o 1: 'branch2-r1' tags:
134 |
137 |
135 o 0: 'r0' tags:
138 o 0: 'r0' tags:
136
139
@@ -1,108 +1,111 b''
1 $ cat >> $HGRCPATH <<EOF
1 $ cat >> $HGRCPATH <<EOF
2 > [extensions]
2 > [extensions]
3 > graphlog=
3 > graphlog=
4 > rebase=
4 > rebase=
5 >
5 >
6 > [phases]
7 > publish=False
8 >
6 > [alias]
9 > [alias]
7 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
10 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
8 > EOF
11 > EOF
9
12
10 $ hg init a
13 $ hg init a
11 $ cd a
14 $ cd a
12 $ hg unbundle $TESTDIR/bundles/rebase.hg
15 $ hg unbundle $TESTDIR/bundles/rebase.hg
13 adding changesets
16 adding changesets
14 adding manifests
17 adding manifests
15 adding file changes
18 adding file changes
16 added 8 changesets with 7 changes to 7 files (+2 heads)
19 added 8 changesets with 7 changes to 7 files (+2 heads)
17 (run 'hg heads' to see heads, 'hg merge' to merge)
20 (run 'hg heads' to see heads, 'hg merge' to merge)
18 $ hg up tip
21 $ hg up tip
19 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
22 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
20 $ cd ..
23 $ cd ..
21
24
22
25
23 Rebasing descendant onto ancestor across different named branches
26 Rebasing descendant onto ancestor across different named branches
24
27
25 $ hg clone -q -u . a a1
28 $ hg clone -q -u . a a1
26
29
27 $ cd a1
30 $ cd a1
28
31
29 $ hg branch dev
32 $ hg branch dev
30 marked working directory as branch dev
33 marked working directory as branch dev
31 (branches are permanent and global, did you want a bookmark?)
34 (branches are permanent and global, did you want a bookmark?)
32
35
33 $ echo x > x
36 $ echo x > x
34
37
35 $ hg add x
38 $ hg add x
36
39
37 $ hg ci -m 'extra named branch'
40 $ hg ci -m 'extra named branch'
38
41
39 $ hg tglog
42 $ hg tglog
40 @ 8: 'extra named branch' dev
43 @ 8: 'extra named branch' dev
41 |
44 |
42 o 7: 'H'
45 o 7: 'H'
43 |
46 |
44 | o 6: 'G'
47 | o 6: 'G'
45 |/|
48 |/|
46 o | 5: 'F'
49 o | 5: 'F'
47 | |
50 | |
48 | o 4: 'E'
51 | o 4: 'E'
49 |/
52 |/
50 | o 3: 'D'
53 | o 3: 'D'
51 | |
54 | |
52 | o 2: 'C'
55 | o 2: 'C'
53 | |
56 | |
54 | o 1: 'B'
57 | o 1: 'B'
55 |/
58 |/
56 o 0: 'A'
59 o 0: 'A'
57
60
58
61
59
62
60 $ hg rebase -s 1 -d 8 --keepbranches
63 $ hg rebase -s 1 -d 8 --keepbranches
61 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
64 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
62
65
63 $ hg tglog
66 $ hg tglog
64 @ 8: 'D'
67 @ 8: 'D'
65 |
68 |
66 o 7: 'C'
69 o 7: 'C'
67 |
70 |
68 o 6: 'B'
71 o 6: 'B'
69 |
72 |
70 o 5: 'extra named branch' dev
73 o 5: 'extra named branch' dev
71 |
74 |
72 o 4: 'H'
75 o 4: 'H'
73 |
76 |
74 | o 3: 'G'
77 | o 3: 'G'
75 |/|
78 |/|
76 o | 2: 'F'
79 o | 2: 'F'
77 | |
80 | |
78 | o 1: 'E'
81 | o 1: 'E'
79 |/
82 |/
80 o 0: 'A'
83 o 0: 'A'
81
84
82 $ hg rebase -s 4 -d 5
85 $ hg rebase -s 4 -d 5
83 abort: source is ancestor of destination
86 abort: source is ancestor of destination
84 [255]
87 [255]
85
88
86 $ hg rebase -s 5 -d 4
89 $ hg rebase -s 5 -d 4
87 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
90 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
88
91
89 $ hg tglog
92 $ hg tglog
90 @ 8: 'D'
93 @ 8: 'D'
91 |
94 |
92 o 7: 'C'
95 o 7: 'C'
93 |
96 |
94 o 6: 'B'
97 o 6: 'B'
95 |
98 |
96 o 5: 'extra named branch'
99 o 5: 'extra named branch'
97 |
100 |
98 o 4: 'H'
101 o 4: 'H'
99 |
102 |
100 | o 3: 'G'
103 | o 3: 'G'
101 |/|
104 |/|
102 o | 2: 'F'
105 o | 2: 'F'
103 | |
106 | |
104 | o 1: 'E'
107 | o 1: 'E'
105 |/
108 |/
106 o 0: 'A'
109 o 0: 'A'
107
110
108 $ cd ..
111 $ cd ..
@@ -1,389 +1,392 b''
1 $ cat >> $HGRCPATH <<EOF
1 $ cat >> $HGRCPATH <<EOF
2 > [extensions]
2 > [extensions]
3 > graphlog=
3 > graphlog=
4 > rebase=
4 > rebase=
5 >
5 >
6 > [phases]
7 > publish=False
8 >
6 > [alias]
9 > [alias]
7 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
10 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
8 > EOF
11 > EOF
9
12
10
13
11 $ hg init a
14 $ hg init a
12 $ cd a
15 $ cd a
13 $ hg unbundle $TESTDIR/bundles/rebase.hg
16 $ hg unbundle $TESTDIR/bundles/rebase.hg
14 adding changesets
17 adding changesets
15 adding manifests
18 adding manifests
16 adding file changes
19 adding file changes
17 added 8 changesets with 7 changes to 7 files (+2 heads)
20 added 8 changesets with 7 changes to 7 files (+2 heads)
18 (run 'hg heads' to see heads, 'hg merge' to merge)
21 (run 'hg heads' to see heads, 'hg merge' to merge)
19 $ hg up tip
22 $ hg up tip
20 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
23 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
21
24
22 $ echo I > I
25 $ echo I > I
23 $ hg ci -AmI
26 $ hg ci -AmI
24 adding I
27 adding I
25
28
26 $ hg tglog
29 $ hg tglog
27 @ 8: 'I'
30 @ 8: 'I'
28 |
31 |
29 o 7: 'H'
32 o 7: 'H'
30 |
33 |
31 | o 6: 'G'
34 | o 6: 'G'
32 |/|
35 |/|
33 o | 5: 'F'
36 o | 5: 'F'
34 | |
37 | |
35 | o 4: 'E'
38 | o 4: 'E'
36 |/
39 |/
37 | o 3: 'D'
40 | o 3: 'D'
38 | |
41 | |
39 | o 2: 'C'
42 | o 2: 'C'
40 | |
43 | |
41 | o 1: 'B'
44 | o 1: 'B'
42 |/
45 |/
43 o 0: 'A'
46 o 0: 'A'
44
47
45 $ cd ..
48 $ cd ..
46
49
47
50
48 These fail:
51 These fail:
49
52
50 $ hg clone -q -u . a a1
53 $ hg clone -q -u . a a1
51 $ cd a1
54 $ cd a1
52
55
53 $ hg rebase -s 8 -d 7
56 $ hg rebase -s 8 -d 7
54 nothing to rebase
57 nothing to rebase
55 [1]
58 [1]
56
59
57 $ hg rebase --continue --abort
60 $ hg rebase --continue --abort
58 abort: cannot use both abort and continue
61 abort: cannot use both abort and continue
59 [255]
62 [255]
60
63
61 $ hg rebase --continue --collapse
64 $ hg rebase --continue --collapse
62 abort: cannot use collapse with continue or abort
65 abort: cannot use collapse with continue or abort
63 [255]
66 [255]
64
67
65 $ hg rebase --continue --dest 4
68 $ hg rebase --continue --dest 4
66 abort: abort and continue do not allow specifying revisions
69 abort: abort and continue do not allow specifying revisions
67 [255]
70 [255]
68
71
69 $ hg rebase --base 5 --source 4
72 $ hg rebase --base 5 --source 4
70 abort: cannot specify both a source and a base
73 abort: cannot specify both a source and a base
71 [255]
74 [255]
72
75
73 $ hg rebase
76 $ hg rebase
74 nothing to rebase
77 nothing to rebase
75 [1]
78 [1]
76
79
77 $ hg up -q 7
80 $ hg up -q 7
78
81
79 $ hg rebase --traceback
82 $ hg rebase --traceback
80 nothing to rebase
83 nothing to rebase
81 [1]
84 [1]
82
85
83
86
84 These work:
87 These work:
85
88
86 Rebase with no arguments (from 3 onto 8):
89 Rebase with no arguments (from 3 onto 8):
87
90
88 $ hg up -q -C 3
91 $ hg up -q -C 3
89
92
90 $ hg rebase
93 $ hg rebase
91 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
94 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
92
95
93 $ hg tglog
96 $ hg tglog
94 @ 8: 'D'
97 @ 8: 'D'
95 |
98 |
96 o 7: 'C'
99 o 7: 'C'
97 |
100 |
98 o 6: 'B'
101 o 6: 'B'
99 |
102 |
100 o 5: 'I'
103 o 5: 'I'
101 |
104 |
102 o 4: 'H'
105 o 4: 'H'
103 |
106 |
104 | o 3: 'G'
107 | o 3: 'G'
105 |/|
108 |/|
106 o | 2: 'F'
109 o | 2: 'F'
107 | |
110 | |
108 | o 1: 'E'
111 | o 1: 'E'
109 |/
112 |/
110 o 0: 'A'
113 o 0: 'A'
111
114
112 Try to rollback after a rebase (fail):
115 Try to rollback after a rebase (fail):
113
116
114 $ hg rollback
117 $ hg rollback
115 no rollback information available
118 no rollback information available
116 [1]
119 [1]
117
120
118 $ cd ..
121 $ cd ..
119
122
120
123
121 Rebase with base == '.' => same as no arguments (from 3 onto 8):
124 Rebase with base == '.' => same as no arguments (from 3 onto 8):
122
125
123 $ hg clone -q -u 3 a a2
126 $ hg clone -q -u 3 a a2
124 $ cd a2
127 $ cd a2
125
128
126 $ hg rebase --base .
129 $ hg rebase --base .
127 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
130 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
128
131
129 $ hg tglog
132 $ hg tglog
130 @ 8: 'D'
133 @ 8: 'D'
131 |
134 |
132 o 7: 'C'
135 o 7: 'C'
133 |
136 |
134 o 6: 'B'
137 o 6: 'B'
135 |
138 |
136 o 5: 'I'
139 o 5: 'I'
137 |
140 |
138 o 4: 'H'
141 o 4: 'H'
139 |
142 |
140 | o 3: 'G'
143 | o 3: 'G'
141 |/|
144 |/|
142 o | 2: 'F'
145 o | 2: 'F'
143 | |
146 | |
144 | o 1: 'E'
147 | o 1: 'E'
145 |/
148 |/
146 o 0: 'A'
149 o 0: 'A'
147
150
148 $ cd ..
151 $ cd ..
149
152
150
153
151 Rebase with dest == `hg branch` => same as no arguments (from 3 onto 8):
154 Rebase with dest == `hg branch` => same as no arguments (from 3 onto 8):
152
155
153 $ hg clone -q -u 3 a a3
156 $ hg clone -q -u 3 a a3
154 $ cd a3
157 $ cd a3
155
158
156 $ hg rebase --dest `hg branch`
159 $ hg rebase --dest `hg branch`
157 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
160 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
158
161
159 $ hg tglog
162 $ hg tglog
160 @ 8: 'D'
163 @ 8: 'D'
161 |
164 |
162 o 7: 'C'
165 o 7: 'C'
163 |
166 |
164 o 6: 'B'
167 o 6: 'B'
165 |
168 |
166 o 5: 'I'
169 o 5: 'I'
167 |
170 |
168 o 4: 'H'
171 o 4: 'H'
169 |
172 |
170 | o 3: 'G'
173 | o 3: 'G'
171 |/|
174 |/|
172 o | 2: 'F'
175 o | 2: 'F'
173 | |
176 | |
174 | o 1: 'E'
177 | o 1: 'E'
175 |/
178 |/
176 o 0: 'A'
179 o 0: 'A'
177
180
178 $ cd ..
181 $ cd ..
179
182
180
183
181 Specify only source (from 2 onto 8):
184 Specify only source (from 2 onto 8):
182
185
183 $ hg clone -q -u . a a4
186 $ hg clone -q -u . a a4
184 $ cd a4
187 $ cd a4
185
188
186 $ hg rebase --source 2
189 $ hg rebase --source 2
187 saved backup bundle to $TESTTMP/a4/.hg/strip-backup/*-backup.hg (glob)
190 saved backup bundle to $TESTTMP/a4/.hg/strip-backup/*-backup.hg (glob)
188
191
189 $ hg tglog
192 $ hg tglog
190 @ 8: 'D'
193 @ 8: 'D'
191 |
194 |
192 o 7: 'C'
195 o 7: 'C'
193 |\
196 |\
194 | o 6: 'I'
197 | o 6: 'I'
195 | |
198 | |
196 | o 5: 'H'
199 | o 5: 'H'
197 | |
200 | |
198 | | o 4: 'G'
201 | | o 4: 'G'
199 | |/|
202 | |/|
200 | o | 3: 'F'
203 | o | 3: 'F'
201 | | |
204 | | |
202 | | o 2: 'E'
205 | | o 2: 'E'
203 | |/
206 | |/
204 o | 1: 'B'
207 o | 1: 'B'
205 |/
208 |/
206 o 0: 'A'
209 o 0: 'A'
207
210
208 $ cd ..
211 $ cd ..
209
212
210
213
211 Specify only dest (from 3 onto 6):
214 Specify only dest (from 3 onto 6):
212
215
213 $ hg clone -q -u 3 a a5
216 $ hg clone -q -u 3 a a5
214 $ cd a5
217 $ cd a5
215
218
216 $ hg rebase --dest 6
219 $ hg rebase --dest 6
217 saved backup bundle to $TESTTMP/a5/.hg/strip-backup/*-backup.hg (glob)
220 saved backup bundle to $TESTTMP/a5/.hg/strip-backup/*-backup.hg (glob)
218
221
219 $ hg tglog
222 $ hg tglog
220 @ 8: 'D'
223 @ 8: 'D'
221 |
224 |
222 o 7: 'C'
225 o 7: 'C'
223 |
226 |
224 o 6: 'B'
227 o 6: 'B'
225 |
228 |
226 | o 5: 'I'
229 | o 5: 'I'
227 | |
230 | |
228 | o 4: 'H'
231 | o 4: 'H'
229 | |
232 | |
230 o | 3: 'G'
233 o | 3: 'G'
231 |\|
234 |\|
232 | o 2: 'F'
235 | o 2: 'F'
233 | |
236 | |
234 o | 1: 'E'
237 o | 1: 'E'
235 |/
238 |/
236 o 0: 'A'
239 o 0: 'A'
237
240
238 $ cd ..
241 $ cd ..
239
242
240
243
241 Specify only base (from 1 onto 8):
244 Specify only base (from 1 onto 8):
242
245
243 $ hg clone -q -u . a a6
246 $ hg clone -q -u . a a6
244 $ cd a6
247 $ cd a6
245
248
246 $ hg rebase --base 3
249 $ hg rebase --base 3
247 saved backup bundle to $TESTTMP/a6/.hg/strip-backup/*-backup.hg (glob)
250 saved backup bundle to $TESTTMP/a6/.hg/strip-backup/*-backup.hg (glob)
248
251
249 $ hg tglog
252 $ hg tglog
250 @ 8: 'D'
253 @ 8: 'D'
251 |
254 |
252 o 7: 'C'
255 o 7: 'C'
253 |
256 |
254 o 6: 'B'
257 o 6: 'B'
255 |
258 |
256 o 5: 'I'
259 o 5: 'I'
257 |
260 |
258 o 4: 'H'
261 o 4: 'H'
259 |
262 |
260 | o 3: 'G'
263 | o 3: 'G'
261 |/|
264 |/|
262 o | 2: 'F'
265 o | 2: 'F'
263 | |
266 | |
264 | o 1: 'E'
267 | o 1: 'E'
265 |/
268 |/
266 o 0: 'A'
269 o 0: 'A'
267
270
268 $ cd ..
271 $ cd ..
269
272
270
273
271 Specify source and dest (from 2 onto 7):
274 Specify source and dest (from 2 onto 7):
272
275
273 $ hg clone -q -u . a a7
276 $ hg clone -q -u . a a7
274 $ cd a7
277 $ cd a7
275
278
276 $ hg rebase --detach --source 2 --dest 7
279 $ hg rebase --detach --source 2 --dest 7
277 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/*-backup.hg (glob)
280 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/*-backup.hg (glob)
278
281
279 $ hg tglog
282 $ hg tglog
280 @ 8: 'D'
283 @ 8: 'D'
281 |
284 |
282 o 7: 'C'
285 o 7: 'C'
283 |
286 |
284 | o 6: 'I'
287 | o 6: 'I'
285 |/
288 |/
286 o 5: 'H'
289 o 5: 'H'
287 |
290 |
288 | o 4: 'G'
291 | o 4: 'G'
289 |/|
292 |/|
290 o | 3: 'F'
293 o | 3: 'F'
291 | |
294 | |
292 | o 2: 'E'
295 | o 2: 'E'
293 |/
296 |/
294 | o 1: 'B'
297 | o 1: 'B'
295 |/
298 |/
296 o 0: 'A'
299 o 0: 'A'
297
300
298 $ cd ..
301 $ cd ..
299
302
300
303
301 Specify base and dest (from 1 onto 7):
304 Specify base and dest (from 1 onto 7):
302
305
303 $ hg clone -q -u . a a8
306 $ hg clone -q -u . a a8
304 $ cd a8
307 $ cd a8
305
308
306 $ hg rebase --base 3 --dest 7
309 $ hg rebase --base 3 --dest 7
307 saved backup bundle to $TESTTMP/a8/.hg/strip-backup/*-backup.hg (glob)
310 saved backup bundle to $TESTTMP/a8/.hg/strip-backup/*-backup.hg (glob)
308
311
309 $ hg tglog
312 $ hg tglog
310 @ 8: 'D'
313 @ 8: 'D'
311 |
314 |
312 o 7: 'C'
315 o 7: 'C'
313 |
316 |
314 o 6: 'B'
317 o 6: 'B'
315 |
318 |
316 | o 5: 'I'
319 | o 5: 'I'
317 |/
320 |/
318 o 4: 'H'
321 o 4: 'H'
319 |
322 |
320 | o 3: 'G'
323 | o 3: 'G'
321 |/|
324 |/|
322 o | 2: 'F'
325 o | 2: 'F'
323 | |
326 | |
324 | o 1: 'E'
327 | o 1: 'E'
325 |/
328 |/
326 o 0: 'A'
329 o 0: 'A'
327
330
328 $ cd ..
331 $ cd ..
329
332
330 Test --tool parameter:
333 Test --tool parameter:
331
334
332 $ hg init b
335 $ hg init b
333 $ cd b
336 $ cd b
334
337
335 $ echo c1 > c1
338 $ echo c1 > c1
336 $ hg ci -Am c1
339 $ hg ci -Am c1
337 adding c1
340 adding c1
338
341
339 $ echo c2 > c2
342 $ echo c2 > c2
340 $ hg ci -Am c2
343 $ hg ci -Am c2
341 adding c2
344 adding c2
342
345
343 $ hg up -q 0
346 $ hg up -q 0
344 $ echo c2b > c2
347 $ echo c2b > c2
345 $ hg ci -Am c2b
348 $ hg ci -Am c2b
346 adding c2
349 adding c2
347 created new head
350 created new head
348
351
349 $ cd ..
352 $ cd ..
350
353
351 $ hg clone -q -u . b b1
354 $ hg clone -q -u . b b1
352 $ cd b1
355 $ cd b1
353
356
354 $ hg rebase -s 2 -d 1 --tool internal:local
357 $ hg rebase -s 2 -d 1 --tool internal:local
355 saved backup bundle to $TESTTMP/b1/.hg/strip-backup/*-backup.hg (glob)
358 saved backup bundle to $TESTTMP/b1/.hg/strip-backup/*-backup.hg (glob)
356
359
357 $ hg cat c2
360 $ hg cat c2
358 c2
361 c2
359
362
360 $ cd ..
363 $ cd ..
361
364
362
365
363 $ hg clone -q -u . b b2
366 $ hg clone -q -u . b b2
364 $ cd b2
367 $ cd b2
365
368
366 $ hg rebase -s 2 -d 1 --tool internal:other
369 $ hg rebase -s 2 -d 1 --tool internal:other
367 saved backup bundle to $TESTTMP/b2/.hg/strip-backup/*-backup.hg (glob)
370 saved backup bundle to $TESTTMP/b2/.hg/strip-backup/*-backup.hg (glob)
368
371
369 $ hg cat c2
372 $ hg cat c2
370 c2b
373 c2b
371
374
372 $ cd ..
375 $ cd ..
373
376
374
377
375 $ hg clone -q -u . b b3
378 $ hg clone -q -u . b b3
376 $ cd b3
379 $ cd b3
377
380
378 $ hg rebase -s 2 -d 1 --tool internal:fail
381 $ hg rebase -s 2 -d 1 --tool internal:fail
379 abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
382 abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
380 [255]
383 [255]
381
384
382 $ hg resolve -l
385 $ hg resolve -l
383 U c2
386 U c2
384
387
385 $ hg resolve -m c2
388 $ hg resolve -m c2
386 $ hg rebase -c --tool internal:fail
389 $ hg rebase -c --tool internal:fail
387 tool option will be ignored
390 tool option will be ignored
388 saved backup bundle to $TESTTMP/b3/.hg/strip-backup/*-backup.hg (glob)
391 saved backup bundle to $TESTTMP/b3/.hg/strip-backup/*-backup.hg (glob)
389
392
@@ -1,508 +1,521 b''
1 $ cat >> $HGRCPATH <<EOF
1 $ cat >> $HGRCPATH <<EOF
2 > [extensions]
2 > [extensions]
3 > graphlog=
3 > graphlog=
4 > rebase=
4 > rebase=
5 >
5 >
6 > [phases]
7 > publish=False
8 >
6 > [alias]
9 > [alias]
7 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
10 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
8 > EOF
11 > EOF
9
12
10
13
11 $ hg init a
14 $ hg init a
12 $ cd a
15 $ cd a
13 $ hg unbundle $TESTDIR/bundles/rebase.hg
16 $ hg unbundle $TESTDIR/bundles/rebase.hg
14 adding changesets
17 adding changesets
15 adding manifests
18 adding manifests
16 adding file changes
19 adding file changes
17 added 8 changesets with 7 changes to 7 files (+2 heads)
20 added 8 changesets with 7 changes to 7 files (+2 heads)
18 (run 'hg heads' to see heads, 'hg merge' to merge)
21 (run 'hg heads' to see heads, 'hg merge' to merge)
19 $ hg up tip
22 $ hg up tip
20 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
23 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
21 $ cd ..
24 $ cd ..
22
25
23
26
24 Rebasing
27 Rebasing
25 D onto H - simple rebase:
28 D onto H - simple rebase:
26
29
27 $ hg clone -q -u . a a1
30 $ hg clone -q -u . a a1
28 $ cd a1
31 $ cd a1
29
32
30 $ hg tglog
33 $ hg tglog
31 @ 7: 'H'
34 @ 7: 'H'
32 |
35 |
33 | o 6: 'G'
36 | o 6: 'G'
34 |/|
37 |/|
35 o | 5: 'F'
38 o | 5: 'F'
36 | |
39 | |
37 | o 4: 'E'
40 | o 4: 'E'
38 |/
41 |/
39 | o 3: 'D'
42 | o 3: 'D'
40 | |
43 | |
41 | o 2: 'C'
44 | o 2: 'C'
42 | |
45 | |
43 | o 1: 'B'
46 | o 1: 'B'
44 |/
47 |/
45 o 0: 'A'
48 o 0: 'A'
46
49
47
50
48 $ hg rebase -s 3 -d 7
51 $ hg rebase -s 3 -d 7
49 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
52 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
50
53
51 $ hg tglog
54 $ hg tglog
52 @ 7: 'D'
55 @ 7: 'D'
53 |\
56 |\
54 | o 6: 'H'
57 | o 6: 'H'
55 | |
58 | |
56 | | o 5: 'G'
59 | | o 5: 'G'
57 | |/|
60 | |/|
58 | o | 4: 'F'
61 | o | 4: 'F'
59 | | |
62 | | |
60 | | o 3: 'E'
63 | | o 3: 'E'
61 | |/
64 | |/
62 o | 2: 'C'
65 o | 2: 'C'
63 | |
66 | |
64 o | 1: 'B'
67 o | 1: 'B'
65 |/
68 |/
66 o 0: 'A'
69 o 0: 'A'
67
70
68 $ cd ..
71 $ cd ..
69
72
70
73
71 D onto F - intermediate point:
74 D onto F - intermediate point:
72
75
73 $ hg clone -q -u . a a2
76 $ hg clone -q -u . a a2
74 $ cd a2
77 $ cd a2
75
78
76 $ hg rebase -s 3 -d 5
79 $ hg rebase -s 3 -d 5
77 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
80 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
78
81
79 $ hg tglog
82 $ hg tglog
80 @ 7: 'D'
83 @ 7: 'D'
81 |\
84 |\
82 | | o 6: 'H'
85 | | o 6: 'H'
83 | |/
86 | |/
84 | | o 5: 'G'
87 | | o 5: 'G'
85 | |/|
88 | |/|
86 | o | 4: 'F'
89 | o | 4: 'F'
87 | | |
90 | | |
88 | | o 3: 'E'
91 | | o 3: 'E'
89 | |/
92 | |/
90 o | 2: 'C'
93 o | 2: 'C'
91 | |
94 | |
92 o | 1: 'B'
95 o | 1: 'B'
93 |/
96 |/
94 o 0: 'A'
97 o 0: 'A'
95
98
96 $ cd ..
99 $ cd ..
97
100
98
101
99 E onto H - skip of G:
102 E onto H - skip of G:
100
103
101 $ hg clone -q -u . a a3
104 $ hg clone -q -u . a a3
102 $ cd a3
105 $ cd a3
103
106
104 $ hg rebase -s 4 -d 7
107 $ hg rebase -s 4 -d 7
105 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
108 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
106
109
107 $ hg tglog
110 $ hg tglog
108 @ 6: 'E'
111 @ 6: 'E'
109 |
112 |
110 o 5: 'H'
113 o 5: 'H'
111 |
114 |
112 o 4: 'F'
115 o 4: 'F'
113 |
116 |
114 | o 3: 'D'
117 | o 3: 'D'
115 | |
118 | |
116 | o 2: 'C'
119 | o 2: 'C'
117 | |
120 | |
118 | o 1: 'B'
121 | o 1: 'B'
119 |/
122 |/
120 o 0: 'A'
123 o 0: 'A'
121
124
122 $ cd ..
125 $ cd ..
123
126
124
127
125 F onto E - rebase of a branching point (skip G):
128 F onto E - rebase of a branching point (skip G):
126
129
127 $ hg clone -q -u . a a4
130 $ hg clone -q -u . a a4
128 $ cd a4
131 $ cd a4
129
132
130 $ hg rebase -s 5 -d 4
133 $ hg rebase -s 5 -d 4
131 saved backup bundle to $TESTTMP/a4/.hg/strip-backup/*-backup.hg (glob)
134 saved backup bundle to $TESTTMP/a4/.hg/strip-backup/*-backup.hg (glob)
132
135
133 $ hg tglog
136 $ hg tglog
134 @ 6: 'H'
137 @ 6: 'H'
135 |
138 |
136 o 5: 'F'
139 o 5: 'F'
137 |
140 |
138 o 4: 'E'
141 o 4: 'E'
139 |
142 |
140 | o 3: 'D'
143 | o 3: 'D'
141 | |
144 | |
142 | o 2: 'C'
145 | o 2: 'C'
143 | |
146 | |
144 | o 1: 'B'
147 | o 1: 'B'
145 |/
148 |/
146 o 0: 'A'
149 o 0: 'A'
147
150
148 $ cd ..
151 $ cd ..
149
152
150
153
151 G onto H - merged revision having a parent in ancestors of target:
154 G onto H - merged revision having a parent in ancestors of target:
152
155
153 $ hg clone -q -u . a a5
156 $ hg clone -q -u . a a5
154 $ cd a5
157 $ cd a5
155
158
156 $ hg rebase -s 6 -d 7
159 $ hg rebase -s 6 -d 7
157 saved backup bundle to $TESTTMP/a5/.hg/strip-backup/*-backup.hg (glob)
160 saved backup bundle to $TESTTMP/a5/.hg/strip-backup/*-backup.hg (glob)
158
161
159 $ hg tglog
162 $ hg tglog
160 @ 7: 'G'
163 @ 7: 'G'
161 |\
164 |\
162 | o 6: 'H'
165 | o 6: 'H'
163 | |
166 | |
164 | o 5: 'F'
167 | o 5: 'F'
165 | |
168 | |
166 o | 4: 'E'
169 o | 4: 'E'
167 |/
170 |/
168 | o 3: 'D'
171 | o 3: 'D'
169 | |
172 | |
170 | o 2: 'C'
173 | o 2: 'C'
171 | |
174 | |
172 | o 1: 'B'
175 | o 1: 'B'
173 |/
176 |/
174 o 0: 'A'
177 o 0: 'A'
175
178
176 $ cd ..
179 $ cd ..
177
180
178
181
179 F onto B - G maintains E as parent:
182 F onto B - G maintains E as parent:
180
183
181 $ hg clone -q -u . a a6
184 $ hg clone -q -u . a a6
182 $ cd a6
185 $ cd a6
183
186
184 $ hg rebase -s 5 -d 1
187 $ hg rebase -s 5 -d 1
185 saved backup bundle to $TESTTMP/a6/.hg/strip-backup/*-backup.hg (glob)
188 saved backup bundle to $TESTTMP/a6/.hg/strip-backup/*-backup.hg (glob)
186
189
187 $ hg tglog
190 $ hg tglog
188 @ 7: 'H'
191 @ 7: 'H'
189 |
192 |
190 | o 6: 'G'
193 | o 6: 'G'
191 |/|
194 |/|
192 o | 5: 'F'
195 o | 5: 'F'
193 | |
196 | |
194 | o 4: 'E'
197 | o 4: 'E'
195 | |
198 | |
196 | | o 3: 'D'
199 | | o 3: 'D'
197 | | |
200 | | |
198 +---o 2: 'C'
201 +---o 2: 'C'
199 | |
202 | |
200 o | 1: 'B'
203 o | 1: 'B'
201 |/
204 |/
202 o 0: 'A'
205 o 0: 'A'
203
206
204 $ cd ..
207 $ cd ..
205
208
206
209
207 These will fail (using --source):
210 These will fail (using --source):
208
211
209 G onto F - rebase onto an ancestor:
212 G onto F - rebase onto an ancestor:
210
213
211 $ hg clone -q -u . a a7
214 $ hg clone -q -u . a a7
212 $ cd a7
215 $ cd a7
213
216
214 $ hg rebase -s 6 -d 5
217 $ hg rebase -s 6 -d 5
215 nothing to rebase
218 nothing to rebase
216 [1]
219 [1]
217
220
218 F onto G - rebase onto a descendant:
221 F onto G - rebase onto a descendant:
219
222
220 $ hg rebase -s 5 -d 6
223 $ hg rebase -s 5 -d 6
221 abort: source is ancestor of destination
224 abort: source is ancestor of destination
222 [255]
225 [255]
223
226
224 G onto B - merge revision with both parents not in ancestors of target:
227 G onto B - merge revision with both parents not in ancestors of target:
225
228
226 $ hg rebase -s 6 -d 1
229 $ hg rebase -s 6 -d 1
227 abort: cannot use revision 6 as base, result would have 3 parents
230 abort: cannot use revision 6 as base, result would have 3 parents
228 [255]
231 [255]
229
232
230
233
231 These will abort gracefully (using --base):
234 These will abort gracefully (using --base):
232
235
233 G onto G - rebase onto same changeset:
236 G onto G - rebase onto same changeset:
234
237
235 $ hg rebase -b 6 -d 6
238 $ hg rebase -b 6 -d 6
236 nothing to rebase
239 nothing to rebase
237 [1]
240 [1]
238
241
239 G onto F - rebase onto an ancestor:
242 G onto F - rebase onto an ancestor:
240
243
241 $ hg rebase -b 6 -d 5
244 $ hg rebase -b 6 -d 5
242 nothing to rebase
245 nothing to rebase
243 [1]
246 [1]
244
247
245 F onto G - rebase onto a descendant:
248 F onto G - rebase onto a descendant:
246
249
247 $ hg rebase -b 5 -d 6
250 $ hg rebase -b 5 -d 6
248 nothing to rebase
251 nothing to rebase
249 [1]
252 [1]
250
253
251 C onto A - rebase onto an ancestor:
254 C onto A - rebase onto an ancestor:
252
255
253 $ hg rebase -d 0 -s 2
256 $ hg rebase -d 0 -s 2
254 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/5fddd98957c8-backup.hg (glob)
257 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/5fddd98957c8-backup.hg (glob)
255 $ hg tglog
258 $ hg tglog
256 @ 7: 'D'
259 @ 7: 'D'
257 |
260 |
258 o 6: 'C'
261 o 6: 'C'
259 |
262 |
260 | o 5: 'H'
263 | o 5: 'H'
261 | |
264 | |
262 | | o 4: 'G'
265 | | o 4: 'G'
263 | |/|
266 | |/|
264 | o | 3: 'F'
267 | o | 3: 'F'
265 |/ /
268 |/ /
266 | o 2: 'E'
269 | o 2: 'E'
267 |/
270 |/
268 | o 1: 'B'
271 | o 1: 'B'
269 |/
272 |/
270 o 0: 'A'
273 o 0: 'A'
271
274
275
276 Check rebasing public changeset
277
278 $ hg pull --config phases.publish=True -q -r 6 . # update phase of 6
279 $ hg rebase -d 5 -b 6
280 abort: Can't rebase immutable changeset e1c4361dd923
281 (see hg help phases for details)
282 [255]
283
284 $ hg rebase -d 5 -b 6 --keep
272 $ cd ..
285 $ cd ..
273
286
274 Test for revset
287 Test for revset
275
288
276 We need a bit different graph
289 We need a bit different graph
277 All destination are B
290 All destination are B
278
291
279 $ hg init ah
292 $ hg init ah
280 $ cd ah
293 $ cd ah
281 $ hg unbundle $TESTDIR/bundles/rebase-revset.hg
294 $ hg unbundle $TESTDIR/bundles/rebase-revset.hg
282 adding changesets
295 adding changesets
283 adding manifests
296 adding manifests
284 adding file changes
297 adding file changes
285 added 9 changesets with 9 changes to 9 files (+2 heads)
298 added 9 changesets with 9 changes to 9 files (+2 heads)
286 (run 'hg heads' to see heads, 'hg merge' to merge)
299 (run 'hg heads' to see heads, 'hg merge' to merge)
287 $ hg tglog
300 $ hg tglog
288 o 8: 'I'
301 o 8: 'I'
289 |
302 |
290 o 7: 'H'
303 o 7: 'H'
291 |
304 |
292 o 6: 'G'
305 o 6: 'G'
293 |
306 |
294 | o 5: 'F'
307 | o 5: 'F'
295 | |
308 | |
296 | o 4: 'E'
309 | o 4: 'E'
297 |/
310 |/
298 o 3: 'D'
311 o 3: 'D'
299 |
312 |
300 o 2: 'C'
313 o 2: 'C'
301 |
314 |
302 | o 1: 'B'
315 | o 1: 'B'
303 |/
316 |/
304 o 0: 'A'
317 o 0: 'A'
305
318
306 $ cd ..
319 $ cd ..
307
320
308
321
309 Simple case with keep:
322 Simple case with keep:
310
323
311 Source on have two descendant heads but ask for one
324 Source on have two descendant heads but ask for one
312
325
313 $ hg clone -q -u . ah ah1
326 $ hg clone -q -u . ah ah1
314 $ cd ah1
327 $ cd ah1
315 $ hg rebase -r '2::8' -d 1
328 $ hg rebase -r '2::8' -d 1
316 abort: can't remove original changesets with unrebased descendants
329 abort: can't remove original changesets with unrebased descendants
317 (use --keep to keep original changesets)
330 (use --keep to keep original changesets)
318 [255]
331 [255]
319 $ hg rebase -r '2::8' -d 1 --keep
332 $ hg rebase -r '2::8' -d 1 --keep
320 $ hg tglog
333 $ hg tglog
321 @ 13: 'I'
334 @ 13: 'I'
322 |
335 |
323 o 12: 'H'
336 o 12: 'H'
324 |
337 |
325 o 11: 'G'
338 o 11: 'G'
326 |
339 |
327 o 10: 'D'
340 o 10: 'D'
328 |
341 |
329 o 9: 'C'
342 o 9: 'C'
330 |
343 |
331 | o 8: 'I'
344 | o 8: 'I'
332 | |
345 | |
333 | o 7: 'H'
346 | o 7: 'H'
334 | |
347 | |
335 | o 6: 'G'
348 | o 6: 'G'
336 | |
349 | |
337 | | o 5: 'F'
350 | | o 5: 'F'
338 | | |
351 | | |
339 | | o 4: 'E'
352 | | o 4: 'E'
340 | |/
353 | |/
341 | o 3: 'D'
354 | o 3: 'D'
342 | |
355 | |
343 | o 2: 'C'
356 | o 2: 'C'
344 | |
357 | |
345 o | 1: 'B'
358 o | 1: 'B'
346 |/
359 |/
347 o 0: 'A'
360 o 0: 'A'
348
361
349
362
350 $ cd ..
363 $ cd ..
351
364
352 Base on have one descendant heads we ask for but common ancestor have two
365 Base on have one descendant heads we ask for but common ancestor have two
353
366
354 $ hg clone -q -u . ah ah2
367 $ hg clone -q -u . ah ah2
355 $ cd ah2
368 $ cd ah2
356 $ hg rebase -r '3::8' -d 1
369 $ hg rebase -r '3::8' -d 1
357 abort: can't remove original changesets with unrebased descendants
370 abort: can't remove original changesets with unrebased descendants
358 (use --keep to keep original changesets)
371 (use --keep to keep original changesets)
359 [255]
372 [255]
360 $ hg rebase -r '3::8' -d 1 --keep
373 $ hg rebase -r '3::8' -d 1 --keep
361 $ hg tglog
374 $ hg tglog
362 @ 12: 'I'
375 @ 12: 'I'
363 |
376 |
364 o 11: 'H'
377 o 11: 'H'
365 |
378 |
366 o 10: 'G'
379 o 10: 'G'
367 |
380 |
368 o 9: 'D'
381 o 9: 'D'
369 |\
382 |\
370 | | o 8: 'I'
383 | | o 8: 'I'
371 | | |
384 | | |
372 | | o 7: 'H'
385 | | o 7: 'H'
373 | | |
386 | | |
374 | | o 6: 'G'
387 | | o 6: 'G'
375 | | |
388 | | |
376 | | | o 5: 'F'
389 | | | o 5: 'F'
377 | | | |
390 | | | |
378 | | | o 4: 'E'
391 | | | o 4: 'E'
379 | | |/
392 | | |/
380 | | o 3: 'D'
393 | | o 3: 'D'
381 | |/
394 | |/
382 | o 2: 'C'
395 | o 2: 'C'
383 | |
396 | |
384 o | 1: 'B'
397 o | 1: 'B'
385 |/
398 |/
386 o 0: 'A'
399 o 0: 'A'
387
400
388
401
389 $ cd ..
402 $ cd ..
390
403
391 rebase subset
404 rebase subset
392
405
393 $ hg clone -q -u . ah ah3
406 $ hg clone -q -u . ah ah3
394 $ cd ah3
407 $ cd ah3
395 $ hg rebase -r '3::7' -d 1
408 $ hg rebase -r '3::7' -d 1
396 abort: can't remove original changesets with unrebased descendants
409 abort: can't remove original changesets with unrebased descendants
397 (use --keep to keep original changesets)
410 (use --keep to keep original changesets)
398 [255]
411 [255]
399 $ hg rebase -r '3::7' -d 1 --keep
412 $ hg rebase -r '3::7' -d 1 --keep
400 $ hg tglog
413 $ hg tglog
401 @ 11: 'H'
414 @ 11: 'H'
402 |
415 |
403 o 10: 'G'
416 o 10: 'G'
404 |
417 |
405 o 9: 'D'
418 o 9: 'D'
406 |\
419 |\
407 | | o 8: 'I'
420 | | o 8: 'I'
408 | | |
421 | | |
409 | | o 7: 'H'
422 | | o 7: 'H'
410 | | |
423 | | |
411 | | o 6: 'G'
424 | | o 6: 'G'
412 | | |
425 | | |
413 | | | o 5: 'F'
426 | | | o 5: 'F'
414 | | | |
427 | | | |
415 | | | o 4: 'E'
428 | | | o 4: 'E'
416 | | |/
429 | | |/
417 | | o 3: 'D'
430 | | o 3: 'D'
418 | |/
431 | |/
419 | o 2: 'C'
432 | o 2: 'C'
420 | |
433 | |
421 o | 1: 'B'
434 o | 1: 'B'
422 |/
435 |/
423 o 0: 'A'
436 o 0: 'A'
424
437
425
438
426 $ cd ..
439 $ cd ..
427
440
428 rebase subset with multiple head
441 rebase subset with multiple head
429
442
430 $ hg clone -q -u . ah ah4
443 $ hg clone -q -u . ah ah4
431 $ cd ah4
444 $ cd ah4
432 $ hg rebase -r '3::(7+5)' -d 1
445 $ hg rebase -r '3::(7+5)' -d 1
433 abort: can't remove original changesets with unrebased descendants
446 abort: can't remove original changesets with unrebased descendants
434 (use --keep to keep original changesets)
447 (use --keep to keep original changesets)
435 [255]
448 [255]
436 $ hg rebase -r '3::(7+5)' -d 1 --keep
449 $ hg rebase -r '3::(7+5)' -d 1 --keep
437 $ hg tglog
450 $ hg tglog
438 @ 13: 'H'
451 @ 13: 'H'
439 |
452 |
440 o 12: 'G'
453 o 12: 'G'
441 |
454 |
442 | o 11: 'F'
455 | o 11: 'F'
443 | |
456 | |
444 | o 10: 'E'
457 | o 10: 'E'
445 |/
458 |/
446 o 9: 'D'
459 o 9: 'D'
447 |\
460 |\
448 | | o 8: 'I'
461 | | o 8: 'I'
449 | | |
462 | | |
450 | | o 7: 'H'
463 | | o 7: 'H'
451 | | |
464 | | |
452 | | o 6: 'G'
465 | | o 6: 'G'
453 | | |
466 | | |
454 | | | o 5: 'F'
467 | | | o 5: 'F'
455 | | | |
468 | | | |
456 | | | o 4: 'E'
469 | | | o 4: 'E'
457 | | |/
470 | | |/
458 | | o 3: 'D'
471 | | o 3: 'D'
459 | |/
472 | |/
460 | o 2: 'C'
473 | o 2: 'C'
461 | |
474 | |
462 o | 1: 'B'
475 o | 1: 'B'
463 |/
476 |/
464 o 0: 'A'
477 o 0: 'A'
465
478
466
479
467 $ cd ..
480 $ cd ..
468
481
469 More advanced tests
482 More advanced tests
470
483
471 rebase on ancestor with revset
484 rebase on ancestor with revset
472
485
473 $ hg clone -q -u . ah ah5
486 $ hg clone -q -u . ah ah5
474 $ cd ah5
487 $ cd ah5
475 $ hg rebase -r '6::' -d 2
488 $ hg rebase -r '6::' -d 2
476 saved backup bundle to $TESTTMP/ah5/.hg/strip-backup/3d8a618087a7-backup.hg (glob)
489 saved backup bundle to $TESTTMP/ah5/.hg/strip-backup/3d8a618087a7-backup.hg (glob)
477 $ hg tglog
490 $ hg tglog
478 @ 8: 'I'
491 @ 8: 'I'
479 |
492 |
480 o 7: 'H'
493 o 7: 'H'
481 |
494 |
482 o 6: 'G'
495 o 6: 'G'
483 |
496 |
484 | o 5: 'F'
497 | o 5: 'F'
485 | |
498 | |
486 | o 4: 'E'
499 | o 4: 'E'
487 | |
500 | |
488 | o 3: 'D'
501 | o 3: 'D'
489 |/
502 |/
490 o 2: 'C'
503 o 2: 'C'
491 |
504 |
492 | o 1: 'B'
505 | o 1: 'B'
493 |/
506 |/
494 o 0: 'A'
507 o 0: 'A'
495
508
496 $ cd ..
509 $ cd ..
497
510
498
511
499 rebase with multiple root.
512 rebase with multiple root.
500 We rebase E and G on B
513 We rebase E and G on B
501 We would expect heads are I, F if it was supported
514 We would expect heads are I, F if it was supported
502
515
503 $ hg clone -q -u . ah ah6
516 $ hg clone -q -u . ah ah6
504 $ cd ah6
517 $ cd ah6
505 $ hg rebase -r '(4+6)::' -d 1
518 $ hg rebase -r '(4+6)::' -d 1
506 abort: can't rebase multiple roots
519 abort: can't rebase multiple roots
507 [255]
520 [255]
508 $ cd ..
521 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now