Example #1
0
def concludenode(repo, rev, p1, p2, commitmsg=None, editor=None, extrafn=None,
                 keepbranches=False):
    '''Commit the wd changes with parents p1 and p2. Reuse commit info from rev
    but also store useful information in extra.
    Return node of committed revision.'''
    dsguard = cmdutil.dirstateguard(repo, 'rebase')
    try:
        repo.setparents(repo[p1].node(), repo[p2].node())
        ctx = repo[rev]
        if commitmsg is None:
            commitmsg = ctx.description()
        keepbranch = keepbranches and repo[p1].branch() != ctx.branch()
        extra = {'rebase_source': ctx.hex()}
        if extrafn:
            extrafn(ctx, extra)

        backup = repo.ui.backupconfig('phases', 'new-commit')
        try:
            targetphase = max(ctx.phase(), phases.draft)
            repo.ui.setconfig('phases', 'new-commit', targetphase, 'rebase')
            if keepbranch:
                repo.ui.setconfig('ui', 'allowemptycommit', True)
            # Commit might fail if unresolved files exist
            newnode = repo.commit(text=commitmsg, user=ctx.user(),
                                  date=ctx.date(), extra=extra, editor=editor)
        finally:
            repo.ui.restoreconfig(backup)

        repo.dirstate.setbranch(repo[newnode].branch())
        dsguard.close()
        return newnode
    finally:
        release(dsguard)
Example #2
0
def concludenode(repo, rev, p1, p2, commitmsg=None, editor=None, extrafn=None):
    """Commit the wd changes with parents p1 and p2. Reuse commit info from rev
    but also store useful information in extra.
    Return node of committed revision."""
    dsguard = cmdutil.dirstateguard(repo, "rebase")
    try:
        repo.setparents(repo[p1].node(), repo[p2].node())
        ctx = repo[rev]
        if commitmsg is None:
            commitmsg = ctx.description()
        extra = {"rebase_source": ctx.hex()}
        if extrafn:
            extrafn(ctx, extra)

        backup = repo.ui.backupconfig("phases", "new-commit")
        try:
            targetphase = max(ctx.phase(), phases.draft)
            repo.ui.setconfig("phases", "new-commit", targetphase, "rebase")
            # Commit might fail if unresolved files exist
            newnode = repo.commit(text=commitmsg, user=ctx.user(), date=ctx.date(), extra=extra, editor=editor)
        finally:
            repo.ui.restoreconfig(backup)

        repo.dirstate.setbranch(repo[newnode].branch())
        dsguard.close()
        return newnode
    finally:
        release(dsguard)
Example #3
0
def concludenode(repo, rev, p1, p2, commitmsg=None, editor=None, extrafn=None):
    '''Commit the wd changes with parents p1 and p2. Reuse commit info from rev
    but also store useful information in extra.
    Return node of committed revision.'''
    dsguard = cmdutil.dirstateguard(repo, 'rebase')
    try:
        repo.setparents(repo[p1].node(), repo[p2].node())
        ctx = repo[rev]
        if commitmsg is None:
            commitmsg = ctx.description()
        extra = {'rebase_source': ctx.hex()}
        if extrafn:
            extrafn(ctx, extra)

        backup = repo.ui.backupconfig('phases', 'new-commit')
        try:
            targetphase = max(ctx.phase(), phases.draft)
            repo.ui.setconfig('phases', 'new-commit', targetphase, 'rebase')
            # Commit might fail if unresolved files exist
            newnode = repo.commit(text=commitmsg, user=ctx.user(),
                                  date=ctx.date(), extra=extra, editor=editor)
        finally:
            repo.ui.restoreconfig(backup)

        repo.dirstate.setbranch(repo[newnode].branch())
        dsguard.close()
        return newnode
    finally:
        release(dsguard)
