Ejemplo n.º 1
0
    def process(self):
        self.marks.store()  # checkpoint
        new_branch = False
        push_bookmarks = []
        self.parser.read_line()
        for line in self.parser.read_block('done'):
            command = line.split()[0]
            if command not in ('blob', 'commit', 'reset', 'tag', 'feature'):
                die('unhandled command: %s' % line)
            getattr(self, 'do_%s' % command)()

        for ref, node in self.parsed_refs.iteritems():
            if ref.startswith('refs/heads/branches'):
                branch = ref[len('refs/heads/branches'):]
                if git_to_hg_spaces(branch) not in self.hgremote.branches:
                    new_branch = True
            elif ref.startswith('refs/heads/'):
                bookmark = ref[len('refs/heads/'):]
                old = self.hgremote.bookmarks.get(bookmark)
                old = old.hex() if old else ''
                if not pushbookmark(self.repo, bookmark, old, node):
                    continue
                push_bookmarks.append((bookmark, old, hghex(node)))
            elif ref.startswith('refs/tags/'):
                self.write_tag(ref)
            else:
                # transport-helper/fast-export bugs
                log("Fast-export unexpected ref: %s" % ref, "WARNING")
                continue

        success = False
        try:
            self.repo.push(self.hgremote.peer, force=False, newbranch=new_branch)
            for bookmark, old, new in push_bookmarks:
                self.hgremote.peer.pushkey('bookmarks', bookmark, old, new)
            self.marks.store()
            success = True
        except Abort as e:
            # mercurial.error.Abort: push creates new remote head f14531ca4e2d!
            if e.message.startswith("push creates new remote head"):
                self.marks.load()  # restore from checkpoint
                # strip revs, implementation finds min revision from list
                if self.processed_nodes:
                    self.repo.mq.strip(self.repo, self.processed_nodes)
            else:
                die("unknown hg exception: %s" % e)
        # TODO: handle network/other errors?

        for ref in self.parsed_refs:
            if success:
                output("ok %s" % ref)
            else:
                output("error %s non-fast forward" % ref)  # TODO: other errors as well
        output()

        if not success:
            # wait until fast-export finishes to muck with the marks file
            self.remove_processed_git_marks()
Ejemplo n.º 2
0
    def process(self):
        self.marks.store()  # checkpoint
        new_branch = False
        push_bookmarks = []
        self.parser.read_line()
        for line in self.parser.read_block('done'):
            command = line.split()[0]
            if command not in ('blob', 'commit', 'reset', 'tag', 'feature'):
                die('unhandled command: %s' % line)
            getattr(self, 'do_%s' % command)()

        updated_refs = {}
        for ref, node in self.parsed_refs.iteritems():
            if ref.startswith(self.hgremote.prefix):
                # This seems to be a git fast-export bug
                continue
            name, reftype = ref_to_name_reftype(ref)
            name = git_to_hg_spaces(name)
            if reftype == BRANCH:
                if name not in self.hgremote.branches:
                    new_branch = True
            elif reftype == BOOKMARK:
                old = self.hgremote.bookmarks.get(name)
                old = old.hex() if old else ''
                if not pushbookmark(self.repo, name, old, node):
                    continue
                push_bookmarks.append((name, old, hghex(node)))
            elif reftype == TAG:
                self.write_tag(name, node)
            else:
                assert False, "unexpected reftype: %s" % reftype
            updated_refs[ref] = node

        success = False
        try:
            self.repo.push(self.hgremote.peer,
                           force=False,
                           newbranch=new_branch)
            for bookmark, old, new in push_bookmarks:
                self.hgremote.peer.pushkey('bookmarks', bookmark, old, new)
            self.marks.store()
            success = True
        except Abort as e:
            # mercurial.error.Abort: push creates new remote head f14531ca4e2d!
            if e.message.startswith("push creates new remote head"):
                self.marks.load()  # restore from checkpoint
                # strip revs, implementation finds min revision from list
                if self.processed_nodes:
                    self.repo.mq.strip(self.repo, self.processed_nodes)
            else:
                die("unknown hg exception: %s" % e)
        # TODO: handle network/other errors?

        for ref, node in updated_refs.items():
            if success:
                status = ""
                name, reftype = ref_to_name_reftype(ref)
                gitify_ref = self.hgremote.make_gitify_ref(name, reftype)
                last_known_rev = self.marks.tips.get(gitify_ref)
                new_rev = self.repo[node].rev()
                if last_known_rev is not None and last_known_rev == new_rev:
                    # up to date status tells git that nothing has changed
                    # during the push for this ref, which prevents it from
                    # printing pointless status info to the user such as:
                    #  * [new branch]      master -> master
                    status = " up to date"
                output("ok %s%s" % (ref, status))
            else:
                output("error %s non-fast forward" %
                       ref)  # TODO: other errors as well
        output()

        if not success:
            # wait until fast-export finishes to muck with the marks file
            self.remove_processed_git_marks()
