comparison mercurial/commands.py @ 12727:52971985be14

backout: provide linear backout as a default (without --merge option) This changes backouts changeset to retain linear history, .e. it is committed as a child of the working directory parent, not the reverted changeset parent. The default behavior was previously to just commit a reverted change as a child of the backed out changeset - thus creating a new head. Most of the time, you would use the --merge option, as it does not make sense to keep this dangling head as is. The previous behavior could be obtained by using 'hg update --clean .' after a 'hg backout --merge'. The --merge option itself is not affected by this change. There is also still an autocommit of the backout if a merge is not needed, i.e. in case the backout is the parent of the working directory. Previously we had (pwd = parent of the working directory): pwd older backout auto merge backout --merge auto commit With the new linear approach: pwd older backout auto commit backout --merge auto commit auto: commit done by the backout command merge: backout also already committed but explicit merge and commit needed commit: user need to commit the update/merge
author Gilles Moris <gilles.moris@free.fr>
date Fri, 10 Sep 2010 10:28:18 +0200
parents 61c0df2b089a
children 05bd2658bbb3
comparison
equal deleted inserted replaced
12726:61c0df2b089a 12727:52971985be14
202 matchfn, prefix, subrepos=opts.get('subrepos')) 202 matchfn, prefix, subrepos=opts.get('subrepos'))
203 203
204 def backout(ui, repo, node=None, rev=None, **opts): 204 def backout(ui, repo, node=None, rev=None, **opts):
205 '''reverse effect of earlier changeset 205 '''reverse effect of earlier changeset
206 206
207 Commit the backed out changes as a new changeset. The new 207 The backout command merges the reverse effect of the reverted
208 changeset is a child of the backed out changeset. 208 changeset into the working directory.
209 209
210 If you backout a changeset other than the tip, a new head is 210 With the --merge option, it first commits the reverted changes
211 created. This head will be the new tip and you should merge this 211 as a new changeset. This new changeset is a child of the reverted
212 backout changeset with another head. 212 changeset.
213
214 The --merge option remembers the parent of the working directory 213 The --merge option remembers the parent of the working directory
215 before starting the backout, then merges the new head with that 214 before starting the backout, then merges the new head with that
216 changeset afterwards. This saves you from doing the merge by hand. 215 changeset afterwards.
217 The result of this merge is not committed, as with a normal merge. 216 This will result in an explicit merge in the history.
217
218 If you backout a changeset other than the original parent of the
219 working directory, the result of this merge is not committed,
220 as with a normal merge. Otherwise, no merge is needed and the
221 commit is automatic.
222
223 Note that the default behavior (without --merge) has changed in
224 version 1.7. To restore the previous default behavior, use
225 :hg:`backout --merge` and then :hg:`update --clean .` to get rid of
226 the ongoing merge.
218 227
219 See :hg:`help dates` for a list of formats valid for -d/--date. 228 See :hg:`help dates` for a list of formats valid for -d/--date.
220 229
221 Returns 0 on success. 230 Returns 0 on success.
222 ''' 231 '''
266 revert_opts['date'] = None 275 revert_opts['date'] = None
267 revert_opts['all'] = True 276 revert_opts['all'] = True
268 revert_opts['rev'] = hex(parent) 277 revert_opts['rev'] = hex(parent)
269 revert_opts['no_backup'] = None 278 revert_opts['no_backup'] = None
270 revert(ui, repo, **revert_opts) 279 revert(ui, repo, **revert_opts)
280 if not opts.get('merge') and op1 != node:
281 return hg.update(repo, op1)
282
271 commit_opts = opts.copy() 283 commit_opts = opts.copy()
272 commit_opts['addremove'] = False 284 commit_opts['addremove'] = False
273 if not commit_opts['message'] and not commit_opts['logfile']: 285 if not commit_opts['message'] and not commit_opts['logfile']:
274 # we don't translate commit messages 286 # we don't translate commit messages
275 commit_opts['message'] = "Backed out changeset %s" % short(node) 287 commit_opts['message'] = "Backed out changeset %s" % short(node)
277 commit(ui, repo, **commit_opts) 289 commit(ui, repo, **commit_opts)
278 def nice(node): 290 def nice(node):
279 return '%d:%s' % (repo.changelog.rev(node), short(node)) 291 return '%d:%s' % (repo.changelog.rev(node), short(node))
280 ui.status(_('changeset %s backs out changeset %s\n') % 292 ui.status(_('changeset %s backs out changeset %s\n') %
281 (nice(repo.changelog.tip()), nice(node))) 293 (nice(repo.changelog.tip()), nice(node)))
282 if op1 != node: 294 if opts.get('merge') and op1 != node:
283 hg.clean(repo, op1, show_stats=False) 295 hg.clean(repo, op1, show_stats=False)
284 if opts.get('merge'): 296 ui.status(_('merging with changeset %s\n')
285 ui.status(_('merging with changeset %s\n') 297 % nice(repo.changelog.tip()))
286 % nice(repo.changelog.tip())) 298 return hg.merge(repo, hex(repo.changelog.tip()))
287 hg.merge(repo, hex(repo.changelog.tip())) 299 return 0
288 else:
289 ui.status(_('the backout changeset is a new head - '
290 'do not forget to merge\n'))
291 ui.status(_('(use "backout --merge" '
292 'if you want to auto-merge)\n'))
293 300
294 def bisect(ui, repo, rev=None, extra=None, command=None, 301 def bisect(ui, repo, rev=None, extra=None, command=None,
295 reset=None, good=None, bad=None, skip=None, noupdate=None): 302 reset=None, good=None, bad=None, skip=None, noupdate=None):
296 """subdivision search of changesets 303 """subdivision search of changesets
297 304