##// 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 3054 ('c', 'continue', False, _('resume interrupted graft')),
3055 3055 ('e', 'edit', False, _('invoke editor on commit messages')),
3056 3056 ('', 'log', None, _('append graft info to log message')),
3057 ('f', 'force', False, _('force graft')),
3057 3058 ('D', 'currentdate', False,
3058 3059 _('record the current date as commit date')),
3059 3060 ('U', 'currentuser', False,
@@ -3077,6 +3078,10 b' def graft(ui, repo, *revs, **opts):'
3077 3078
3078 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 3085 If a graft merge results in conflicts, the graft process is
3081 3086 interrupted so that the current merge can be manually resolved.
3082 3087 Once all conflicts are addressed, the graft process can be
@@ -3151,51 +3156,52 b' def graft(ui, repo, *revs, **opts):'
3151 3156 return -1
3152 3157
3153 3158 # check for ancestors of dest branch
3154 crev = repo['.'].rev()
3155 ancestors = repo.changelog.ancestors([crev], inclusive=True)
3156 # Cannot use x.remove(y) on smart set, this has to be a list.
3157 # XXX make this lazy in the future
3158 revs = list(revs)
3159 # don't mutate while iterating, create a copy
3160 for rev in list(revs):
3161 if rev in ancestors:
3162 ui.warn(_('skipping ancestor revision %s\n') % rev)
3163 # XXX remove on list is slow
3164 revs.remove(rev)
3165 if not revs:
3166 return -1
3167
3168 # analyze revs for earlier grafts
3169 ids = {}
3170 for ctx in repo.set("%ld", revs):
3171 ids[ctx.hex()] = ctx.rev()
3172 n = ctx.extra().get('source')
3173 if n:
3174 ids[n] = ctx.rev()
3175
3176 # check ancestors for earlier grafts
3177 ui.debug('scanning for duplicate grafts\n')
3178
3179 for rev in repo.changelog.findmissingrevs(revs, [crev]):
3180 ctx = repo[rev]
3181 n = ctx.extra().get('source')
3182 if n in ids:
3183 r = repo[n].rev()
3184 if r in revs:
3185 ui.warn(_('skipping revision %s (already grafted to %s)\n')
3186 % (r, rev))
3159 if not opts.get('force'):
3160 crev = repo['.'].rev()
3161 ancestors = repo.changelog.ancestors([crev], inclusive=True)
3162 # Cannot use x.remove(y) on smart set, this has to be a list.
3163 # XXX make this lazy in the future
3164 revs = list(revs)
3165 # don't mutate while iterating, create a copy
3166 for rev in list(revs):
3167 if rev in ancestors:
3168 ui.warn(_('skipping ancestor revision %s\n') % rev)
3169 # XXX remove on list is slow
3170 revs.remove(rev)
3171 if not revs:
3172 return -1
3173
3174 # analyze revs for earlier grafts
3175 ids = {}
3176 for ctx in repo.set("%ld", revs):
3177 ids[ctx.hex()] = ctx.rev()
3178 n = ctx.extra().get('source')
3179 if n:
3180 ids[n] = ctx.rev()
3181
3182 # check ancestors for earlier grafts
3183 ui.debug('scanning for duplicate grafts\n')
3184
3185 for rev in repo.changelog.findmissingrevs(revs, [crev]):
3186 ctx = repo[rev]
3187 n = ctx.extra().get('source')
3188 if n in ids:
3189 r = repo[n].rev()
3190 if r in revs:
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 3202 revs.remove(r)
3188 elif ids[n] in revs:
3189 ui.warn(_('skipping already grafted revision %s '
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
3203 if not revs:
3204 return -1
3199 3205
3200 3206 wlock = repo.wlock()
3201 3207 try:
@@ -257,7 +257,7 b' Show all commands + options'
257 257 debugsuccessorssets:
258 258 debugwalk: include, exclude
259 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 261 grep: print0, all, text, follow, ignore-case, files-with-matches, line-number, rev, user, date, include, exclude
262 262 heads: rev, topo, active, closed, style, template
263 263 help: extension, command, keyword
@@ -631,3 +631,33 b' graft works on complex revset'
631 631 grafting revision 13
632 632 grafting revision 19
633 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