Ejemplo n.º 3
0
    def process(self):
        self.marks.store()  # checkpoint
        new_branch = False
        push_bookmarks = []
        self.parser.read_line()
        for line in self.parser.read_block('done'):
            command = line.split()[0]
            if command not in ('blob', 'commit', 'reset', 'tag', 'feature'):
                die('unhandled command: %s' % line)
            getattr(self, 'do_%s' % command)()

        updated_refs = {}
        for ref, node in self.parsed_refs.iteritems():
            if ref.startswith(self.hgremote.prefix):
                # This seems to be a git fast-export bug
                continue
            name, reftype = ref_to_name_reftype(ref)
            name = git_to_hg_spaces(name)
            if reftype == BRANCH:
                if name not in self.hgremote.branches:
                    new_branch = True
            elif reftype == BOOKMARK:
                old = self.hgremote.bookmarks.get(name)
                old = old.hex() if old else ''
                if not pushbookmark(self.repo, name, old, node):
                    continue
                push_bookmarks.append((name, old, hghex(node)))
            elif reftype == TAG:
                self.write_tag(name, node)
            else:
                assert False, "unexpected reftype: %s" % reftype
            updated_refs[ref] = node

        success = False
        try:
            self.repo.push(self.hgremote.peer, force=False, newbranch=new_branch)
            for bookmark, old, new in push_bookmarks:
                self.hgremote.peer.pushkey('bookmarks', bookmark, old, new)
            self.marks.store()
            success = True
        except Abort as e:
            # mercurial.error.Abort: push creates new remote head f14531ca4e2d!
            if e.message.startswith("push creates new remote head"):
                self.marks.load()  # restore from checkpoint
                # strip revs, implementation finds min revision from list
                if self.processed_nodes:
                    self.repo.mq.strip(self.repo, self.processed_nodes)
            else:
                die("unknown hg exception: %s" % e)
        # TODO: handle network/other errors?

        for ref, node in updated_refs.items():
            if success:
                status = ""
                name, reftype = ref_to_name_reftype(ref)
                gitify_ref = self.hgremote.make_gitify_ref(name, reftype)
                last_known_rev = self.marks.tips.get(gitify_ref)
                new_rev = self.repo[node].rev()
                if last_known_rev is not None and last_known_rev == new_rev:
                    # up to date status tells git that nothing has changed
                    # during the push for this ref, which prevents it from
                    # printing pointless status info to the user such as:
                    #  * [new branch]      master -> master
                    status = " up to date"
                output("ok %s%s" % (ref, status))
            else:
                output("error %s non-fast forward" % ref)  # TODO: other errors as well
        output()

        if not success:
            # wait until fast-export finishes to muck with the marks file
            self.remove_processed_git_marks()
Ejemplo n.º 4
0
def do_export(parser):
    p_bmarks = []
    p_revs = {}

    parser.next()

    for line in parser.each_block('done'):
        if parser.check('blob'):
            parse_blob(parser)
        elif parser.check('commit'):
            parse_commit(parser)
        elif parser.check('reset'):
            parse_reset(parser)
        elif parser.check('tag'):
            parse_tag(parser)
        elif parser.check('feature'):
            pass
        else:
            die('unhandled export command: %s' % line)

    need_fetch = False

    for ref, node in parsed_refs.iteritems():
        bnode = hgbin(node) if node else None
        if ref.startswith('refs/heads/branches'):
            branch = ref[len('refs/heads/branches/'):]
            if branch in branches and bnode in branches[branch]:
                # up to date
                continue

            if peer:
                remotemap = peer.branchmap()
                if remotemap and branch in remotemap:
                    heads = [hghex(e) for e in remotemap[branch]]
                    if not check_tip(ref, 'branches', branch, heads):
                        print "error %s fetch first" % ref
                        need_fetch = True
                        continue

            p_revs[bnode] = ref
            print "ok %s" % ref
        elif ref.startswith('refs/heads/'):
            bmark = ref[len('refs/heads/'):]
            new = node
            old = bmarks[bmark].hex() if bmark in bmarks else ''

            if old == new:
                continue

            print "ok %s" % ref
            if bmark != fake_bmark and \
                    not (bmark == 'master' and bmark not in parser.repo._bookmarks):
                p_bmarks.append((ref, bmark, old, new))

            if peer:
                remote_old = peer.listkeys('bookmarks').get(bmark)
                if remote_old:
                    if not check_tip(ref, 'bookmarks', bmark, remote_old):
                        print "error %s fetch first" % ref
                        need_fetch = True
                        continue

            p_revs[bnode] = ref
        elif ref.startswith('refs/tags/'):
            if dry_run:
                print "ok %s" % ref
                continue
            tag = ref[len('refs/tags/'):]
            tag = hgref(tag)
            author, msg = parsed_tags.get(tag, (None, None))
            if mode == 'git':
                if not msg:
                    msg = 'Added tag %s for changeset %s' % (tag, node[:12])
                tagnode, branch = write_tag(parser.repo, tag, node, msg, author)
                p_revs[tagnode] = 'refs/heads/branches/' + gitref(branch)
            else:
                fp = parser.repo.opener('localtags', 'a')
                fp.write('%s %s\n' % (node, tag))
                fp.close()
            p_revs[bnode] = ref
            print "ok %s" % ref
        else:
            # transport-helper/fast-export bugs
            continue

    if need_fetch:
        print
        return

    if dry_run:
        if peer and not force_push:
            checkheads(parser.repo, peer, p_revs)
        print
        return

    if peer:
        if not push(parser.repo, peer, parsed_refs, p_revs):
            # do not update bookmarks
            print
            return

        # update remote bookmarks
        remote_bmarks = peer.listkeys('bookmarks')
        for ref, bmark, old, new in p_bmarks:
            if force_push:
                old = remote_bmarks.get(bmark, '')
            if not peer.pushkey('bookmarks', bmark, old, new):
                print "error %s" % ref
    else:
        # update local bookmarks
        for ref, bmark, old, new in p_bmarks:
            if not bookmarks.pushbookmark(parser.repo, bmark, old, new):
                print "error %s" % ref

    print
