docs: def submit(ui, repo, *pats, **opts):
  	"""submit change to remote repository
  
  	Submits change to remote repository.
  	Bails out if the local repository is not in sync with the remote one.
  	"""
  	if codereview_disabled:
  		raise hg_util.Abort(codereview_disabled)
  
  	# We already called this on startup but sometimes Mercurial forgets.
  	set_mercurial_encoding_to_utf8()
  
  	if not opts["no_incoming"] and hg_incoming(ui, repo):
  		need_sync()
  
  	cl, err = CommandLineCL(ui, repo, pats, opts, op="submit", defaultcc=defaultcc)
  	if err != "":
  		raise hg_util.Abort(err)
  
  	user = None
  	if cl.copied_from:
  		user = cl.copied_from
  	userline = CheckContributor(ui, repo, user)
  	typecheck(userline, str)
  
  	about = ""
  	if cl.reviewer:
  		about += "R=" + JoinComma([CutDomain(s) for s in cl.reviewer]) + "\n"
  	if opts.get('tbr'):
  		tbr = SplitCommaSpace(opts.get('tbr'))
  		cl.reviewer = Add(cl.reviewer, tbr)
  		about += "TBR=" + JoinComma([CutDomain(s) for s in tbr]) + "\n"
  	if cl.cc:
  		about += "CC=" + JoinComma([CutDomain(s) for s in cl.cc]) + "\n"
  
  	if not cl.reviewer:
  		raise hg_util.Abort("no reviewers listed in CL")
  
  	if not cl.local:
  		raise hg_util.Abort("cannot submit non-local CL")
  
  	# upload, to sync current patch and also get change number if CL is new.
  	if not cl.copied_from:
  		cl.Upload(ui, repo, gofmt_just_warn=True)
  
  	# check gofmt for real; allowed upload to warn in order to save CL.
  	cl.Flush(ui, repo)
  	CheckFormat(ui, repo, cl.files)
  
  	about += "%s%s\n" % (server_url_base, cl.name)
  
  	if cl.copied_from:
  		about += "\nCommitter: " + CheckContributor(ui, repo, None) + "\n"
  	typecheck(about, str)
  
  	if not cl.mailed and not cl.copied_from:		# in case this is TBR
  		cl.Mail(ui, repo)
  
  	# submit changes locally
  	message = cl.desc.rstrip() + "\n\n" + about
  	typecheck(message, str)
  
  	set_status("pushing " + cl.name + " to remote server")
  
  	if hg_outgoing(ui, repo):
  		raise hg_util.Abort("local repository corrupt or out-of-phase with remote: found outgoing changes")
  	
  	old_heads = len(hg_heads(ui, repo).split())
  
  	global commit_okay
  	commit_okay = True
  	ret = hg_commit(ui, repo, *['path:'+f for f in cl.files], message=message, user=userline)
  	commit_okay = False
  	if ret:
  		raise hg_util.Abort("nothing changed")
  	node = repo["-1"].node()
  	# push to remote; if it fails for any reason, roll back
  	try:
  		new_heads = len(hg_heads(ui, repo).split())
  		if old_heads != new_heads and not (old_heads == 0 and new_heads == 1):
  			# Created new head, so we weren't up to date.
  			need_sync()
  
  		# Push changes to remote.  If it works, we're committed.  If not, roll back.
  		try:
  			if hg_push(ui, repo):
  				raise hg_util.Abort("push error")
  		except hg_error.Abort, e:
  			if e.message.find("push creates new heads") >= 0:
  				# Remote repository had changes we missed.
  				need_sync()
  			raise
  		except urllib2.HTTPError, e:
  			print >>sys.stderr, "pushing to remote server failed; do you have commit permissions?"
  			raise
  	except:
  		real_rollback()
  		raise
  
  	# We're committed. Upload final patch, close review, add commit message.
  	changeURL = hg_node.short(node)
  	url = ui.expandpath("default")
  	m = re.match("(^https?://([^@/]+@)?([^.]+)\.googlecode\.com/hg/?)" + "|" +
  		"(^https?://([^@/]+@)?code\.google\.com/p/([^/.]+)(\.[^./]+)?/?)", url)
  	if m:
  		if m.group(1): # prj.googlecode.com/hg/ case
  			changeURL = "https://code.google.com/p/%s/source/detail?r=%s" % (m.group(3), changeURL)
  		elif m.group(4) and m.group(7): # code.google.com/p/prj.subrepo/ case
  			changeURL = "https://code.google.com/p/%s/source/detail?r=%s&repo=%s" % (m.group(6), changeURL, m.group(7)[1:])
  		elif m.group(4): # code.google.com/p/prj/ case
  			changeURL = "https://code.google.com/p/%s/source/detail?r=%s" % (m.group(6), changeURL)
  		else:
  			print >>sys.stderr, "URL: ", url
  	else:
  		print >>sys.stderr, "URL: ", url
  	pmsg = "*** Submitted as " + changeURL + " ***\n\n" + message
  
  	# When posting, move reviewers to CC line,
  	# so that the issue stops showing up in their "My Issues" page.
  	PostMessage(ui, cl.name, pmsg, reviewers="", cc=JoinComma(cl.reviewer+cl.cc))
  
  	if not cl.copied_from:
  		EditDesc(cl.name, closed=True, private=cl.private)
  	cl.Delete(ui, repo)
  
  	c = repo[None]
  	if c.branch() == releaseBranch and not c.modified() and not c.added() and not c.removed():
  		ui.write("switching from %s to default branch.\n" % releaseBranch)
  		err = hg_clean(repo, "default")
  		if err:
  			return err
  	return 0