mirror of
https://github.com/facebook/sapling.git
synced 2024-10-16 19:57:18 +03:00
162 lines
4.7 KiB
Python
162 lines
4.7 KiB
Python
import re
|
|
import os
|
|
import urllib
|
|
|
|
from mercurial import hg
|
|
from mercurial import node
|
|
from mercurial import util as hgutil
|
|
|
|
|
|
b_re = re.compile(r'^\+\+\+ b\/([^\n]*)', re.MULTILINE)
|
|
a_re = re.compile(r'^--- a\/([^\n]*)', re.MULTILINE)
|
|
devnull_re = re.compile(r'^([-+]{3}) /dev/null', re.MULTILINE)
|
|
header_re = re.compile(r'^diff --git .* b\/(.*)', re.MULTILINE)
|
|
newfile_devnull_re = re.compile(r'^--- /dev/null\n\+\+\+ b/([^\n]*)',
|
|
re.MULTILINE)
|
|
|
|
|
|
def formatrev(rev):
|
|
if rev == -1:
|
|
return '\t(working copy)'
|
|
return '\t(revision %d)' % rev
|
|
|
|
|
|
def filterdiff(diff, oldrev, newrev):
|
|
diff = newfile_devnull_re.sub(r'--- \1\t(revision 0)' '\n'
|
|
r'+++ \1\t(working copy)',
|
|
diff)
|
|
oldrev = formatrev(oldrev)
|
|
newrev = formatrev(newrev)
|
|
diff = a_re.sub(r'--- \1'+ oldrev, diff)
|
|
diff = b_re.sub(r'+++ \1' + newrev, diff)
|
|
diff = devnull_re.sub(r'\1 /dev/null\t(working copy)', diff)
|
|
diff = header_re.sub(r'Index: \1' + '\n' + ('=' * 67), diff)
|
|
return diff
|
|
|
|
|
|
def parentrev(ui, repo, meta, hashes):
|
|
"""Find the svn parent revision of the repo's dirstate.
|
|
"""
|
|
workingctx = repo.parents()[0]
|
|
outrev = outgoing_revisions(repo, hashes, workingctx.node())
|
|
if outrev:
|
|
workingctx = repo[outrev[-1]].parents()[0]
|
|
return workingctx
|
|
|
|
|
|
def islocalrepo(url):
|
|
if not url.startswith('file:///'):
|
|
return False
|
|
if '#' in url.split('/')[-1]: # strip off #anchor
|
|
url = url[:url.rfind('#')]
|
|
path = url[len('file://'):]
|
|
path = urllib.url2pathname(path).replace(os.sep, '/')
|
|
while '/' in path:
|
|
if reduce(lambda x,y: x and y,
|
|
map(lambda p: os.path.exists(os.path.join(path, p)),
|
|
('hooks', 'format', 'db', ))):
|
|
return True
|
|
path = path.rsplit('/', 1)[0]
|
|
return False
|
|
|
|
|
|
def version(ui):
|
|
"""Return version information if available."""
|
|
try:
|
|
import __version__
|
|
return __version__.version
|
|
except ImportError:
|
|
try:
|
|
dn = os.path.dirname
|
|
repo = hg.repository(ui, dn(dn(__file__)))
|
|
ver = repo.dirstate.parents()[0]
|
|
return node.hex(ver)[:12]
|
|
except:
|
|
return 'unknown'
|
|
|
|
|
|
def normalize_url(url):
|
|
if url.startswith('svn+http://') or url.startswith('svn+https://'):
|
|
url = url[4:]
|
|
url, revs, checkout = parseurl(url)
|
|
url = url.rstrip('/')
|
|
if checkout:
|
|
url = '%s#%s' % (url, checkout)
|
|
return url
|
|
|
|
|
|
def parseurl(url, heads=[]):
|
|
parsed = hg.parseurl(url, heads)
|
|
if len(parsed) == 3:
|
|
# old hg, remove when we can be 1.5-only
|
|
svn_url, heads, checkout = parsed
|
|
else:
|
|
svn_url, heads = parsed
|
|
if heads:
|
|
checkout = heads[0]
|
|
else:
|
|
checkout = None
|
|
return svn_url, heads, checkout
|
|
|
|
|
|
class PrefixMatch(object):
|
|
def __init__(self, prefix):
|
|
self.p = prefix
|
|
|
|
def files(self):
|
|
return []
|
|
|
|
def __call__(self, fn):
|
|
return fn.startswith(self.p)
|
|
|
|
def outgoing_revisions(repo, reverse_map, sourcerev):
|
|
"""Given a repo and an hg_editor, determines outgoing revisions for the
|
|
current working copy state.
|
|
"""
|
|
outgoing_rev_hashes = []
|
|
if sourcerev in reverse_map:
|
|
return
|
|
sourcerev = repo[sourcerev]
|
|
while (not sourcerev.node() in reverse_map
|
|
and sourcerev.node() != node.nullid):
|
|
outgoing_rev_hashes.append(sourcerev.node())
|
|
sourcerev = sourcerev.parents()
|
|
if len(sourcerev) != 1:
|
|
raise hgutil.Abort("Sorry, can't find svn parent of a merge revision.")
|
|
sourcerev = sourcerev[0]
|
|
if sourcerev.node() != node.nullid:
|
|
return outgoing_rev_hashes
|
|
|
|
default_commit_msg = '*** empty log message ***'
|
|
|
|
def describe_commit(ui, h, b):
|
|
ui.note(' committed to "%s" as %s\n' % ((b or 'default'), node.short(h)))
|
|
|
|
|
|
def swap_out_encoding(new_encoding="UTF-8"):
|
|
from mercurial import encoding
|
|
old = encoding.encoding
|
|
encoding.encoding = new_encoding
|
|
return old
|
|
|
|
|
|
def issamefile(parentctx, childctx, f):
|
|
"""Assuming f exists and is the same in childctx and parentctx, return True."""
|
|
if parentctx == childctx:
|
|
return True
|
|
if parentctx.rev() > childctx.rev():
|
|
parentctx, childctx = childctx, parentctx
|
|
|
|
def selfandancestors(selfctx):
|
|
yield selfctx
|
|
for ctx in selfctx.ancestors():
|
|
yield ctx
|
|
|
|
for pctx in selfandancestors(childctx):
|
|
if pctx.rev() <= parentctx.rev():
|
|
return True
|
|
if f in pctx.files():
|
|
return False
|
|
# parentctx is not an ancestor of childctx, files are unrelated
|
|
return False
|