Example #4
0
    def apply(self, repo, source, revmap, merges, opts={}):
        '''apply the revisions in revmap one by one in revision order'''
        revs = sorted(revmap)
        p1, p2 = repo.dirstate.parents()
        pulls = []
        diffopts = patch.difffeatureopts(self.ui, opts)
        diffopts.git = True

        lock = wlock = tr = dsguard = None
        try:
            wlock = repo.wlock()
            dsguard = cmdutil.dirstateguard(repo, 'transplant')
            lock = repo.lock()
            tr = repo.transaction('transplant')
            for rev in revs:
                node = revmap[rev]
                revstr = '%s:%s' % (rev, short(node))

                if self.applied(repo, node, p1):
                    self.ui.warn(_('skipping already applied revision %s\n') %
                                 revstr)
                    continue

                parents = source.changelog.parents(node)
                if not (opts.get('filter') or opts.get('log')):
                    # If the changeset parent is the same as the
                    # wdir's parent, just pull it.
                    if parents[0] == p1:
                        pulls.append(node)
                        p1 = node
                        continue
                    if pulls:
                        if source != repo:
                            exchange.pull(repo, source.peer(), heads=pulls)
                        merge.update(repo, pulls[-1], False, False, None)
                        p1, p2 = repo.dirstate.parents()
                        pulls = []

                domerge = False
                if node in merges:
                    # pulling all the merge revs at once would mean we
                    # couldn't transplant after the latest even if
                    # transplants before them fail.
                    domerge = True
                    if not hasnode(repo, node):
                        exchange.pull(repo, source.peer(), heads=[node])

                skipmerge = False
                if parents[1] != revlog.nullid:
                    if not opts.get('parent'):
                        self.ui.note(_('skipping merge changeset %s:%s\n')
                                     % (rev, short(node)))
                        skipmerge = True
                    else:
                        parent = source.lookup(opts['parent'])
                        if parent not in parents:
                            raise util.Abort(_('%s is not a parent of %s') %
                                             (short(parent), short(node)))
                else:
                    parent = parents[0]

                if skipmerge:
                    patchfile = None
                else:
                    fd, patchfile = tempfile.mkstemp(prefix='hg-transplant-')
                    fp = os.fdopen(fd, 'w')
                    gen = patch.diff(source, parent, node, opts=diffopts)
                    for chunk in gen:
                        fp.write(chunk)
                    fp.close()

                del revmap[rev]
                if patchfile or domerge:
                    try:
                        try:
                            n = self.applyone(repo, node,
                                              source.changelog.read(node),
                                              patchfile, merge=domerge,
                                              log=opts.get('log'),
                                              filter=opts.get('filter'))
                        except TransplantError:
                            # Do not rollback, it is up to the user to
                            # fix the merge or cancel everything
                            tr.close()
                            dsguard.close()
                            raise
                        if n and domerge:
                            self.ui.status(_('%s merged at %s\n') % (revstr,
                                      short(n)))
                        elif n:
                            self.ui.status(_('%s transplanted to %s\n')
                                           % (short(node),
                                              short(n)))
                    finally:
                        if patchfile:
                            os.unlink(patchfile)
            tr.close()
            dsguard.close()
            if pulls:
                exchange.pull(repo, source.peer(), heads=pulls)
                merge.update(repo, pulls[-1], False, False, None)
        finally:
            self.saveseries(revmap, merges)
            self.transplants.write()
            if tr:
                tr.release()
            if lock:
                lock.release()
            if dsguard:
                dsguard.release()
            wlock.release()
Example #5
0
    def apply(self, repo, source, revmap, merges, opts={}):
        '''apply the revisions in revmap one by one in revision order'''
        revs = sorted(revmap)
        p1, p2 = repo.dirstate.parents()
        pulls = []
        diffopts = patch.difffeatureopts(self.ui, opts)
        diffopts.git = True

        lock = wlock = tr = dsguard = None
        try:
            wlock = repo.wlock()
            dsguard = cmdutil.dirstateguard(repo, 'transplant')
            lock = repo.lock()
            tr = repo.transaction('transplant')
            for rev in revs:
                node = revmap[rev]
                revstr = '%s:%s' % (rev, short(node))

                if self.applied(repo, node, p1):
                    self.ui.warn(
                        _('skipping already applied revision %s\n') % revstr)
                    continue

                parents = source.changelog.parents(node)
                if not (opts.get('filter') or opts.get('log')):
                    # If the changeset parent is the same as the
                    # wdir's parent, just pull it.
                    if parents[0] == p1:
                        pulls.append(node)
                        p1 = node
                        continue
                    if pulls:
                        if source != repo:
                            exchange.pull(repo, source.peer(), heads=pulls)
                        merge.update(repo, pulls[-1], False, False, None)
                        p1, p2 = repo.dirstate.parents()
                        pulls = []

                domerge = False
                if node in merges:
                    # pulling all the merge revs at once would mean we
                    # couldn't transplant after the latest even if
                    # transplants before them fail.
                    domerge = True
                    if not hasnode(repo, node):
                        exchange.pull(repo, source.peer(), heads=[node])

                skipmerge = False
                if parents[1] != revlog.nullid:
                    if not opts.get('parent'):
                        self.ui.note(
                            _('skipping merge changeset %s:%s\n') %
                            (rev, short(node)))
                        skipmerge = True
                    else:
                        parent = source.lookup(opts['parent'])
                        if parent not in parents:
                            raise util.Abort(
                                _('%s is not a parent of %s') %
                                (short(parent), short(node)))
                else:
                    parent = parents[0]

                if skipmerge:
                    patchfile = None
                else:
                    fd, patchfile = tempfile.mkstemp(prefix='hg-transplant-')
                    fp = os.fdopen(fd, 'w')
                    gen = patch.diff(source, parent, node, opts=diffopts)
                    for chunk in gen:
                        fp.write(chunk)
                    fp.close()

                del revmap[rev]
                if patchfile or domerge:
                    try:
                        try:
                            n = self.applyone(repo,
                                              node,
                                              source.changelog.read(node),
                                              patchfile,
                                              merge=domerge,
                                              log=opts.get('log'),
                                              filter=opts.get('filter'))
                        except TransplantError:
                            # Do not rollback, it is up to the user to
                            # fix the merge or cancel everything
                            tr.close()
                            dsguard.close()
                            raise
                        if n and domerge:
                            self.ui.status(
                                _('%s merged at %s\n') % (revstr, short(n)))
                        elif n:
                            self.ui.status(
                                _('%s transplanted to %s\n') %
                                (short(node), short(n)))
                    finally:
                        if patchfile:
                            os.unlink(patchfile)
            tr.close()
            dsguard.close()
            if pulls:
                exchange.pull(repo, source.peer(), heads=pulls)
                merge.update(repo, pulls[-1], False, False, None)
        finally:
            self.saveseries(revmap, merges)
            self.transplants.write()
            if tr:
                tr.release()
            if lock:
                lock.release()
            if dsguard:
                dsguard.release()
            wlock.release()