annotate mercurial/mdiff.py @ 535:fba26990604a

Deal with failed clone/transaction interaction -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Deal with failed clone/transaction interaction > What is happening is that something in the transaction machinery is > causing the directory to be completely recreated. The transaction gets rolled back by its destructor. This is critical so it happens whenever an exception occurs that unwinds the stack. Unfortunately, what's happening with clone is we're trying to delete the directory during exception propagation. And a reference to the transaction is held in the exception backtrace stack frames so it still exists until the exception is completely resolved. So there's no way to do the directory delete inside the exception handling cleanly. But we can handle it similarly to the transaction itself: use an object with a destructor. manifest hash: fc38550a20d64d08333f256bbedc312493c1390b -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.0 (GNU/Linux) iD8DBQFCxDT2ywK+sNU5EO8RAjikAJ0Tej56rAutxQDfYzVbFGtT1sEC5ACgmVds /fwdQyHn+FwshugqXLemUaM= =3f78 -----END PGP SIGNATURE-----
author mpm@selenic.com
date Thu, 30 Jun 2005 10:07:50 -0800
parents 03f27b1381f9
children df8a5a0098d4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
239
75840796e8e2 mdiff.py: kill #! line, add copyright notice
mpm@selenic.com
parents: 184
diff changeset
1 # mdiff.py - diff and patch routines for mercurial
75840796e8e2 mdiff.py: kill #! line, add copyright notice
mpm@selenic.com
parents: 184
diff changeset
2 #
75840796e8e2 mdiff.py: kill #! line, add copyright notice
mpm@selenic.com
parents: 184
diff changeset
3 # Copyright 2005 Matt Mackall <mpm@selenic.com>
75840796e8e2 mdiff.py: kill #! line, add copyright notice
mpm@selenic.com
parents: 184
diff changeset
4 #
75840796e8e2 mdiff.py: kill #! line, add copyright notice
mpm@selenic.com
parents: 184
diff changeset
5 # This software may be used and distributed according to the terms
75840796e8e2 mdiff.py: kill #! line, add copyright notice
mpm@selenic.com
parents: 184
diff changeset
6 # of the GNU General Public License, incorporated herein by reference.
75840796e8e2 mdiff.py: kill #! line, add copyright notice
mpm@selenic.com
parents: 184
diff changeset
7
432
3b9e3d3d2810 Start using bdiff for generating deltas
mpm@selenic.com
parents: 396
diff changeset
8 import difflib, struct, bdiff
3b9e3d3d2810 Start using bdiff for generating deltas
mpm@selenic.com
parents: 396
diff changeset
9 from mpatch import *
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
10
396
8f8bb77d560e Show revisions in diffs like CVS, based on a patch from Goffredo Baroncelli.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 361
diff changeset
11 def unidiff(a, ad, b, bd, fn, r=None):
8f8bb77d560e Show revisions in diffs like CVS, based on a patch from Goffredo Baroncelli.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 361
diff changeset
12
35
9197c26a414b unidiff: punt on comparing empty files
mpm@selenic.com
parents: 0
diff changeset
13 if not a and not b: return ""
264
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
14
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
15 if a == None:
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
16 b = b.splitlines(1)
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
17 l1 = "--- %s\t%s\n" % ("/dev/null", ad)
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
18 l2 = "+++ %s\t%s\n" % ("b/" + fn, bd)
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
19 l3 = "@@ -0,0 +1,%d @@\n" % len(b)
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
20 l = [l1, l2, l3] + ["+" + e for e in b]
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
21 elif b == None:
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
22 a = a.splitlines(1)
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
23 l1 = "--- %s\t%s\n" % ("a/" + fn, ad)
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
24 l2 = "+++ %s\t%s\n" % ("/dev/null", bd)
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
25 l3 = "@@ -1,%d +0,0 @@\n" % len(a)
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
26 l = [l1, l2, l3] + ["-" + e for e in a]
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
27 else:
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
28 a = a.splitlines(1)
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
29 b = b.splitlines(1)
272
467cea2bf2d8 diff: use tab to separate date from filename
mpm@selenic.com
parents: 264
diff changeset
30 l = list(difflib.unified_diff(a, b, "a/" + fn, "b/" + fn))
278
777e388c06d6 unidiff: handle empty diffs more gracefully
mpm@selenic.com
parents: 272
diff changeset
31 if not l: return ""
272
467cea2bf2d8 diff: use tab to separate date from filename
mpm@selenic.com
parents: 264
diff changeset
32 # difflib uses a space, rather than a tab
467cea2bf2d8 diff: use tab to separate date from filename
mpm@selenic.com
parents: 264
diff changeset
33 l[0] = l[0][:-2] + "\t" + ad + "\n"
467cea2bf2d8 diff: use tab to separate date from filename
mpm@selenic.com
parents: 264
diff changeset
34 l[1] = l[1][:-2] + "\t" + bd + "\n"
170
e6c621a825f2 hg diff: fix missing final newline bug
mpm@selenic.com
parents: 127
diff changeset
35
e6c621a825f2 hg diff: fix missing final newline bug
mpm@selenic.com
parents: 127
diff changeset
36 for ln in xrange(len(l)):
e6c621a825f2 hg diff: fix missing final newline bug
mpm@selenic.com
parents: 127
diff changeset
37 if l[ln][-1] != '\n':
e6c621a825f2 hg diff: fix missing final newline bug
mpm@selenic.com
parents: 127
diff changeset
38 l[ln] += "\n\ No newline at end of file\n"
e6c621a825f2 hg diff: fix missing final newline bug
mpm@selenic.com
parents: 127
diff changeset
39
396
8f8bb77d560e Show revisions in diffs like CVS, based on a patch from Goffredo Baroncelli.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 361
diff changeset
40 if r:
8f8bb77d560e Show revisions in diffs like CVS, based on a patch from Goffredo Baroncelli.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 361
diff changeset
41 l.insert(0, "diff %s %s\n" %
8f8bb77d560e Show revisions in diffs like CVS, based on a patch from Goffredo Baroncelli.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 361
diff changeset
42 (' '.join(["-r %s" % rev for rev in r]), fn))
8f8bb77d560e Show revisions in diffs like CVS, based on a patch from Goffredo Baroncelli.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 361
diff changeset
43
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
44 return "".join(l)
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
45
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
46 def sortdiff(a, b):
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
47 la = lb = 0
325
ad87e19854a6 mdiff: reinstate new algorithm
mpm@selenic.com
parents: 318
diff changeset
48 lena = len(a)
ad87e19854a6 mdiff: reinstate new algorithm
mpm@selenic.com
parents: 318
diff changeset
49 lenb = len(b)
515
03f27b1381f9 Whitespace cleanups
mpm@selenic.com
parents: 432
diff changeset
50
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
51 while 1:
325
ad87e19854a6 mdiff: reinstate new algorithm
mpm@selenic.com
parents: 318
diff changeset
52 am, bm, = la, lb
ad87e19854a6 mdiff: reinstate new algorithm
mpm@selenic.com
parents: 318
diff changeset
53
ad87e19854a6 mdiff: reinstate new algorithm
mpm@selenic.com
parents: 318
diff changeset
54 # walk over matching lines
326
235443668bea mdiff: fix the fix
mpm@selenic.com
parents: 325
diff changeset
55 while lb < lenb and la < lena and a[la] == b[lb] :
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
56 la += 1
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
57 lb += 1
318
2819f63b16bf mdiff: revert grouping optimization for the time being
mpm@selenic.com
parents: 317
diff changeset
58
325
ad87e19854a6 mdiff: reinstate new algorithm
mpm@selenic.com
parents: 318
diff changeset
59 if la > am:
ad87e19854a6 mdiff: reinstate new algorithm
mpm@selenic.com
parents: 318
diff changeset
60 yield (am, bm, la - am) # return a match
ad87e19854a6 mdiff: reinstate new algorithm
mpm@selenic.com
parents: 318
diff changeset
61
ad87e19854a6 mdiff: reinstate new algorithm
mpm@selenic.com
parents: 318
diff changeset
62 # skip mismatched lines from b
361
88268aa2b8d2 Fix another sortdiff cornercase
mpm@selenic.com
parents: 330
diff changeset
63 while la < lena and lb < lenb and b[lb] < a[la]:
325
ad87e19854a6 mdiff: reinstate new algorithm
mpm@selenic.com
parents: 318
diff changeset
64 lb += 1
318
2819f63b16bf mdiff: revert grouping optimization for the time being
mpm@selenic.com
parents: 317
diff changeset
65
325
ad87e19854a6 mdiff: reinstate new algorithm
mpm@selenic.com
parents: 318
diff changeset
66 if lb >= lenb:
ad87e19854a6 mdiff: reinstate new algorithm
mpm@selenic.com
parents: 318
diff changeset
67 break
515
03f27b1381f9 Whitespace cleanups
mpm@selenic.com
parents: 432
diff changeset
68
325
ad87e19854a6 mdiff: reinstate new algorithm
mpm@selenic.com
parents: 318
diff changeset
69 # skip mismatched lines from a
361
88268aa2b8d2 Fix another sortdiff cornercase
mpm@selenic.com
parents: 330
diff changeset
70 while la < lena and lb < lenb and b[lb] > a[la]:
325
ad87e19854a6 mdiff: reinstate new algorithm
mpm@selenic.com
parents: 318
diff changeset
71 la += 1
ad87e19854a6 mdiff: reinstate new algorithm
mpm@selenic.com
parents: 318
diff changeset
72
ad87e19854a6 mdiff: reinstate new algorithm
mpm@selenic.com
parents: 318
diff changeset
73 if la >= lena:
ad87e19854a6 mdiff: reinstate new algorithm
mpm@selenic.com
parents: 318
diff changeset
74 break
515
03f27b1381f9 Whitespace cleanups
mpm@selenic.com
parents: 432
diff changeset
75
325
ad87e19854a6 mdiff: reinstate new algorithm
mpm@selenic.com
parents: 318
diff changeset
76 yield (lena, lenb, 0)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
77
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
78 def diff(a, b, sorted=0):
325
ad87e19854a6 mdiff: reinstate new algorithm
mpm@selenic.com
parents: 318
diff changeset
79 if not a:
ad87e19854a6 mdiff: reinstate new algorithm
mpm@selenic.com
parents: 318
diff changeset
80 s = "".join(b)
ad87e19854a6 mdiff: reinstate new algorithm
mpm@selenic.com
parents: 318
diff changeset
81 return s and (struct.pack(">lll", 0, 0, len(s)) + s)
ad87e19854a6 mdiff: reinstate new algorithm
mpm@selenic.com
parents: 318
diff changeset
82
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
83 bin = []
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
84 p = [0]
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
85 for i in a: p.append(p[-1] + len(i))
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
86
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
87 if sorted:
317
b18ce742566a hg commit: user and date options
mpm@selenic.com
parents: 278
diff changeset
88 try:
b18ce742566a hg commit: user and date options
mpm@selenic.com
parents: 278
diff changeset
89 d = sortdiff(a, b)
b18ce742566a hg commit: user and date options
mpm@selenic.com
parents: 278
diff changeset
90 except:
b18ce742566a hg commit: user and date options
mpm@selenic.com
parents: 278
diff changeset
91 print a, b
b18ce742566a hg commit: user and date options
mpm@selenic.com
parents: 278
diff changeset
92 raise
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
93 else:
325
ad87e19854a6 mdiff: reinstate new algorithm
mpm@selenic.com
parents: 318
diff changeset
94 d = difflib.SequenceMatcher(None, a, b).get_matching_blocks()
ad87e19854a6 mdiff: reinstate new algorithm
mpm@selenic.com
parents: 318
diff changeset
95 la = 0
ad87e19854a6 mdiff: reinstate new algorithm
mpm@selenic.com
parents: 318
diff changeset
96 lb = 0
ad87e19854a6 mdiff: reinstate new algorithm
mpm@selenic.com
parents: 318
diff changeset
97 for am, bm, size in d:
ad87e19854a6 mdiff: reinstate new algorithm
mpm@selenic.com
parents: 318
diff changeset
98 s = "".join(b[lb:bm])
ad87e19854a6 mdiff: reinstate new algorithm
mpm@selenic.com
parents: 318
diff changeset
99 if am > la or s:
ad87e19854a6 mdiff: reinstate new algorithm
mpm@selenic.com
parents: 318
diff changeset
100 bin.append(struct.pack(">lll", p[la], p[am], len(s)) + s)
ad87e19854a6 mdiff: reinstate new algorithm
mpm@selenic.com
parents: 318
diff changeset
101 la = am + size
ad87e19854a6 mdiff: reinstate new algorithm
mpm@selenic.com
parents: 318
diff changeset
102 lb = bm + size
515
03f27b1381f9 Whitespace cleanups
mpm@selenic.com
parents: 432
diff changeset
103
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
104 return "".join(bin)
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
105
120
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
106 def patchtext(bin):
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
107 pos = 0
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
108 t = []
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
109 while pos < len(bin):
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
110 p1, p2, l = struct.unpack(">lll", bin[pos:pos + 12])
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
111 pos += 12
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
112 t.append(bin[pos:pos + l])
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
113 pos += l
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
114 return "".join(t)
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
115
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
116 def patch(a, bin):
72
4a6ab4d80dc4 Add an O(m + nlog n) patching extension
mpm@selenic.com
parents: 71
diff changeset
117 return patches(a, [bin])
432
3b9e3d3d2810 Start using bdiff for generating deltas
mpm@selenic.com
parents: 396
diff changeset
118
3b9e3d3d2810 Start using bdiff for generating deltas
mpm@selenic.com
parents: 396
diff changeset
119 textdiff = bdiff.bdiff
3b9e3d3d2810 Start using bdiff for generating deltas
mpm@selenic.com
parents: 396
diff changeset
120
3b9e3d3d2810 Start using bdiff for generating deltas
mpm@selenic.com
parents: 396
diff changeset
121