##// END OF EJS Templates
graft: allow regrafting ancestors with --force (issue3220)
Siddharth Agarwal -
r21979:c2863cfe default
parent child Browse files
Show More
@@ -3054,6 +3054,7 b' def forget(ui, repo, *pats, **opts):'
3054 ('c', 'continue', False, _('resume interrupted graft')),
3054 ('c', 'continue', False, _('resume interrupted graft')),
3055 ('e', 'edit', False, _('invoke editor on commit messages')),
3055 ('e', 'edit', False, _('invoke editor on commit messages')),
3056 ('', 'log', None, _('append graft info to log message')),
3056 ('', 'log', None, _('append graft info to log message')),
3057 ('f', 'force', False, _('force graft')),
3057 ('D', 'currentdate', False,
3058 ('D', 'currentdate', False,
3058 _('record the current date as commit date')),
3059 _('record the current date as commit date')),
3059 ('U', 'currentuser', False,
3060 ('U', 'currentuser', False,
@@ -3077,6 +3078,10 b' def graft(ui, repo, *revs, **opts):'
3077
3078
3078 (grafted from CHANGESETHASH)
3079 (grafted from CHANGESETHASH)
3079
3080
3081 If --force is specified, revisions will be grafted even if they
3082 are already ancestors of or have been grafted to the destination.
3083 This is useful when the revisions have since been backed out.
3084
3080 If a graft merge results in conflicts, the graft process is
3085 If a graft merge results in conflicts, the graft process is
3081 interrupted so that the current merge can be manually resolved.
3086 interrupted so that the current merge can be manually resolved.
3082 Once all conflicts are addressed, the graft process can be
3087 Once all conflicts are addressed, the graft process can be
@@ -3151,51 +3156,52 b' def graft(ui, repo, *revs, **opts):'
3151 return -1
3156 return -1
3152
3157
3153 # check for ancestors of dest branch
3158 # check for ancestors of dest branch
3154 crev = repo['.'].rev()
3159 if not opts.get('force'):
3155 ancestors = repo.changelog.ancestors([crev], inclusive=True)
3160 crev = repo['.'].rev()
3156 # Cannot use x.remove(y) on smart set, this has to be a list.
3161 ancestors = repo.changelog.ancestors([crev], inclusive=True)
3157 # XXX make this lazy in the future
3162 # Cannot use x.remove(y) on smart set, this has to be a list.
3158 revs = list(revs)
3163 # XXX make this lazy in the future
3159 # don't mutate while iterating, create a copy
3164 revs = list(revs)
3160 for rev in list(revs):
3165 # don't mutate while iterating, create a copy
3161 if rev in ancestors:
3166 for rev in list(revs):
3162 ui.warn(_('skipping ancestor revision %s\n') % rev)
3167 if rev in ancestors:
3163 # XXX remove on list is slow
3168 ui.warn(_('skipping ancestor revision %s\n') % rev)
3164 revs.remove(rev)
3169 # XXX remove on list is slow
3165 if not revs:
3170 revs.remove(rev)
3166 return -1
3171 if not revs:
3167
3172 return -1
3168 # analyze revs for earlier grafts
3173
3169 ids = {}
3174 # analyze revs for earlier grafts
3170 for ctx in repo.set("%ld", revs):
3175 ids = {}
3171 ids[ctx.hex()] = ctx.rev()
3176 for ctx in repo.set("%ld", revs):
3172 n = ctx.extra().get('source')
3177 ids[ctx.hex()] = ctx.rev()
3173 if n:
3178 n = ctx.extra().get('source')
3174 ids[n] = ctx.rev()
3179 if n:
3175
3180 ids[n] = ctx.rev()
3176 # check ancestors for earlier grafts
3181
3177 ui.debug('scanning for duplicate grafts\n')
3182 # check ancestors for earlier grafts
3178
3183 ui.debug('scanning for duplicate grafts\n')
3179 for rev in repo.changelog.findmissingrevs(revs, [crev]):
3184
3180 ctx = repo[rev]
3185 for rev in repo.changelog.findmissingrevs(revs, [crev]):
3181 n = ctx.extra().get('source')
3186 ctx = repo[rev]
3182 if n in ids:
3187 n = ctx.extra().get('source')
3183 r = repo[n].rev()
3188 if n in ids:
3184 if r in revs:
3189 r = repo[n].rev()
3185 ui.warn(_('skipping revision %s (already grafted to %s)\n')
3190 if r in revs:
3186 % (r, rev))
3191 ui.warn(_('skipping revision %s (already grafted to %s)\n')
3192 % (r, rev))
3193 revs.remove(r)
3194 elif ids[n] in revs:
3195 ui.warn(_('skipping already grafted revision %s '
3196 '(%s also has origin %d)\n') % (ids[n], rev, r))
3197 revs.remove(ids[n])
3198 elif ctx.hex() in ids:
3199 r = ids[ctx.hex()]
3200 ui.warn(_('skipping already grafted revision %s '
3201 '(was grafted from %d)\n') % (r, rev))
3187 revs.remove(r)
3202 revs.remove(r)
3188 elif ids[n] in revs:
3203 if not revs:
3189 ui.warn(_('skipping already grafted revision %s '
3204 return -1
3190 '(%s also has origin %d)\n') % (ids[n], rev, r))
3191 revs.remove(ids[n])
3192 elif ctx.hex() in ids:
3193 r = ids[ctx.hex()]
3194 ui.warn(_('skipping already grafted revision %s '
3195 '(was grafted from %d)\n') % (r, rev))
3196 revs.remove(r)
3197 if not revs:
3198 return -1
3199
3205
3200 wlock = repo.wlock()
3206 wlock = repo.wlock()
3201 try:
3207 try:
@@ -257,7 +257,7 b' Show all commands + options'
257 debugsuccessorssets:
257 debugsuccessorssets:
258 debugwalk: include, exclude
258 debugwalk: include, exclude
259 debugwireargs: three, four, five, ssh, remotecmd, insecure
259 debugwireargs: three, four, five, ssh, remotecmd, insecure
260 graft: rev, continue, edit, log, currentdate, currentuser, date, user, tool, dry-run
260 graft: rev, continue, edit, log, force, currentdate, currentuser, date, user, tool, dry-run
261 grep: print0, all, text, follow, ignore-case, files-with-matches, line-number, rev, user, date, include, exclude
261 grep: print0, all, text, follow, ignore-case, files-with-matches, line-number, rev, user, date, include, exclude
262 heads: rev, topo, active, closed, style, template
262 heads: rev, topo, active, closed, style, template
263 help: extension, command, keyword
263 help: extension, command, keyword
@@ -631,3 +631,33 b' graft works on complex revset'
631 grafting revision 13
631 grafting revision 13
632 grafting revision 19
632 grafting revision 19
633 merging b
633 merging b
634
635 graft with --force (still doesn't graft merges)
636
637 $ hg graft 19 0 6
638 skipping ungraftable merge revision 6
639 skipping ancestor revision 0
640 skipping already grafted revision 19 (22 also has origin 2)
641 [255]
642 $ hg graft 19 0 6 --force
643 skipping ungraftable merge revision 6
644 grafting revision 19
645 merging b
646 grafting revision 0
647
648 graft --force after backout
649
650 $ echo abc > a
651 $ hg ci -m 28
652 $ hg backout 28
653 reverting a
654 changeset 29:484c03b8dfa4 backs out changeset 28:6c56f0f7f033
655 $ hg graft 28
656 skipping ancestor revision 28
657 [255]
658 $ hg graft 28 --force
659 grafting revision 28
660 merging a
661 $ cat a
662 abc
663
General Comments 0
You need to be logged in to leave comments. Login now