Ejemplo n.º 5
0
def do_export(parser):
    p_bmarks = []
    p_revs = {}

    parser.next()

    for line in parser.each_block('done'):
        if parser.check('blob'):
            parse_blob(parser)
        elif parser.check('commit'):
            parse_commit(parser)
        elif parser.check('reset'):
            parse_reset(parser)
        elif parser.check('tag'):
            parse_tag(parser)
        elif parser.check('feature'):
            pass
        else:
            die('unhandled export command: %s' % line)

    need_fetch = False

    for ref, node in parsed_refs.iteritems():
        bnode = hgbin(node) if node else None
        if ref.startswith('refs/heads/branches'):
            branch = ref[len('refs/heads/branches/'):]
            if branch in branches and bnode in branches[branch]:
                # up to date
                continue

            if peer:
                remotemap = peer.branchmap()
                if remotemap and branch in remotemap:
                    heads = [hghex(e) for e in remotemap[branch]]
                    if not check_tip(ref, 'branches', branch, heads):
                        print "error %s fetch first" % ref
                        need_fetch = True
                        continue

            p_revs[bnode] = ref
            print "ok %s" % ref
        elif ref.startswith('refs/heads/'):
            bmark = ref[len('refs/heads/'):]
            new = node
            old = bmarks[bmark].hex() if bmark in bmarks else ''

            if old == new:
                continue

            print "ok %s" % ref
            if bmark != fake_bmark and \
                    not (bmark == 'master' and bmark not in parser.repo._bookmarks):
                p_bmarks.append((ref, bmark, old, new))

            if peer:
                remote_old = peer.listkeys('bookmarks').get(bmark)
                if remote_old:
                    if not check_tip(ref, 'bookmarks', bmark, remote_old):
                        print "error %s fetch first" % ref
                        need_fetch = True
                        continue

            p_revs[bnode] = ref
        elif ref.startswith('refs/tags/'):
            if dry_run:
                print "ok %s" % ref
                continue
            tag = ref[len('refs/tags/'):]
            tag = hgref(tag)
            author, msg = parsed_tags.get(tag, (None, None))
            if mode == 'git':
                if not msg:
                    msg = 'Added tag %s for changeset %s' % (tag, node[:12])
                tagnode, branch = write_tag(parser.repo, tag, node, msg, author)
                p_revs[tagnode] = 'refs/heads/branches/' + gitref(branch)
            else:
                fp = parser.repo.opener('localtags', 'a')
                fp.write('%s %s\n' % (node, tag))
                fp.close()
            p_revs[bnode] = ref
            print "ok %s" % ref
        else:
            # transport-helper/fast-export bugs
            continue

    if need_fetch:
        print
        return

    if dry_run:
        if peer and not force_push:
            checkheads(parser.repo, peer, p_revs)
        print
        return

    if peer:
        if not push(parser.repo, peer, parsed_refs, p_revs):
            # do not update bookmarks
            print
            return

        # update remote bookmarks
        remote_bmarks = peer.listkeys('bookmarks')
        for ref, bmark, old, new in p_bmarks:
            if force_push:
                old = remote_bmarks.get(bmark, '')
            if not peer.pushkey('bookmarks', bmark, old, new):
                print "error %s" % ref
    else:
        # update local bookmarks
        for ref, bmark, old, new in p_bmarks:
            if not bookmarks.pushbookmark(parser.repo, bmark, old, new):
                print "error %s" % ref

    print