mirror of
https://github.com/facebook/sapling.git
synced 2024-10-04 13:57:13 +03:00
Diff in subdirectories from Jake Edge
Dates in diff Fix O(n^2) behaviour of manifest diff Add a/ and b/ to work with patch -p1
This commit is contained in:
parent
b3f6fa6d57
commit
264f689db9
23
hg
23
hg
@ -48,20 +48,25 @@ def filterfiles(list, files):
|
|||||||
return l
|
return l
|
||||||
|
|
||||||
def diff(files = None, node1 = None, node2 = None):
|
def diff(files = None, node1 = None, node2 = None):
|
||||||
|
def date(c):
|
||||||
|
return time.asctime(time.gmtime(float(c[2].split(' ')[0])))
|
||||||
|
|
||||||
if node2:
|
if node2:
|
||||||
change = repo.changelog.read(node2)
|
change = repo.changelog.read(node2)
|
||||||
mmap2 = repo.manifest.read(change[0])
|
mmap2 = repo.manifest.read(change[0])
|
||||||
(c, a, d) = repo.diffrevs(node1, node2)
|
(c, a, d) = repo.diffrevs(node1, node2)
|
||||||
def read(f): return repo.file(f).read(mmap2[f])
|
def read(f): return repo.file(f).read(mmap2[f])
|
||||||
|
date2 = date(change)
|
||||||
else:
|
else:
|
||||||
|
date2 = time.asctime()
|
||||||
if not node1:
|
if not node1:
|
||||||
node1 = repo.current
|
node1 = repo.current
|
||||||
(c, a, d) = repo.diffdir(repo.root, node1)
|
(c, a, d) = repo.diffdir(repo.root, node1)
|
||||||
def read(f): return file(f).read()
|
def read(f): return file(os.path.join(repo.root, f)).read()
|
||||||
|
|
||||||
change = repo.changelog.read(node1)
|
change = repo.changelog.read(node1)
|
||||||
mmap = repo.manifest.read(change[0])
|
mmap = repo.manifest.read(change[0])
|
||||||
|
date1 = date(change)
|
||||||
|
|
||||||
if files:
|
if files:
|
||||||
(c, a, d) = map(lambda x: filterfiles(x, files), (c, a, d))
|
(c, a, d) = map(lambda x: filterfiles(x, files), (c, a, d))
|
||||||
@ -69,16 +74,15 @@ def diff(files = None, node1 = None, node2 = None):
|
|||||||
for f in c:
|
for f in c:
|
||||||
to = repo.file(f).read(mmap[f])
|
to = repo.file(f).read(mmap[f])
|
||||||
tn = read(f)
|
tn = read(f)
|
||||||
sys.stdout.write(mdiff.unidiff(to, tn, f))
|
sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
|
||||||
for f in a:
|
for f in a:
|
||||||
to = ""
|
to = ""
|
||||||
tn = read(f)
|
tn = read(f)
|
||||||
sys.stdout.write(mdiff.unidiff(to, tn, f))
|
sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
|
||||||
for f in d:
|
for f in d:
|
||||||
to = repo.file(f).read(mmap[f])
|
to = repo.file(f).read(mmap[f])
|
||||||
tn = ""
|
tn = ""
|
||||||
sys.stdout.write(mdiff.unidiff(to, tn, f))
|
sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
|
||||||
|
|
||||||
|
|
||||||
options = {}
|
options = {}
|
||||||
opts = [('v', 'verbose', None, 'verbose'),
|
opts = [('v', 'verbose', None, 'verbose'),
|
||||||
@ -178,8 +182,13 @@ elif cmd == "diff":
|
|||||||
if len(revs) > 2:
|
if len(revs) > 2:
|
||||||
print "too many revisions to diff"
|
print "too many revisions to diff"
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
else:
|
|
||||||
diff(args, *revs)
|
if os.getcwd() != repo.root:
|
||||||
|
relpath = os.getcwd()[len(repo.root) + 1: ]
|
||||||
|
if not args: args = [ relpath ]
|
||||||
|
else: args = [ os.path.join(relpath, x) for x in args ]
|
||||||
|
|
||||||
|
diff(args, *revs)
|
||||||
|
|
||||||
elif cmd == "export":
|
elif cmd == "export":
|
||||||
node = repo.changelog.lookup(args[0])
|
node = repo.changelog.lookup(args[0])
|
||||||
|
@ -499,7 +499,7 @@ class localrepository:
|
|||||||
dc = dict.fromkeys(mf)
|
dc = dict.fromkeys(mf)
|
||||||
|
|
||||||
def fcmp(fn):
|
def fcmp(fn):
|
||||||
t1 = file(fn).read()
|
t1 = file(os.path.join(self.root, fn)).read()
|
||||||
t2 = self.file(fn).revision(mf[fn])
|
t2 = self.file(fn).revision(mf[fn])
|
||||||
return cmp(t1, t2)
|
return cmp(t1, t2)
|
||||||
|
|
||||||
@ -509,7 +509,7 @@ class localrepository:
|
|||||||
|
|
||||||
for f in files:
|
for f in files:
|
||||||
fn = os.path.join(d, f)
|
fn = os.path.join(d, f)
|
||||||
try: s = os.stat(fn)
|
try: s = os.stat(os.path.join(self.root, fn))
|
||||||
except: continue
|
except: continue
|
||||||
if fn in dc:
|
if fn in dc:
|
||||||
c = dc[fn]
|
c = dc[fn]
|
||||||
|
@ -2,11 +2,11 @@
|
|||||||
import difflib, struct
|
import difflib, struct
|
||||||
from cStringIO import StringIO
|
from cStringIO import StringIO
|
||||||
|
|
||||||
def unidiff(a, b, fn):
|
def unidiff(a, ad, b, bd, fn):
|
||||||
if not a and not b: return ""
|
if not a and not b: return ""
|
||||||
a = a.splitlines(1)
|
a = a.splitlines(1)
|
||||||
b = b.splitlines(1)
|
b = b.splitlines(1)
|
||||||
l = list(difflib.unified_diff(a, b, fn, fn))
|
l = list(difflib.unified_diff(a, b, "a/" + fn, "b/" + fn, ad, bd))
|
||||||
return "".join(l)
|
return "".join(l)
|
||||||
|
|
||||||
def textdiff(a, b):
|
def textdiff(a, b):
|
||||||
@ -29,15 +29,11 @@ def sortdiff(a, b):
|
|||||||
la += 1
|
la += 1
|
||||||
lb += 1
|
lb += 1
|
||||||
|
|
||||||
si = lb
|
if lb < len(b):
|
||||||
while lb < len(b):
|
yield "insert", la, la, lb, len(b)
|
||||||
lb += 1
|
|
||||||
yield "insert", la, la, si, lb
|
|
||||||
|
|
||||||
si = la
|
if la < len(a):
|
||||||
while la < len(a):
|
yield "delete", la, len(a), lb, lb
|
||||||
la += 1
|
|
||||||
yield "delete", si, la, lb, lb
|
|
||||||
|
|
||||||
def diff(a, b, sorted=0):
|
def diff(a, b, sorted=0):
|
||||||
bin = []
|
bin = []
|
||||||
@ -60,6 +56,7 @@ def patch(a, bin):
|
|||||||
last = pos = 0
|
last = pos = 0
|
||||||
r = []
|
r = []
|
||||||
|
|
||||||
|
c = 0
|
||||||
while pos < len(bin):
|
while pos < len(bin):
|
||||||
p1, p2, l = struct.unpack(">lll", bin[pos:pos + 12])
|
p1, p2, l = struct.unpack(">lll", bin[pos:pos + 12])
|
||||||
pos += 12
|
pos += 12
|
||||||
@ -67,6 +64,7 @@ def patch(a, bin):
|
|||||||
r.append(bin[pos:pos + l])
|
r.append(bin[pos:pos + l])
|
||||||
pos += l
|
pos += l
|
||||||
last = p2
|
last = p2
|
||||||
|
c += 1
|
||||||
r.append(a[last:])
|
r.append(a[last:])
|
||||||
|
|
||||||
return "".join(r)
|
return "".join(r)
|
||||||
|
@ -114,7 +114,7 @@ class revlog:
|
|||||||
last = self.length(base)
|
last = self.length(base)
|
||||||
text = decompress(data[:last])
|
text = decompress(data[:last])
|
||||||
|
|
||||||
for r in range(base + 1, rev + 1):
|
for r in xrange(base + 1, rev + 1):
|
||||||
s = self.length(r)
|
s = self.length(r)
|
||||||
b = decompress(data[last:last + s])
|
b = decompress(data[last:last + s])
|
||||||
text = self.patch(text, b)
|
text = self.patch(text, b)
|
||||||
@ -138,14 +138,16 @@ class revlog:
|
|||||||
t = n - 1
|
t = n - 1
|
||||||
|
|
||||||
if n:
|
if n:
|
||||||
start = self.start(self.base(t))
|
base = self.base(t)
|
||||||
|
start = self.start(base)
|
||||||
end = self.end(t)
|
end = self.end(t)
|
||||||
prev = self.revision(self.tip())
|
prev = self.revision(self.tip())
|
||||||
data = compress(self.diff(prev, text))
|
data = compress(self.diff(prev, text))
|
||||||
|
dist = end - start + len(data)
|
||||||
|
|
||||||
# full versions are inserted when the needed deltas
|
# full versions are inserted when the needed deltas
|
||||||
# become comparable to the uncompressed text
|
# become comparable to the uncompressed text
|
||||||
if not n or (end + len(data) - start) > len(text) * 2:
|
if not n or dist > len(text) * 2:
|
||||||
data = compress(text)
|
data = compress(text)
|
||||||
base = n
|
base = n
|
||||||
else:
|
else:
|
||||||
|
Loading…
Reference in New Issue
Block a user