author | Eric Hopper <hopper@omnifarious.org> |
Thu, 10 May 2007 13:42:36 -0700 | |
changeset 4436 | a764edb6fc95 |
parent 4435 | aac150af09e8 |
child 4443 | eff2eefdb65a |
child 4488 | 62019c4427e3 |
permissions | -rw-r--r-- |
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
1 |
# patch.py - patch file parsing routines |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
2 |
# |
2865
71e78f2ca5ae
merge git patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2863
diff
changeset
|
3 |
# Copyright 2006 Brendan Cully <brendan@kublai.com> |
71e78f2ca5ae
merge git patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2863
diff
changeset
|
4 |
# |
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
5 |
# This software may be used and distributed according to the terms |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
6 |
# of the GNU General Public License, incorporated herein by reference. |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
7 |
|
3891 | 8 |
from i18n import _ |
2874
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
9 |
from node import * |
3967
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
10 |
import base85, cmdutil, mdiff, util, context, revlog |
3963
ba45041827a2
remove various unused import
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3902
diff
changeset
|
11 |
import cStringIO, email.Parser, os, popen2, re, sha |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
3717
diff
changeset
|
12 |
import sys, tempfile, zlib |
2866
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
13 |
|
2933
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
14 |
# helper functions |
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
15 |
|
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
16 |
def copyfile(src, dst, basedir=None): |
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
17 |
if not basedir: |
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
18 |
basedir = os.getcwd() |
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
19 |
|
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
20 |
abssrc, absdst = [os.path.join(basedir, n) for n in (src, dst)] |
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
21 |
if os.path.exists(absdst): |
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
22 |
raise util.Abort(_("cannot create %s: destination already exists") % |
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
23 |
dst) |
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
24 |
|
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
25 |
targetdir = os.path.dirname(absdst) |
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
26 |
if not os.path.isdir(targetdir): |
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
27 |
os.makedirs(targetdir) |
3629
4cfb72bcb978
util: add copyfile function
Matt Mackall <mpm@selenic.com>
parents:
3588
diff
changeset
|
28 |
|
4cfb72bcb978
util: add copyfile function
Matt Mackall <mpm@selenic.com>
parents:
3588
diff
changeset
|
29 |
util.copyfile(abssrc, absdst) |
2933
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
30 |
|
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
31 |
# public functions |
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
32 |
|
2866
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
33 |
def extract(ui, fileobj): |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
34 |
'''extract patch from data read from fileobj. |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
35 |
|
4263 | 36 |
patch can be a normal patch or contained in an email message. |
2866
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
37 |
|
4263 | 38 |
return tuple (filename, message, user, date, node, p1, p2). |
39 |
Any item in the returned tuple can be None. If filename is None, |
|
40 |
fileobj did not contain a patch. Caller must unlink filename when done.''' |
|
2866
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
41 |
|
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
42 |
# attempt to detect the start of a patch |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
43 |
# (this heuristic is borrowed from quilt) |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
44 |
diffre = re.compile(r'^(?:Index:[ \t]|diff[ \t]|RCS file: |' + |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
45 |
'retrieving revision [0-9]+(\.[0-9]+)*$|' + |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
46 |
'(---|\*\*\*)[ \t])', re.MULTILINE) |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
47 |
|
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
48 |
fd, tmpname = tempfile.mkstemp(prefix='hg-patch-') |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
49 |
tmpfp = os.fdopen(fd, 'w') |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
50 |
try: |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
51 |
msg = email.Parser.Parser().parse(fileobj) |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
52 |
|
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
53 |
message = msg['Subject'] |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
54 |
user = msg['From'] |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
55 |
# should try to parse msg['Date'] |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
56 |
date = None |
4263 | 57 |
nodeid = None |
58 |
parents = [] |
|
2866
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
59 |
|
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
60 |
if message: |
4201
7e95381a9f1e
Strip [PATCH...] from message subject when importing patches
Brendan Cully <brendan@kublai.com>
parents:
4200
diff
changeset
|
61 |
if message.startswith('[PATCH'): |
7e95381a9f1e
Strip [PATCH...] from message subject when importing patches
Brendan Cully <brendan@kublai.com>
parents:
4200
diff
changeset
|
62 |
pend = message.find(']') |
4208
bd9b84b9a84b
Make [PATCH] removal slightly more robust
Brendan Cully <brendan@kublai.com>
parents:
4201
diff
changeset
|
63 |
if pend >= 0: |
bd9b84b9a84b
Make [PATCH] removal slightly more robust
Brendan Cully <brendan@kublai.com>
parents:
4201
diff
changeset
|
64 |
message = message[pend+1:].lstrip() |
2866
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
65 |
message = message.replace('\n\t', ' ') |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
66 |
ui.debug('Subject: %s\n' % message) |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
67 |
if user: |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
68 |
ui.debug('From: %s\n' % user) |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
69 |
diffs_seen = 0 |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
70 |
ok_types = ('text/plain', 'text/x-diff', 'text/x-patch') |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
71 |
|
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
72 |
for part in msg.walk(): |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
73 |
content_type = part.get_content_type() |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
74 |
ui.debug('Content-Type: %s\n' % content_type) |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
75 |
if content_type not in ok_types: |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
76 |
continue |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
77 |
payload = part.get_payload(decode=True) |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
78 |
m = diffre.search(payload) |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
79 |
if m: |
4220
1253703853a8
git-send-email compatibility: stop reading changelog after ^---$
Brendan Cully <brendan@kublai.com>
parents:
4208
diff
changeset
|
80 |
hgpatch = False |
1253703853a8
git-send-email compatibility: stop reading changelog after ^---$
Brendan Cully <brendan@kublai.com>
parents:
4208
diff
changeset
|
81 |
ignoretext = False |
1253703853a8
git-send-email compatibility: stop reading changelog after ^---$
Brendan Cully <brendan@kublai.com>
parents:
4208
diff
changeset
|
82 |
|
2866
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
83 |
ui.debug(_('found patch at byte %d\n') % m.start(0)) |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
84 |
diffs_seen += 1 |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
85 |
cfp = cStringIO.StringIO() |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
86 |
if message: |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
87 |
cfp.write(message) |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
88 |
cfp.write('\n') |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
89 |
for line in payload[:m.start(0)].splitlines(): |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
90 |
if line.startswith('# HG changeset patch'): |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
91 |
ui.debug(_('patch generated by hg export\n')) |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
92 |
hgpatch = True |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
93 |
# drop earlier commit message content |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
94 |
cfp.seek(0) |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
95 |
cfp.truncate() |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
96 |
elif hgpatch: |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
97 |
if line.startswith('# User '): |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
98 |
user = line[7:] |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
99 |
ui.debug('From: %s\n' % user) |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
100 |
elif line.startswith("# Date "): |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
101 |
date = line[7:] |
4263 | 102 |
elif line.startswith("# Node ID "): |
103 |
nodeid = line[10:] |
|
104 |
elif line.startswith("# Parent "): |
|
105 |
parents.append(line[10:]) |
|
4220
1253703853a8
git-send-email compatibility: stop reading changelog after ^---$
Brendan Cully <brendan@kublai.com>
parents:
4208
diff
changeset
|
106 |
elif line == '---' and 'git-send-email' in msg['X-Mailer']: |
1253703853a8
git-send-email compatibility: stop reading changelog after ^---$
Brendan Cully <brendan@kublai.com>
parents:
4208
diff
changeset
|
107 |
ignoretext = True |
1253703853a8
git-send-email compatibility: stop reading changelog after ^---$
Brendan Cully <brendan@kublai.com>
parents:
4208
diff
changeset
|
108 |
if not line.startswith('# ') and not ignoretext: |
2866
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
109 |
cfp.write(line) |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
110 |
cfp.write('\n') |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
111 |
message = cfp.getvalue() |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
112 |
if tmpfp: |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
113 |
tmpfp.write(payload) |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
114 |
if not payload.endswith('\n'): |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
115 |
tmpfp.write('\n') |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
116 |
elif not diffs_seen and message and content_type == 'text/plain': |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
117 |
message += '\n' + payload |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
118 |
except: |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
119 |
tmpfp.close() |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
120 |
os.unlink(tmpname) |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
121 |
raise |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
122 |
|
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
123 |
tmpfp.close() |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
124 |
if not diffs_seen: |
2893e51407a4
commands.import: refactor patch parsing into patch.extract.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2865
diff
changeset
|
125 |
os.unlink(tmpname) |
4263 | 126 |
return None, message, user, date, None, None, None |
127 |
p1 = parents and parents.pop(0) or None |
|
128 |
p2 = parents and parents.pop(0) or None |
|
129 |
return tmpname, message, user, date, nodeid, p1, p2 |
|
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
130 |
|
3716
ab5600428b08
handle files with both git binary patches and copy/rename ops
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3702
diff
changeset
|
131 |
GP_PATCH = 1 << 0 # we have to run patch |
ab5600428b08
handle files with both git binary patches and copy/rename ops
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3702
diff
changeset
|
132 |
GP_FILTER = 1 << 1 # there's some copy/rename operation |
ab5600428b08
handle files with both git binary patches and copy/rename ops
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3702
diff
changeset
|
133 |
GP_BINARY = 1 << 2 # there's a binary patch |
ab5600428b08
handle files with both git binary patches and copy/rename ops
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3702
diff
changeset
|
134 |
|
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
135 |
def readgitpatch(patchname): |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
136 |
"""extract git-style metadata about patches from <patchname>""" |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
137 |
class gitpatch: |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
138 |
"op is one of ADD, DELETE, RENAME, MODIFY or COPY" |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
139 |
def __init__(self, path): |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
140 |
self.path = path |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
141 |
self.oldpath = None |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
142 |
self.mode = None |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
143 |
self.op = 'MODIFY' |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
144 |
self.copymod = False |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
145 |
self.lineno = 0 |
3367
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
146 |
self.binary = False |
3223
53e843840349
Whitespace/Tab cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents:
3199
diff
changeset
|
147 |
|
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
148 |
# Filter patch for git information |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
149 |
gitre = re.compile('diff --git a/(.*) b/(.*)') |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
150 |
pf = file(patchname) |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
151 |
gp = None |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
152 |
gitpatches = [] |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
153 |
# Can have a git patch with only metadata, causing patch to complain |
3716
ab5600428b08
handle files with both git binary patches and copy/rename ops
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3702
diff
changeset
|
154 |
dopatch = 0 |
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
155 |
|
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
156 |
lineno = 0 |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
157 |
for line in pf: |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
158 |
lineno += 1 |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
159 |
if line.startswith('diff --git'): |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
160 |
m = gitre.match(line) |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
161 |
if m: |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
162 |
if gp: |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
163 |
gitpatches.append(gp) |
3673
eb0b4a2d70a9
white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents:
3629
diff
changeset
|
164 |
src, dst = m.group(1, 2) |
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
165 |
gp = gitpatch(dst) |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
166 |
gp.lineno = lineno |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
167 |
elif gp: |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
168 |
if line.startswith('--- '): |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
169 |
if gp.op in ('COPY', 'RENAME'): |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
170 |
gp.copymod = True |
3716
ab5600428b08
handle files with both git binary patches and copy/rename ops
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3702
diff
changeset
|
171 |
dopatch |= GP_FILTER |
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
172 |
gitpatches.append(gp) |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
173 |
gp = None |
3716
ab5600428b08
handle files with both git binary patches and copy/rename ops
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3702
diff
changeset
|
174 |
dopatch |= GP_PATCH |
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
175 |
continue |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
176 |
if line.startswith('rename from '): |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
177 |
gp.op = 'RENAME' |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
178 |
gp.oldpath = line[12:].rstrip() |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
179 |
elif line.startswith('rename to '): |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
180 |
gp.path = line[10:].rstrip() |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
181 |
elif line.startswith('copy from '): |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
182 |
gp.op = 'COPY' |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
183 |
gp.oldpath = line[10:].rstrip() |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
184 |
elif line.startswith('copy to '): |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
185 |
gp.path = line[8:].rstrip() |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
186 |
elif line.startswith('deleted file'): |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
187 |
gp.op = 'DELETE' |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
188 |
elif line.startswith('new file mode '): |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
189 |
gp.op = 'ADD' |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
190 |
gp.mode = int(line.rstrip()[-3:], 8) |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
191 |
elif line.startswith('new mode '): |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
192 |
gp.mode = int(line.rstrip()[-3:], 8) |
3367
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
193 |
elif line.startswith('GIT binary patch'): |
3716
ab5600428b08
handle files with both git binary patches and copy/rename ops
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3702
diff
changeset
|
194 |
dopatch |= GP_BINARY |
3367
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
195 |
gp.binary = True |
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
196 |
if gp: |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
197 |
gitpatches.append(gp) |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
198 |
|
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
199 |
if not gitpatches: |
3716
ab5600428b08
handle files with both git binary patches and copy/rename ops
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3702
diff
changeset
|
200 |
dopatch = GP_PATCH |
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
201 |
|
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
202 |
return (dopatch, gitpatches) |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
203 |
|
3055
efd26ceedafb
Fix git patch application when cwd != repo.root
Brendan Cully <brendan@kublai.com>
parents:
2952
diff
changeset
|
204 |
def dogitpatch(patchname, gitpatches, cwd=None): |
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
205 |
"""Preprocess git patch so that vanilla patch can handle it""" |
3367
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
206 |
def extractbin(fp): |
3717
9e248cfd8b94
handle files with more than one git binary patch
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3716
diff
changeset
|
207 |
i = [0] # yuck |
9e248cfd8b94
handle files with more than one git binary patch
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3716
diff
changeset
|
208 |
def readline(): |
9e248cfd8b94
handle files with more than one git binary patch
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3716
diff
changeset
|
209 |
i[0] += 1 |
9e248cfd8b94
handle files with more than one git binary patch
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3716
diff
changeset
|
210 |
return fp.readline().rstrip() |
9e248cfd8b94
handle files with more than one git binary patch
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3716
diff
changeset
|
211 |
line = readline() |
3367
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
212 |
while line and not line.startswith('literal '): |
3717
9e248cfd8b94
handle files with more than one git binary patch
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3716
diff
changeset
|
213 |
line = readline() |
3367
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
214 |
if not line: |
3717
9e248cfd8b94
handle files with more than one git binary patch
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3716
diff
changeset
|
215 |
return None, i[0] |
3374
fd43ff3b4442
Use line length field when extracting git binary patches
Brendan Cully <brendan@kublai.com>
parents:
3367
diff
changeset
|
216 |
size = int(line[8:]) |
3367
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
217 |
dec = [] |
3717
9e248cfd8b94
handle files with more than one git binary patch
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3716
diff
changeset
|
218 |
line = readline() |
3367
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
219 |
while line: |
3374
fd43ff3b4442
Use line length field when extracting git binary patches
Brendan Cully <brendan@kublai.com>
parents:
3367
diff
changeset
|
220 |
l = line[0] |
fd43ff3b4442
Use line length field when extracting git binary patches
Brendan Cully <brendan@kublai.com>
parents:
3367
diff
changeset
|
221 |
if l <= 'Z' and l >= 'A': |
fd43ff3b4442
Use line length field when extracting git binary patches
Brendan Cully <brendan@kublai.com>
parents:
3367
diff
changeset
|
222 |
l = ord(l) - ord('A') + 1 |
fd43ff3b4442
Use line length field when extracting git binary patches
Brendan Cully <brendan@kublai.com>
parents:
3367
diff
changeset
|
223 |
else: |
fd43ff3b4442
Use line length field when extracting git binary patches
Brendan Cully <brendan@kublai.com>
parents:
3367
diff
changeset
|
224 |
l = ord(l) - ord('a') + 27 |
fd43ff3b4442
Use line length field when extracting git binary patches
Brendan Cully <brendan@kublai.com>
parents:
3367
diff
changeset
|
225 |
dec.append(base85.b85decode(line[1:])[:l]) |
3717
9e248cfd8b94
handle files with more than one git binary patch
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3716
diff
changeset
|
226 |
line = readline() |
3367
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
227 |
text = zlib.decompress(''.join(dec)) |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
228 |
if len(text) != size: |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
229 |
raise util.Abort(_('binary patch is %d bytes, not %d') % |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
230 |
(len(text), size)) |
3717
9e248cfd8b94
handle files with more than one git binary patch
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3716
diff
changeset
|
231 |
return text, i[0] |
3367
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
232 |
|
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
233 |
pf = file(patchname) |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
234 |
pfline = 1 |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
235 |
|
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
236 |
fd, patchname = tempfile.mkstemp(prefix='hg-patch-') |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
237 |
tmpfp = os.fdopen(fd, 'w') |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
238 |
|
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
239 |
try: |
3473
0e68608bd11d
use xrange instead of range
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3465
diff
changeset
|
240 |
for i in xrange(len(gitpatches)): |
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
241 |
p = gitpatches[i] |
3367
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
242 |
if not p.copymod and not p.binary: |
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
243 |
continue |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
244 |
|
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
245 |
# rewrite patch hunk |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
246 |
while pfline < p.lineno: |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
247 |
tmpfp.write(pf.readline()) |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
248 |
pfline += 1 |
3367
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
249 |
|
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
250 |
if p.binary: |
3717
9e248cfd8b94
handle files with more than one git binary patch
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3716
diff
changeset
|
251 |
text, delta = extractbin(pf) |
3367
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
252 |
if not text: |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
253 |
raise util.Abort(_('binary patch extraction failed')) |
3717
9e248cfd8b94
handle files with more than one git binary patch
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3716
diff
changeset
|
254 |
pfline += delta |
3367
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
255 |
if not cwd: |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
256 |
cwd = os.getcwd() |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
257 |
absdst = os.path.join(cwd, p.path) |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
258 |
basedir = os.path.dirname(absdst) |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
259 |
if not os.path.isdir(basedir): |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
260 |
os.makedirs(basedir) |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
261 |
out = file(absdst, 'wb') |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
262 |
out.write(text) |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
263 |
out.close() |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
264 |
elif p.copymod: |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
265 |
copyfile(p.oldpath, p.path, basedir=cwd) |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
266 |
tmpfp.write('diff --git a/%s b/%s\n' % (p.path, p.path)) |
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
267 |
line = pf.readline() |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
268 |
pfline += 1 |
3367
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
269 |
while not line.startswith('--- a/'): |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
270 |
tmpfp.write(line) |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
271 |
line = pf.readline() |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
272 |
pfline += 1 |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
273 |
tmpfp.write('--- a/%s\n' % p.path) |
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
274 |
|
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
275 |
line = pf.readline() |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
276 |
while line: |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
277 |
tmpfp.write(line) |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
278 |
line = pf.readline() |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
279 |
except: |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
280 |
tmpfp.close() |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
281 |
os.unlink(patchname) |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
282 |
raise |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
283 |
|
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
284 |
tmpfp.close() |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
285 |
return patchname |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
286 |
|
3465
2d35a8d2b32d
patch: return list of modified files even when an exception is raised
Brendan Cully <brendan@kublai.com>
parents:
3387
diff
changeset
|
287 |
def patch(patchname, ui, strip=1, cwd=None, files={}): |
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
288 |
"""apply the patch <patchname> to the working directory. |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
289 |
a list of patched files is returned""" |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
290 |
|
3057
d16b93f4a6ca
unlink temporary patch files even when an exception is raised
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3056
diff
changeset
|
291 |
# helper function |
d16b93f4a6ca
unlink temporary patch files even when an exception is raised
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3056
diff
changeset
|
292 |
def __patch(patchname): |
d16b93f4a6ca
unlink temporary patch files even when an exception is raised
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3056
diff
changeset
|
293 |
"""patch and updates the files and fuzz variables""" |
d16b93f4a6ca
unlink temporary patch files even when an exception is raised
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3056
diff
changeset
|
294 |
fuzz = False |
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
295 |
|
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
296 |
args = [] |
4435 | 297 |
patcher = ui.config('ui', 'patch') |
298 |
if not patcher: |
|
299 |
patcher = util.find_in_path('gpatch', os.environ.get('PATH', ''), |
|
300 |
'patch') |
|
301 |
if util.needbinarypatch(): |
|
302 |
args.append('--binary') |
|
4434
439b1c35348a
Fix issue483 - mq does not work under windows with gnu-win32 patch.
Patrick Mezard <pmezard@gmail.com>
parents:
4325
diff
changeset
|
303 |
|
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
304 |
if cwd: |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
305 |
args.append('-d %s' % util.shellquote(cwd)) |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
306 |
fp = os.popen('%s %s -p%d < %s' % (patcher, ' '.join(args), strip, |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
307 |
util.shellquote(patchname))) |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
308 |
|
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
309 |
for line in fp: |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
310 |
line = line.rstrip() |
2919
b70740aefa4d
Unify mq and hg patch invocation.
Brendan Cully <brendan@kublai.com>
parents:
2907
diff
changeset
|
311 |
ui.note(line + '\n') |
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
312 |
if line.startswith('patching file '): |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
313 |
pf = util.parse_patch_output(line) |
2919
b70740aefa4d
Unify mq and hg patch invocation.
Brendan Cully <brendan@kublai.com>
parents:
2907
diff
changeset
|
314 |
printed_file = False |
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
315 |
files.setdefault(pf, (None, None)) |
2919
b70740aefa4d
Unify mq and hg patch invocation.
Brendan Cully <brendan@kublai.com>
parents:
2907
diff
changeset
|
316 |
elif line.find('with fuzz') >= 0: |
b70740aefa4d
Unify mq and hg patch invocation.
Brendan Cully <brendan@kublai.com>
parents:
2907
diff
changeset
|
317 |
fuzz = True |
b70740aefa4d
Unify mq and hg patch invocation.
Brendan Cully <brendan@kublai.com>
parents:
2907
diff
changeset
|
318 |
if not printed_file: |
b70740aefa4d
Unify mq and hg patch invocation.
Brendan Cully <brendan@kublai.com>
parents:
2907
diff
changeset
|
319 |
ui.warn(pf + '\n') |
b70740aefa4d
Unify mq and hg patch invocation.
Brendan Cully <brendan@kublai.com>
parents:
2907
diff
changeset
|
320 |
printed_file = True |
b70740aefa4d
Unify mq and hg patch invocation.
Brendan Cully <brendan@kublai.com>
parents:
2907
diff
changeset
|
321 |
ui.warn(line + '\n') |
b70740aefa4d
Unify mq and hg patch invocation.
Brendan Cully <brendan@kublai.com>
parents:
2907
diff
changeset
|
322 |
elif line.find('saving rejects to file') >= 0: |
b70740aefa4d
Unify mq and hg patch invocation.
Brendan Cully <brendan@kublai.com>
parents:
2907
diff
changeset
|
323 |
ui.warn(line + '\n') |
b70740aefa4d
Unify mq and hg patch invocation.
Brendan Cully <brendan@kublai.com>
parents:
2907
diff
changeset
|
324 |
elif line.find('FAILED') >= 0: |
b70740aefa4d
Unify mq and hg patch invocation.
Brendan Cully <brendan@kublai.com>
parents:
2907
diff
changeset
|
325 |
if not printed_file: |
b70740aefa4d
Unify mq and hg patch invocation.
Brendan Cully <brendan@kublai.com>
parents:
2907
diff
changeset
|
326 |
ui.warn(pf + '\n') |
b70740aefa4d
Unify mq and hg patch invocation.
Brendan Cully <brendan@kublai.com>
parents:
2907
diff
changeset
|
327 |
printed_file = True |
b70740aefa4d
Unify mq and hg patch invocation.
Brendan Cully <brendan@kublai.com>
parents:
2907
diff
changeset
|
328 |
ui.warn(line + '\n') |
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
329 |
code = fp.close() |
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
330 |
if code: |
2868
9a2a481ec3ea
util: qualify name properly.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2866
diff
changeset
|
331 |
raise util.Abort(_("patch command failed: %s") % |
9a2a481ec3ea
util: qualify name properly.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2866
diff
changeset
|
332 |
util.explain_exit(code)[0]) |
3465
2d35a8d2b32d
patch: return list of modified files even when an exception is raised
Brendan Cully <brendan@kublai.com>
parents:
3387
diff
changeset
|
333 |
return fuzz |
3057
d16b93f4a6ca
unlink temporary patch files even when an exception is raised
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3056
diff
changeset
|
334 |
|
d16b93f4a6ca
unlink temporary patch files even when an exception is raised
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3056
diff
changeset
|
335 |
(dopatch, gitpatches) = readgitpatch(patchname) |
3465
2d35a8d2b32d
patch: return list of modified files even when an exception is raised
Brendan Cully <brendan@kublai.com>
parents:
3387
diff
changeset
|
336 |
for gp in gitpatches: |
2d35a8d2b32d
patch: return list of modified files even when an exception is raised
Brendan Cully <brendan@kublai.com>
parents:
3387
diff
changeset
|
337 |
files[gp.path] = (gp.op, gp) |
3057
d16b93f4a6ca
unlink temporary patch files even when an exception is raised
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3056
diff
changeset
|
338 |
|
3465
2d35a8d2b32d
patch: return list of modified files even when an exception is raised
Brendan Cully <brendan@kublai.com>
parents:
3387
diff
changeset
|
339 |
fuzz = False |
3057
d16b93f4a6ca
unlink temporary patch files even when an exception is raised
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3056
diff
changeset
|
340 |
if dopatch: |
3716
ab5600428b08
handle files with both git binary patches and copy/rename ops
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3702
diff
changeset
|
341 |
filterpatch = dopatch & (GP_FILTER | GP_BINARY) |
ab5600428b08
handle files with both git binary patches and copy/rename ops
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3702
diff
changeset
|
342 |
if filterpatch: |
3057
d16b93f4a6ca
unlink temporary patch files even when an exception is raised
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3056
diff
changeset
|
343 |
patchname = dogitpatch(patchname, gitpatches, cwd=cwd) |
d16b93f4a6ca
unlink temporary patch files even when an exception is raised
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3056
diff
changeset
|
344 |
try: |
3716
ab5600428b08
handle files with both git binary patches and copy/rename ops
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3702
diff
changeset
|
345 |
if dopatch & GP_PATCH: |
3465
2d35a8d2b32d
patch: return list of modified files even when an exception is raised
Brendan Cully <brendan@kublai.com>
parents:
3387
diff
changeset
|
346 |
fuzz = __patch(patchname) |
3057
d16b93f4a6ca
unlink temporary patch files even when an exception is raised
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3056
diff
changeset
|
347 |
finally: |
3716
ab5600428b08
handle files with both git binary patches and copy/rename ops
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3702
diff
changeset
|
348 |
if filterpatch: |
3057
d16b93f4a6ca
unlink temporary patch files even when an exception is raised
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3056
diff
changeset
|
349 |
os.unlink(patchname) |
2861
0f08f2c042ec
Move patch-related code into its own module.
Brendan Cully <brendan@kublai.com>
parents:
diff
changeset
|
350 |
|
3465
2d35a8d2b32d
patch: return list of modified files even when an exception is raised
Brendan Cully <brendan@kublai.com>
parents:
3387
diff
changeset
|
351 |
return fuzz |
2874
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
352 |
|
3554
da3ee7ca620f
add untrusted argument to patch.diffopts
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3473
diff
changeset
|
353 |
def diffopts(ui, opts={}, untrusted=False): |
da3ee7ca620f
add untrusted argument to patch.diffopts
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3473
diff
changeset
|
354 |
def get(key, name=None): |
da3ee7ca620f
add untrusted argument to patch.diffopts
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3473
diff
changeset
|
355 |
return (opts.get(key) or |
da3ee7ca620f
add untrusted argument to patch.diffopts
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3473
diff
changeset
|
356 |
ui.configbool('diff', name or key, None, untrusted=untrusted)) |
2888
3848488244fc
Move ui.diffopts to patch.diffopts where it belongs
Matt Mackall <mpm@selenic.com>
parents:
2881
diff
changeset
|
357 |
return mdiff.diffopts( |
3848488244fc
Move ui.diffopts to patch.diffopts where it belongs
Matt Mackall <mpm@selenic.com>
parents:
2881
diff
changeset
|
358 |
text=opts.get('text'), |
3554
da3ee7ca620f
add untrusted argument to patch.diffopts
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3473
diff
changeset
|
359 |
git=get('git'), |
da3ee7ca620f
add untrusted argument to patch.diffopts
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3473
diff
changeset
|
360 |
nodates=get('nodates'), |
da3ee7ca620f
add untrusted argument to patch.diffopts
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3473
diff
changeset
|
361 |
showfunc=get('show_function', 'showfunc'), |
da3ee7ca620f
add untrusted argument to patch.diffopts
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3473
diff
changeset
|
362 |
ignorews=get('ignore_all_space', 'ignorews'), |
da3ee7ca620f
add untrusted argument to patch.diffopts
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3473
diff
changeset
|
363 |
ignorewsamount=get('ignore_space_change', 'ignorewsamount'), |
da3ee7ca620f
add untrusted argument to patch.diffopts
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3473
diff
changeset
|
364 |
ignoreblanklines=get('ignore_blank_lines', 'ignoreblanklines')) |
2888
3848488244fc
Move ui.diffopts to patch.diffopts where it belongs
Matt Mackall <mpm@selenic.com>
parents:
2881
diff
changeset
|
365 |
|
2933
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
366 |
def updatedir(ui, repo, patches, wlock=None): |
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
367 |
'''Update dirstate after patch application according to metadata''' |
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
368 |
if not patches: |
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
369 |
return |
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
370 |
copies = [] |
3701
05c8704a3743
handle git patches that rename a file to more than one destination
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3696
diff
changeset
|
371 |
removes = {} |
2933
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
372 |
cfiles = patches.keys() |
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
373 |
cwd = repo.getcwd() |
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
374 |
if cwd: |
4229
24c22a3f2ef8
pass repo.root to util.pathto() in preparation for the next patch
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4106
diff
changeset
|
375 |
cfiles = [util.pathto(repo.root, cwd, f) for f in patches.keys()] |
2933
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
376 |
for f in patches: |
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
377 |
ctype, gp = patches[f] |
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
378 |
if ctype == 'RENAME': |
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
379 |
copies.append((gp.oldpath, gp.path, gp.copymod)) |
3701
05c8704a3743
handle git patches that rename a file to more than one destination
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3696
diff
changeset
|
380 |
removes[gp.oldpath] = 1 |
2933
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
381 |
elif ctype == 'COPY': |
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
382 |
copies.append((gp.oldpath, gp.path, gp.copymod)) |
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
383 |
elif ctype == 'DELETE': |
3701
05c8704a3743
handle git patches that rename a file to more than one destination
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3696
diff
changeset
|
384 |
removes[gp.path] = 1 |
2933
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
385 |
for src, dst, after in copies: |
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
386 |
if not after: |
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
387 |
copyfile(src, dst, repo.root) |
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
388 |
repo.copy(src, dst, wlock=wlock) |
3701
05c8704a3743
handle git patches that rename a file to more than one destination
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3696
diff
changeset
|
389 |
removes = removes.keys() |
2933
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
390 |
if removes: |
3701
05c8704a3743
handle git patches that rename a file to more than one destination
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3696
diff
changeset
|
391 |
removes.sort() |
2933
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
392 |
repo.remove(removes, True, wlock=wlock) |
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
393 |
for f in patches: |
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
394 |
ctype, gp = patches[f] |
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
395 |
if gp and gp.mode: |
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
396 |
x = gp.mode & 0100 != 0 |
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
397 |
dst = os.path.join(repo.root, gp.path) |
3588
45574a225632
git patch: create empty added files
Brendan Cully <brendan@kublai.com>
parents:
3554
diff
changeset
|
398 |
# patch won't create empty files |
45574a225632
git patch: create empty added files
Brendan Cully <brendan@kublai.com>
parents:
3554
diff
changeset
|
399 |
if ctype == 'ADD' and not os.path.exists(dst): |
4006
67982d3ee76c
symlinks: add flags param to wwrite
Matt Mackall <mpm@selenic.com>
parents:
3996
diff
changeset
|
400 |
repo.wwrite(gp.path, '', x and 'x' or '') |
67982d3ee76c
symlinks: add flags param to wwrite
Matt Mackall <mpm@selenic.com>
parents:
3996
diff
changeset
|
401 |
else: |
67982d3ee76c
symlinks: add flags param to wwrite
Matt Mackall <mpm@selenic.com>
parents:
3996
diff
changeset
|
402 |
util.set_exec(dst, x) |
2933
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
403 |
cmdutil.addremove(repo, cfiles, wlock=wlock) |
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
404 |
files = patches.keys() |
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
405 |
files.extend([r for r in removes if r not in files]) |
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
406 |
files.sort() |
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
407 |
|
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
408 |
return files |
439fd013360d
Move import's working dir update code into patch.updatedir
Brendan Cully <brendan@kublai.com>
parents:
2922
diff
changeset
|
409 |
|
3367
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
410 |
def b85diff(fp, to, tn): |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
411 |
'''print base85-encoded binary diff''' |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
412 |
def gitindex(text): |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
413 |
if not text: |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
414 |
return '0' * 40 |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
415 |
l = len(text) |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
416 |
s = sha.new('blob %d\0' % l) |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
417 |
s.update(text) |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
418 |
return s.hexdigest() |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
419 |
|
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
420 |
def fmtline(line): |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
421 |
l = len(line) |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
422 |
if l <= 26: |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
423 |
l = chr(ord('A') + l - 1) |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
424 |
else: |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
425 |
l = chr(l - 26 + ord('a') - 1) |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
426 |
return '%c%s\n' % (l, base85.b85encode(line, True)) |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
427 |
|
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
428 |
def chunk(text, csize=52): |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
429 |
l = len(text) |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
430 |
i = 0 |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
431 |
while i < l: |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
432 |
yield text[i:i+csize] |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
433 |
i += csize |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
434 |
|
4105
ed46895aa38c
git binary patches: use hashes to detect identical files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4092
diff
changeset
|
435 |
tohash = gitindex(to) |
ed46895aa38c
git binary patches: use hashes to detect identical files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4092
diff
changeset
|
436 |
tnhash = gitindex(tn) |
ed46895aa38c
git binary patches: use hashes to detect identical files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4092
diff
changeset
|
437 |
if tohash == tnhash: |
4106
797dbdd4d7e1
git binary patches: don't print the header for identical files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4105
diff
changeset
|
438 |
return "" |
797dbdd4d7e1
git binary patches: don't print the header for identical files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4105
diff
changeset
|
439 |
|
3367
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
440 |
# TODO: deltas |
4106
797dbdd4d7e1
git binary patches: don't print the header for identical files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4105
diff
changeset
|
441 |
ret = ['index %s..%s\nGIT binary patch\nliteral %s\n' % |
797dbdd4d7e1
git binary patches: don't print the header for identical files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4105
diff
changeset
|
442 |
(tohash, tnhash, len(tn))] |
797dbdd4d7e1
git binary patches: don't print the header for identical files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4105
diff
changeset
|
443 |
for l in chunk(zlib.compress(tn)): |
797dbdd4d7e1
git binary patches: don't print the header for identical files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4105
diff
changeset
|
444 |
ret.append(fmtline(l)) |
797dbdd4d7e1
git binary patches: don't print the header for identical files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4105
diff
changeset
|
445 |
ret.append('\n') |
797dbdd4d7e1
git binary patches: don't print the header for identical files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4105
diff
changeset
|
446 |
return ''.join(ret) |
3367
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
447 |
|
2874
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
448 |
def diff(repo, node1=None, node2=None, files=None, match=util.always, |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
449 |
fp=None, changes=None, opts=None): |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
450 |
'''print diff of changes to files between two nodes, or node and |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
451 |
working directory. |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
452 |
|
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
453 |
if node1 is None, use first dirstate parent instead. |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
454 |
if node2 is None, compare node1 with working directory.''' |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
455 |
|
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
456 |
if opts is None: |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
457 |
opts = mdiff.defaultopts |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
458 |
if fp is None: |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
459 |
fp = repo.ui |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
460 |
|
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
461 |
if not node1: |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
462 |
node1 = repo.dirstate.parents()[0] |
2934
2f190e998eb3
Teach mq about git patches
Brendan Cully <brendan@kublai.com>
parents:
2933
diff
changeset
|
463 |
|
3967
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
464 |
ccache = {} |
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
465 |
def getctx(r): |
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
466 |
if r not in ccache: |
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
467 |
ccache[r] = context.changectx(repo, r) |
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
468 |
return ccache[r] |
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
469 |
|
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
470 |
flcache = {} |
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
471 |
def getfilectx(f, ctx): |
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
472 |
flctx = ctx.filectx(f, filelog=flcache.get(f)) |
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
473 |
if f not in flcache: |
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
474 |
flcache[f] = flctx._filelog |
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
475 |
return flctx |
2934
2f190e998eb3
Teach mq about git patches
Brendan Cully <brendan@kublai.com>
parents:
2933
diff
changeset
|
476 |
|
2874
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
477 |
# reading the data for node1 early allows it to play nicely |
2875
3d6efcbbd1c9
remove localrepository.changes.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2874
diff
changeset
|
478 |
# with repo.status and the revlog cache. |
3967
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
479 |
ctx1 = context.changectx(repo, node1) |
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
480 |
# force manifest reading |
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
481 |
man1 = ctx1.manifest() |
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
482 |
date1 = util.datestr(ctx1.date()) |
2874
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
483 |
|
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
484 |
if not changes: |
2875
3d6efcbbd1c9
remove localrepository.changes.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2874
diff
changeset
|
485 |
changes = repo.status(node1, node2, files, match=match)[:5] |
2874
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
486 |
modified, added, removed, deleted, unknown = changes |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
487 |
|
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
488 |
if not modified and not added and not removed: |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
489 |
return |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
490 |
|
3967
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
491 |
if node2: |
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
492 |
ctx2 = context.changectx(repo, node2) |
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
493 |
else: |
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
494 |
ctx2 = context.workingctx(repo) |
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
495 |
man2 = ctx2.manifest() |
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
496 |
|
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
497 |
# returns False if there was no rename between ctx1 and ctx2 |
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
498 |
# returns None if the file was created between ctx1 and ctx2 |
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
499 |
# returns the (file, node) present in ctx1 that was renamed to f in ctx2 |
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
500 |
def renamed(f): |
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
501 |
startrev = ctx1.rev() |
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
502 |
c = ctx2 |
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
503 |
crev = c.rev() |
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
504 |
if crev is None: |
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
505 |
crev = repo.changelog.count() |
3694
c0b1a0c72c7d
renamedbetween: only return (file, node) pairs that exist in the original rev
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3693
diff
changeset
|
506 |
orig = f |
3967
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
507 |
while crev > startrev: |
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
508 |
if f in c.files(): |
3693
454b3a8cdf28
diff: improve detection of renames when diffing across many revisions
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3673
diff
changeset
|
509 |
try: |
3967
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
510 |
src = getfilectx(f, c).renamed() |
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
511 |
except revlog.LookupError: |
3693
454b3a8cdf28
diff: improve detection of renames when diffing across many revisions
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3673
diff
changeset
|
512 |
return None |
454b3a8cdf28
diff: improve detection of renames when diffing across many revisions
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3673
diff
changeset
|
513 |
if src: |
454b3a8cdf28
diff: improve detection of renames when diffing across many revisions
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3673
diff
changeset
|
514 |
f = src[0] |
3967
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
515 |
crev = c.parents()[0].rev() |
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
516 |
# try to reuse |
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
517 |
c = getctx(crev) |
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
518 |
if f not in man1: |
3694
c0b1a0c72c7d
renamedbetween: only return (file, node) pairs that exist in the original rev
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3693
diff
changeset
|
519 |
return None |
3696
562a65635bcb
diff: better detection of renames when comparing with the working dir.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3695
diff
changeset
|
520 |
if f == orig: |
562a65635bcb
diff: better detection of renames when comparing with the working dir.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3695
diff
changeset
|
521 |
return False |
3967
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
522 |
return f |
2874
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
523 |
|
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
524 |
if repo.ui.quiet: |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
525 |
r = None |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
526 |
else: |
3387
2065789f6a3e
use short hashes with diff -v
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3378
diff
changeset
|
527 |
hexfunc = repo.ui.debugflag and hex or short |
2874
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
528 |
r = [hexfunc(node) for node in [node1, node2] if node] |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
529 |
|
2907 | 530 |
if opts.git: |
531 |
copied = {} |
|
532 |
for f in added: |
|
533 |
src = renamed(f) |
|
534 |
if src: |
|
535 |
copied[f] = src |
|
3967
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
536 |
srcs = [x[1] for x in copied.items()] |
2907 | 537 |
|
2874
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
538 |
all = modified + added + removed |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
539 |
all.sort() |
3702
70c3ee224c08
Don't generate git patches that rename a file to multiple destinations
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3701
diff
changeset
|
540 |
gone = {} |
3996
c190df14338c
exec: add execfunc to simplify exec flag support on non-exec filesystems
Matt Mackall <mpm@selenic.com>
parents:
3970
diff
changeset
|
541 |
|
2874
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
542 |
for f in all: |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
543 |
to = None |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
544 |
tn = None |
2907 | 545 |
dodiff = True |
3329
319358e6bd96
Don't generate git diff header for empty diffs
Brendan Cully <brendan@kublai.com>
parents:
3231
diff
changeset
|
546 |
header = [] |
3967
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
547 |
if f in man1: |
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
548 |
to = getfilectx(f, ctx1).data() |
2874
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
549 |
if f not in removed: |
3967
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
550 |
tn = getfilectx(f, ctx2).data() |
2907 | 551 |
if opts.git: |
552 |
def gitmode(x): |
|
553 |
return x and '100755' or '100644' |
|
554 |
def addmodehdr(header, omode, nmode): |
|
555 |
if omode != nmode: |
|
556 |
header.append('old mode %s\n' % omode) |
|
557 |
header.append('new mode %s\n' % nmode) |
|
558 |
||
559 |
a, b = f, f |
|
560 |
if f in added: |
|
3967
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
561 |
mode = gitmode(man2.execf(f)) |
2907 | 562 |
if f in copied: |
3967
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
563 |
a = copied[f] |
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
564 |
omode = gitmode(man1.execf(a)) |
2907 | 565 |
addmodehdr(header, omode, mode) |
3702
70c3ee224c08
Don't generate git patches that rename a file to multiple destinations
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3701
diff
changeset
|
566 |
if a in removed and a not in gone: |
70c3ee224c08
Don't generate git patches that rename a file to multiple destinations
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3701
diff
changeset
|
567 |
op = 'rename' |
70c3ee224c08
Don't generate git patches that rename a file to multiple destinations
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3701
diff
changeset
|
568 |
gone[a] = 1 |
70c3ee224c08
Don't generate git patches that rename a file to multiple destinations
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3701
diff
changeset
|
569 |
else: |
70c3ee224c08
Don't generate git patches that rename a file to multiple destinations
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3701
diff
changeset
|
570 |
op = 'copy' |
2907 | 571 |
header.append('%s from %s\n' % (op, a)) |
572 |
header.append('%s to %s\n' % (op, f)) |
|
3967
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
573 |
to = getfilectx(a, ctx1).data() |
2907 | 574 |
else: |
575 |
header.append('new file mode %s\n' % mode) |
|
4092
4ced663bebf0
git patches: handle renames of binary files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3900
diff
changeset
|
576 |
if util.binary(tn): |
4ced663bebf0
git patches: handle renames of binary files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
3900
diff
changeset
|
577 |
dodiff = 'binary' |
2907 | 578 |
elif f in removed: |
579 |
if f in srcs: |
|
580 |
dodiff = False |
|
581 |
else: |
|
3967
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
582 |
mode = gitmode(man1.execf(f)) |
2907 | 583 |
header.append('deleted file mode %s\n' % mode) |
584 |
else: |
|
3967
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
585 |
omode = gitmode(man1.execf(f)) |
dccb83241dd0
patch: use contexts for diff
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3963
diff
changeset
|
586 |
nmode = gitmode(man2.execf(f)) |
2907 | 587 |
addmodehdr(header, omode, nmode) |
3367
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
588 |
if util.binary(to) or util.binary(tn): |
7f486971d263
Add git-1.4 binary patch support
Brendan Cully <brendan@kublai.com>
parents:
3329
diff
changeset
|
589 |
dodiff = 'binary' |
2907 | 590 |
r = None |
3329
319358e6bd96
Don't generate git diff header for empty diffs
Brendan Cully <brendan@kublai.com>
parents:
3231
diff
changeset
|
591 |
header.insert(0, 'diff --git a/%s b/%s\n' % (a, b)) |
4106
797dbdd4d7e1
git binary patches: don't print the header for identical files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4105
diff
changeset
|
592 |
if dodiff: |
797dbdd4d7e1
git binary patches: don't print the header for identical files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4105
diff
changeset
|
593 |
if dodiff == 'binary': |
797dbdd4d7e1
git binary patches: don't print the header for identical files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4105
diff
changeset
|
594 |
text = b85diff(fp, to, tn) |
797dbdd4d7e1
git binary patches: don't print the header for identical files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4105
diff
changeset
|
595 |
else: |
4108 | 596 |
text = mdiff.unidiff(to, date1, |
597 |
# ctx2 date may be dynamic |
|
598 |
tn, util.datestr(ctx2.date()), |
|
599 |
f, r, opts=opts) |
|
3329
319358e6bd96
Don't generate git diff header for empty diffs
Brendan Cully <brendan@kublai.com>
parents:
3231
diff
changeset
|
600 |
if text or len(header) > 1: |
2907 | 601 |
fp.write(''.join(header)) |
3329
319358e6bd96
Don't generate git diff header for empty diffs
Brendan Cully <brendan@kublai.com>
parents:
3231
diff
changeset
|
602 |
fp.write(text) |
2874
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
603 |
|
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
604 |
def export(repo, revs, template='hg-%h.patch', fp=None, switch_parent=False, |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
605 |
opts=None): |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
606 |
'''export changesets as hg patches.''' |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
607 |
|
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
608 |
total = len(revs) |
3900
2b3175acb653
Don't use node length for calculating revision number length.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
3899
diff
changeset
|
609 |
revwidth = max([len(str(rev)) for rev in revs]) |
2874
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
610 |
|
3970
fff8a5345eb0
commands.py: use contexts in export
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3967
diff
changeset
|
611 |
def single(rev, seqno, fp): |
fff8a5345eb0
commands.py: use contexts in export
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3967
diff
changeset
|
612 |
ctx = repo.changectx(rev) |
fff8a5345eb0
commands.py: use contexts in export
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3967
diff
changeset
|
613 |
node = ctx.node() |
fff8a5345eb0
commands.py: use contexts in export
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3967
diff
changeset
|
614 |
parents = [p.node() for p in ctx.parents() if p] |
4436
a764edb6fc95
Add branch information to hg export.
Eric Hopper <hopper@omnifarious.org>
parents:
4435
diff
changeset
|
615 |
branch = ctx.branch() |
2874
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
616 |
if switch_parent: |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
617 |
parents.reverse() |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
618 |
prev = (parents and parents[0]) or nullid |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
619 |
|
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
620 |
if not fp: |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
621 |
fp = cmdutil.make_file(repo, template, node, total=total, |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
622 |
seqno=seqno, revwidth=revwidth) |
4125
ef7c39ae5d4c
Suppress <stdout> before hg export -v (regression from previous patch).
Brendan Cully <brendan@kublai.com>
parents:
4124
diff
changeset
|
623 |
if fp != sys.stdout and hasattr(fp, 'name'): |
2874
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
624 |
repo.ui.note("%s\n" % fp.name) |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
625 |
|
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
626 |
fp.write("# HG changeset patch\n") |
3970
fff8a5345eb0
commands.py: use contexts in export
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3967
diff
changeset
|
627 |
fp.write("# User %s\n" % ctx.user()) |
fff8a5345eb0
commands.py: use contexts in export
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3967
diff
changeset
|
628 |
fp.write("# Date %d %d\n" % ctx.date()) |
4436
a764edb6fc95
Add branch information to hg export.
Eric Hopper <hopper@omnifarious.org>
parents:
4435
diff
changeset
|
629 |
if branch and (branch != 'default'): |
a764edb6fc95
Add branch information to hg export.
Eric Hopper <hopper@omnifarious.org>
parents:
4435
diff
changeset
|
630 |
fp.write("# Branch %s\n" % branch) |
2874
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
631 |
fp.write("# Node ID %s\n" % hex(node)) |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
632 |
fp.write("# Parent %s\n" % hex(prev)) |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
633 |
if len(parents) > 1: |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
634 |
fp.write("# Parent %s\n" % hex(parents[1])) |
3970
fff8a5345eb0
commands.py: use contexts in export
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3967
diff
changeset
|
635 |
fp.write(ctx.description().rstrip()) |
2874
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
636 |
fp.write("\n\n") |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
637 |
|
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
638 |
diff(repo, prev, node, fp=fp, opts=opts) |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
639 |
if fp not in (sys.stdout, repo.ui): |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
640 |
fp.close() |
4ec58b157265
refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2868
diff
changeset
|
641 |
|
3900
2b3175acb653
Don't use node length for calculating revision number length.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
3899
diff
changeset
|
642 |
for seqno, rev in enumerate(revs): |
3970
fff8a5345eb0
commands.py: use contexts in export
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3967
diff
changeset
|
643 |
single(rev, seqno+1, fp) |
3096
f422c8265ae5
Add support for diffstat in commit emails, and move diffstat from
Matt Doar <matt@xensource.com>
parents:
3066
diff
changeset
|
644 |
|
f422c8265ae5
Add support for diffstat in commit emails, and move diffstat from
Matt Doar <matt@xensource.com>
parents:
3066
diff
changeset
|
645 |
def diffstat(patchlines): |
4316
6e4334be0aaa
Try to find diffstat in PATH before calling it
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4229
diff
changeset
|
646 |
if not util.find_in_path('diffstat', os.environ.get('PATH', '')): |
6e4334be0aaa
Try to find diffstat in PATH before calling it
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4229
diff
changeset
|
647 |
return |
3096
f422c8265ae5
Add support for diffstat in commit emails, and move diffstat from
Matt Doar <matt@xensource.com>
parents:
3066
diff
changeset
|
648 |
fd, name = tempfile.mkstemp(prefix="hg-patchbomb-", suffix=".txt") |
f422c8265ae5
Add support for diffstat in commit emails, and move diffstat from
Matt Doar <matt@xensource.com>
parents:
3066
diff
changeset
|
649 |
try: |
f422c8265ae5
Add support for diffstat in commit emails, and move diffstat from
Matt Doar <matt@xensource.com>
parents:
3066
diff
changeset
|
650 |
p = popen2.Popen3('diffstat -p1 -w79 2>/dev/null > ' + name) |
f422c8265ae5
Add support for diffstat in commit emails, and move diffstat from
Matt Doar <matt@xensource.com>
parents:
3066
diff
changeset
|
651 |
try: |
f422c8265ae5
Add support for diffstat in commit emails, and move diffstat from
Matt Doar <matt@xensource.com>
parents:
3066
diff
changeset
|
652 |
for line in patchlines: print >> p.tochild, line |
f422c8265ae5
Add support for diffstat in commit emails, and move diffstat from
Matt Doar <matt@xensource.com>
parents:
3066
diff
changeset
|
653 |
p.tochild.close() |
f422c8265ae5
Add support for diffstat in commit emails, and move diffstat from
Matt Doar <matt@xensource.com>
parents:
3066
diff
changeset
|
654 |
if p.wait(): return |
f422c8265ae5
Add support for diffstat in commit emails, and move diffstat from
Matt Doar <matt@xensource.com>
parents:
3066
diff
changeset
|
655 |
fp = os.fdopen(fd, 'r') |
f422c8265ae5
Add support for diffstat in commit emails, and move diffstat from
Matt Doar <matt@xensource.com>
parents:
3066
diff
changeset
|
656 |
stat = [] |
f422c8265ae5
Add support for diffstat in commit emails, and move diffstat from
Matt Doar <matt@xensource.com>
parents:
3066
diff
changeset
|
657 |
for line in fp: stat.append(line.lstrip()) |
f422c8265ae5
Add support for diffstat in commit emails, and move diffstat from
Matt Doar <matt@xensource.com>
parents:
3066
diff
changeset
|
658 |
last = stat.pop() |
f422c8265ae5
Add support for diffstat in commit emails, and move diffstat from
Matt Doar <matt@xensource.com>
parents:
3066
diff
changeset
|
659 |
stat.insert(0, last) |
f422c8265ae5
Add support for diffstat in commit emails, and move diffstat from
Matt Doar <matt@xensource.com>
parents:
3066
diff
changeset
|
660 |
stat = ''.join(stat) |
f422c8265ae5
Add support for diffstat in commit emails, and move diffstat from
Matt Doar <matt@xensource.com>
parents:
3066
diff
changeset
|
661 |
if stat.startswith('0 files'): raise ValueError |
f422c8265ae5
Add support for diffstat in commit emails, and move diffstat from
Matt Doar <matt@xensource.com>
parents:
3066
diff
changeset
|
662 |
return stat |
f422c8265ae5
Add support for diffstat in commit emails, and move diffstat from
Matt Doar <matt@xensource.com>
parents:
3066
diff
changeset
|
663 |
except: raise |
f422c8265ae5
Add support for diffstat in commit emails, and move diffstat from
Matt Doar <matt@xensource.com>
parents:
3066
diff
changeset
|
664 |
finally: |
f422c8265ae5
Add support for diffstat in commit emails, and move diffstat from
Matt Doar <matt@xensource.com>
parents:
3066
diff
changeset
|
665 |
try: os.unlink(name) |
f422c8265ae5
Add support for diffstat in commit emails, and move diffstat from
Matt Doar <matt@xensource.com>
parents:
3066
diff
changeset
|
666 |
except: pass |