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()
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()
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