Show More
@@ -0,0 +1,251 b'' | |||||
|
1 | # patch.py - patch file parsing routines | |||
|
2 | # | |||
|
3 | # Copyright 2006 Brendan Cully <brendan@kublai.com> | |||
|
4 | # | |||
|
5 | # This software may be used and distributed according to the terms | |||
|
6 | # of the GNU General Public License, incorporated herein by reference. | |||
|
7 | ||||
|
8 | from demandload import demandload | |||
|
9 | from i18n import gettext as _ | |||
|
10 | demandload(globals(), "util") | |||
|
11 | demandload(globals(), "cStringIO email.Parser os re shutil tempfile") | |||
|
12 | ||||
|
13 | def extract(ui, fileobj): | |||
|
14 | '''extract patch from data read from fileobj. | |||
|
15 | ||||
|
16 | patch can be normal patch or contained in email message. | |||
|
17 | ||||
|
18 | return tuple (filename, message, user, date). any item in returned | |||
|
19 | tuple can be None. if filename is None, fileobj did not contain | |||
|
20 | patch. caller must unlink filename when done.''' | |||
|
21 | ||||
|
22 | # attempt to detect the start of a patch | |||
|
23 | # (this heuristic is borrowed from quilt) | |||
|
24 | diffre = re.compile(r'^(?:Index:[ \t]|diff[ \t]|RCS file: |' + | |||
|
25 | 'retrieving revision [0-9]+(\.[0-9]+)*$|' + | |||
|
26 | '(---|\*\*\*)[ \t])', re.MULTILINE) | |||
|
27 | ||||
|
28 | fd, tmpname = tempfile.mkstemp(prefix='hg-patch-') | |||
|
29 | tmpfp = os.fdopen(fd, 'w') | |||
|
30 | try: | |||
|
31 | hgpatch = False | |||
|
32 | ||||
|
33 | msg = email.Parser.Parser().parse(fileobj) | |||
|
34 | ||||
|
35 | message = msg['Subject'] | |||
|
36 | user = msg['From'] | |||
|
37 | # should try to parse msg['Date'] | |||
|
38 | date = None | |||
|
39 | ||||
|
40 | if message: | |||
|
41 | message = message.replace('\n\t', ' ') | |||
|
42 | ui.debug('Subject: %s\n' % message) | |||
|
43 | if user: | |||
|
44 | ui.debug('From: %s\n' % user) | |||
|
45 | diffs_seen = 0 | |||
|
46 | ok_types = ('text/plain', 'text/x-diff', 'text/x-patch') | |||
|
47 | ||||
|
48 | for part in msg.walk(): | |||
|
49 | content_type = part.get_content_type() | |||
|
50 | ui.debug('Content-Type: %s\n' % content_type) | |||
|
51 | if content_type not in ok_types: | |||
|
52 | continue | |||
|
53 | payload = part.get_payload(decode=True) | |||
|
54 | m = diffre.search(payload) | |||
|
55 | if m: | |||
|
56 | ui.debug(_('found patch at byte %d\n') % m.start(0)) | |||
|
57 | diffs_seen += 1 | |||
|
58 | cfp = cStringIO.StringIO() | |||
|
59 | if message: | |||
|
60 | cfp.write(message) | |||
|
61 | cfp.write('\n') | |||
|
62 | for line in payload[:m.start(0)].splitlines(): | |||
|
63 | if line.startswith('# HG changeset patch'): | |||
|
64 | ui.debug(_('patch generated by hg export\n')) | |||
|
65 | hgpatch = True | |||
|
66 | # drop earlier commit message content | |||
|
67 | cfp.seek(0) | |||
|
68 | cfp.truncate() | |||
|
69 | elif hgpatch: | |||
|
70 | if line.startswith('# User '): | |||
|
71 | user = line[7:] | |||
|
72 | ui.debug('From: %s\n' % user) | |||
|
73 | elif line.startswith("# Date "): | |||
|
74 | date = line[7:] | |||
|
75 | if not line.startswith('# '): | |||
|
76 | cfp.write(line) | |||
|
77 | cfp.write('\n') | |||
|
78 | message = cfp.getvalue() | |||
|
79 | if tmpfp: | |||
|
80 | tmpfp.write(payload) | |||
|
81 | if not payload.endswith('\n'): | |||
|
82 | tmpfp.write('\n') | |||
|
83 | elif not diffs_seen and message and content_type == 'text/plain': | |||
|
84 | message += '\n' + payload | |||
|
85 | except: | |||
|
86 | tmpfp.close() | |||
|
87 | os.unlink(tmpname) | |||
|
88 | raise | |||
|
89 | ||||
|
90 | tmpfp.close() | |||
|
91 | if not diffs_seen: | |||
|
92 | os.unlink(tmpname) | |||
|
93 | return None, message, user, date | |||
|
94 | return tmpname, message, user, date | |||
|
95 | ||||
|
96 | def readgitpatch(patchname): | |||
|
97 | """extract git-style metadata about patches from <patchname>""" | |||
|
98 | class gitpatch: | |||
|
99 | "op is one of ADD, DELETE, RENAME, MODIFY or COPY" | |||
|
100 | def __init__(self, path): | |||
|
101 | self.path = path | |||
|
102 | self.oldpath = None | |||
|
103 | self.mode = None | |||
|
104 | self.op = 'MODIFY' | |||
|
105 | self.copymod = False | |||
|
106 | self.lineno = 0 | |||
|
107 | ||||
|
108 | # Filter patch for git information | |||
|
109 | gitre = re.compile('diff --git a/(.*) b/(.*)') | |||
|
110 | pf = file(patchname) | |||
|
111 | gp = None | |||
|
112 | gitpatches = [] | |||
|
113 | # Can have a git patch with only metadata, causing patch to complain | |||
|
114 | dopatch = False | |||
|
115 | ||||
|
116 | lineno = 0 | |||
|
117 | for line in pf: | |||
|
118 | lineno += 1 | |||
|
119 | if line.startswith('diff --git'): | |||
|
120 | m = gitre.match(line) | |||
|
121 | if m: | |||
|
122 | if gp: | |||
|
123 | gitpatches.append(gp) | |||
|
124 | src, dst = m.group(1,2) | |||
|
125 | gp = gitpatch(dst) | |||
|
126 | gp.lineno = lineno | |||
|
127 | elif gp: | |||
|
128 | if line.startswith('--- '): | |||
|
129 | if gp.op in ('COPY', 'RENAME'): | |||
|
130 | gp.copymod = True | |||
|
131 | dopatch = 'filter' | |||
|
132 | gitpatches.append(gp) | |||
|
133 | gp = None | |||
|
134 | if not dopatch: | |||
|
135 | dopatch = True | |||
|
136 | continue | |||
|
137 | if line.startswith('rename from '): | |||
|
138 | gp.op = 'RENAME' | |||
|
139 | gp.oldpath = line[12:].rstrip() | |||
|
140 | elif line.startswith('rename to '): | |||
|
141 | gp.path = line[10:].rstrip() | |||
|
142 | elif line.startswith('copy from '): | |||
|
143 | gp.op = 'COPY' | |||
|
144 | gp.oldpath = line[10:].rstrip() | |||
|
145 | elif line.startswith('copy to '): | |||
|
146 | gp.path = line[8:].rstrip() | |||
|
147 | elif line.startswith('deleted file'): | |||
|
148 | gp.op = 'DELETE' | |||
|
149 | elif line.startswith('new file mode '): | |||
|
150 | gp.op = 'ADD' | |||
|
151 | gp.mode = int(line.rstrip()[-3:], 8) | |||
|
152 | elif line.startswith('new mode '): | |||
|
153 | gp.mode = int(line.rstrip()[-3:], 8) | |||
|
154 | if gp: | |||
|
155 | gitpatches.append(gp) | |||
|
156 | ||||
|
157 | if not gitpatches: | |||
|
158 | dopatch = True | |||
|
159 | ||||
|
160 | return (dopatch, gitpatches) | |||
|
161 | ||||
|
162 | def dogitpatch(patchname, gitpatches): | |||
|
163 | """Preprocess git patch so that vanilla patch can handle it""" | |||
|
164 | pf = file(patchname) | |||
|
165 | pfline = 1 | |||
|
166 | ||||
|
167 | fd, patchname = tempfile.mkstemp(prefix='hg-patch-') | |||
|
168 | tmpfp = os.fdopen(fd, 'w') | |||
|
169 | ||||
|
170 | try: | |||
|
171 | for i in range(len(gitpatches)): | |||
|
172 | p = gitpatches[i] | |||
|
173 | if not p.copymod: | |||
|
174 | continue | |||
|
175 | ||||
|
176 | if os.path.exists(p.path): | |||
|
177 | raise util.Abort(_("cannot create %s: destination already exists") % | |||
|
178 | p.path) | |||
|
179 | ||||
|
180 | (src, dst) = [os.path.join(os.getcwd(), n) | |||
|
181 | for n in (p.oldpath, p.path)] | |||
|
182 | ||||
|
183 | targetdir = os.path.dirname(dst) | |||
|
184 | if not os.path.isdir(targetdir): | |||
|
185 | os.makedirs(targetdir) | |||
|
186 | try: | |||
|
187 | shutil.copyfile(src, dst) | |||
|
188 | shutil.copymode(src, dst) | |||
|
189 | except shutil.Error, inst: | |||
|
190 | raise util.Abort(str(inst)) | |||
|
191 | ||||
|
192 | # rewrite patch hunk | |||
|
193 | while pfline < p.lineno: | |||
|
194 | tmpfp.write(pf.readline()) | |||
|
195 | pfline += 1 | |||
|
196 | tmpfp.write('diff --git a/%s b/%s\n' % (p.path, p.path)) | |||
|
197 | line = pf.readline() | |||
|
198 | pfline += 1 | |||
|
199 | while not line.startswith('--- a/'): | |||
|
200 | tmpfp.write(line) | |||
|
201 | line = pf.readline() | |||
|
202 | pfline += 1 | |||
|
203 | tmpfp.write('--- a/%s\n' % p.path) | |||
|
204 | ||||
|
205 | line = pf.readline() | |||
|
206 | while line: | |||
|
207 | tmpfp.write(line) | |||
|
208 | line = pf.readline() | |||
|
209 | except: | |||
|
210 | tmpfp.close() | |||
|
211 | os.unlink(patchname) | |||
|
212 | raise | |||
|
213 | ||||
|
214 | tmpfp.close() | |||
|
215 | return patchname | |||
|
216 | ||||
|
217 | def patch(strip, patchname, ui, cwd=None): | |||
|
218 | """apply the patch <patchname> to the working directory. | |||
|
219 | a list of patched files is returned""" | |||
|
220 | ||||
|
221 | (dopatch, gitpatches) = readgitpatch(patchname) | |||
|
222 | ||||
|
223 | files = {} | |||
|
224 | if dopatch: | |||
|
225 | if dopatch == 'filter': | |||
|
226 | patchname = dogitpatch(patchname, gitpatches) | |||
|
227 | patcher = util.find_in_path('gpatch', os.environ.get('PATH', ''), 'patch') | |||
|
228 | args = [] | |||
|
229 | if cwd: | |||
|
230 | args.append('-d %s' % util.shellquote(cwd)) | |||
|
231 | fp = os.popen('%s %s -p%d < %s' % (patcher, ' '.join(args), strip, | |||
|
232 | util.shellquote(patchname))) | |||
|
233 | ||||
|
234 | if dopatch == 'filter': | |||
|
235 | False and os.unlink(patchname) | |||
|
236 | ||||
|
237 | for line in fp: | |||
|
238 | line = line.rstrip() | |||
|
239 | ui.status("%s\n" % line) | |||
|
240 | if line.startswith('patching file '): | |||
|
241 | pf = util.parse_patch_output(line) | |||
|
242 | files.setdefault(pf, (None, None)) | |||
|
243 | code = fp.close() | |||
|
244 | if code: | |||
|
245 | raise util.Abort(_("patch command failed: %s") % | |||
|
246 | util.explain_exit(code)[0]) | |||
|
247 | ||||
|
248 | for gp in gitpatches: | |||
|
249 | files[gp.path] = (gp.op, gp) | |||
|
250 | ||||
|
251 | return files |
@@ -0,0 +1,122 b'' | |||||
|
1 | #!/bin/sh | |||
|
2 | ||||
|
3 | hg init a | |||
|
4 | cd a | |||
|
5 | ||||
|
6 | echo % new file | |||
|
7 | hg import -mnew - <<EOF | |||
|
8 | diff --git a/new b/new | |||
|
9 | new file mode 100644 | |||
|
10 | index 0000000..7898192 | |||
|
11 | --- /dev/null | |||
|
12 | +++ b/new | |||
|
13 | @@ -0,0 +1 @@ | |||
|
14 | +a | |||
|
15 | EOF | |||
|
16 | ||||
|
17 | echo % chmod +x | |||
|
18 | hg import -msetx - <<EOF | |||
|
19 | diff --git a/new b/new | |||
|
20 | old mode 100644 | |||
|
21 | new mode 100755 | |||
|
22 | EOF | |||
|
23 | ||||
|
24 | test -x new || echo failed | |||
|
25 | ||||
|
26 | echo % copy | |||
|
27 | hg import -mcopy - <<EOF | |||
|
28 | diff --git a/new b/copy | |||
|
29 | old mode 100755 | |||
|
30 | new mode 100644 | |||
|
31 | similarity index 100% | |||
|
32 | copy from new | |||
|
33 | copy to copy | |||
|
34 | diff --git a/new b/copyx | |||
|
35 | similarity index 100% | |||
|
36 | copy from new | |||
|
37 | copy to copyx | |||
|
38 | EOF | |||
|
39 | ||||
|
40 | test -f copy -a ! -x copy || echo failed | |||
|
41 | test -x copyx || echo failed | |||
|
42 | cat copy | |||
|
43 | hg cat copy | |||
|
44 | ||||
|
45 | echo % rename | |||
|
46 | hg import -mrename - <<EOF | |||
|
47 | diff --git a/copy b/rename | |||
|
48 | similarity index 100% | |||
|
49 | rename from copy | |||
|
50 | rename to rename | |||
|
51 | EOF | |||
|
52 | ||||
|
53 | hg locate | |||
|
54 | ||||
|
55 | echo % delete | |||
|
56 | hg import -mdelete - <<EOF | |||
|
57 | diff --git a/copyx b/copyx | |||
|
58 | deleted file mode 100755 | |||
|
59 | index 7898192..0000000 | |||
|
60 | --- a/copyx | |||
|
61 | +++ /dev/null | |||
|
62 | @@ -1 +0,0 @@ | |||
|
63 | -a | |||
|
64 | EOF | |||
|
65 | ||||
|
66 | hg locate | |||
|
67 | test -f copyx && echo failed || true | |||
|
68 | ||||
|
69 | echo % regular diff | |||
|
70 | hg import -mregular - <<EOF | |||
|
71 | diff --git a/rename b/rename | |||
|
72 | index 7898192..72e1fe3 100644 | |||
|
73 | --- a/rename | |||
|
74 | +++ b/rename | |||
|
75 | @@ -1 +1,5 @@ | |||
|
76 | a | |||
|
77 | +a | |||
|
78 | +a | |||
|
79 | +a | |||
|
80 | +a | |||
|
81 | EOF | |||
|
82 | ||||
|
83 | echo % copy and modify | |||
|
84 | hg import -mcopymod - <<EOF | |||
|
85 | diff --git a/rename b/copy2 | |||
|
86 | similarity index 80% | |||
|
87 | copy from rename | |||
|
88 | copy to copy2 | |||
|
89 | index 72e1fe3..b53c148 100644 | |||
|
90 | --- a/rename | |||
|
91 | +++ b/copy2 | |||
|
92 | @@ -1,5 +1,5 @@ | |||
|
93 | a | |||
|
94 | a | |||
|
95 | -a | |||
|
96 | +b | |||
|
97 | a | |||
|
98 | a | |||
|
99 | EOF | |||
|
100 | ||||
|
101 | hg cat copy2 | |||
|
102 | ||||
|
103 | echo % rename and modify | |||
|
104 | hg import -mrenamemod - <<EOF | |||
|
105 | diff --git a/copy2 b/rename2 | |||
|
106 | similarity index 80% | |||
|
107 | rename from copy2 | |||
|
108 | rename to rename2 | |||
|
109 | index b53c148..8f81e29 100644 | |||
|
110 | --- a/copy2 | |||
|
111 | +++ b/rename2 | |||
|
112 | @@ -1,5 +1,5 @@ | |||
|
113 | a | |||
|
114 | a | |||
|
115 | b | |||
|
116 | -a | |||
|
117 | +c | |||
|
118 | a | |||
|
119 | EOF | |||
|
120 | ||||
|
121 | hg locate copy2 | |||
|
122 | hg cat rename2 |
@@ -0,0 +1,39 b'' | |||||
|
1 | % new file | |||
|
2 | applying patch from stdin | |||
|
3 | patching file new | |||
|
4 | % chmod +x | |||
|
5 | applying patch from stdin | |||
|
6 | % copy | |||
|
7 | applying patch from stdin | |||
|
8 | a | |||
|
9 | a | |||
|
10 | % rename | |||
|
11 | applying patch from stdin | |||
|
12 | copyx | |||
|
13 | new | |||
|
14 | rename | |||
|
15 | % delete | |||
|
16 | applying patch from stdin | |||
|
17 | patching file copyx | |||
|
18 | new | |||
|
19 | rename | |||
|
20 | % regular diff | |||
|
21 | applying patch from stdin | |||
|
22 | patching file rename | |||
|
23 | % copy and modify | |||
|
24 | applying patch from stdin | |||
|
25 | patching file copy2 | |||
|
26 | a | |||
|
27 | a | |||
|
28 | b | |||
|
29 | a | |||
|
30 | a | |||
|
31 | % rename and modify | |||
|
32 | applying patch from stdin | |||
|
33 | patching file rename2 | |||
|
34 | copy2: No such file or directory | |||
|
35 | a | |||
|
36 | a | |||
|
37 | b | |||
|
38 | c | |||
|
39 | a |
@@ -216,6 +216,6 b' http://selenic.com/mailman/listinfo/merc' | |||||
216 |
|
216 | |||
217 | COPYING |
|
217 | COPYING | |
218 | ------- |
|
218 | ------- | |
219 | Copyright \(C) 2005 Matt Mackall. |
|
219 | Copyright \(C) 2005, 2006 Matt Mackall. | |
220 | Free use of this software is granted under the terms of the GNU General |
|
220 | Free use of this software is granted under the terms of the GNU General | |
221 | Public License (GPL). |
|
221 | Public License (GPL). |
@@ -30,6 +30,6 b' hg(1) - the command line interface to Me' | |||||
30 |
|
30 | |||
31 | COPYING |
|
31 | COPYING | |
32 | ------- |
|
32 | ------- | |
33 | Copyright \(C) 2005 Matt Mackall. |
|
33 | Copyright \(C) 2005, 2006 Matt Mackall. | |
34 | Free use of this software is granted under the terms of the GNU General |
|
34 | Free use of this software is granted under the terms of the GNU General | |
35 | Public License (GPL). |
|
35 | Public License (GPL). |
@@ -862,6 +862,6 b' http://selenic.com/mailman/listinfo/mercurial[\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\xaa\xe3\x83\xb3\xe3\x82\xb0\xe3\x83\xaa\xe3\x82\xb9\xe3\x83\x88]' | |||||
862 |
|
862 | |||
863 | 著作権情報 |
|
863 | 著作権情報 | |
864 | ----- |
|
864 | ----- | |
865 | Copyright (C) 2005 Matt Mackall. |
|
865 | Copyright (C) 2005, 2006 Matt Mackall. | |
866 | このソフトウェアの自由な使用は GNU 一般公有使用許諾 (GPL) のもとで |
|
866 | このソフトウェアの自由な使用は GNU 一般公有使用許諾 (GPL) のもとで | |
867 | 認められます。 |
|
867 | 認められます。 |
@@ -32,6 +32,6 b' hg(1) - Mercurial \xe3\x82\xb7\xe3\x82\xb9\xe3\x83\x86\xe3\x83\xa0\xe3\x81\xb8\xe3\x81\xae\xe3\x82\xb3\xe3\x83\x9e\xe3\x83\xb3\xe3\x83\x89\xe3\x83\xa9\xe3\x82\xa4\xe3\x83\xb3\xe3\x82\xa4\xe3\x83\xb3\xe3\x82\xbf\xe3\x83\xbc\xe3\x83\x95\xe3\x82\xa7\xe3\x82\xa4\xe3\x82\xb9' | |||||
32 |
|
32 | |||
33 | 著作権情報 |
|
33 | 著作権情報 | |
34 | ---- |
|
34 | ---- | |
35 | Copyright (C) 2005 Matt Mackall. |
|
35 | Copyright (C) 2005, 2006 Matt Mackall. | |
36 | このソフトウェアの自由な使用は GNU 一般公有使用許諾 (GPL) のもとで |
|
36 | このソフトウェアの自由な使用は GNU 一般公有使用許諾 (GPL) のもとで | |
37 | 認められます。 |
|
37 | 認められます。 |
@@ -1,6 +1,6 b'' | |||||
1 | # Minimal support for git commands on an hg repository |
|
1 | # Minimal support for git commands on an hg repository | |
2 | # |
|
2 | # | |
3 | # Copyright 2005 Chris Mason <mason@suse.com> |
|
3 | # Copyright 2005, 2006 Chris Mason <mason@suse.com> | |
4 | # |
|
4 | # | |
5 | # This software may be used and distributed according to the terms |
|
5 | # This software may be used and distributed according to the terms | |
6 | # of the GNU General Public License, incorporated herein by reference. |
|
6 | # of the GNU General Public License, incorporated herein by reference. |
@@ -1,7 +1,6 b'' | |||||
1 |
|
||||
2 |
|
|
1 | # queue.py - patch queues for mercurial | |
3 | # |
|
2 | # | |
4 | # Copyright 2005 Chris Mason <mason@suse.com> |
|
3 | # Copyright 2005, 2006 Chris Mason <mason@suse.com> | |
5 | # |
|
4 | # | |
6 | # This software may be used and distributed according to the terms |
|
5 | # This software may be used and distributed according to the terms | |
7 | # of the GNU General Public License, incorporated herein by reference. |
|
6 | # of the GNU General Public License, incorporated herein by reference. | |
@@ -31,9 +30,9 b' refresh contents of top applied patch ' | |||||
31 | ''' |
|
30 | ''' | |
32 |
|
31 | |||
33 | from mercurial.demandload import * |
|
32 | from mercurial.demandload import * | |
|
33 | from mercurial.i18n import gettext as _ | |||
34 | demandload(globals(), "os sys re struct traceback errno bz2") |
|
34 | demandload(globals(), "os sys re struct traceback errno bz2") | |
35 | from mercurial.i18n import gettext as _ |
|
35 | demandload(globals(), "mercurial:commands,hg,revlog,ui,util") | |
36 | from mercurial import ui, hg, revlog, commands, util |
|
|||
37 |
|
36 | |||
38 | commands.norepo += " qclone qversion" |
|
37 | commands.norepo += " qclone qversion" | |
39 |
|
38 | |||
@@ -561,7 +560,7 b' class queue:' | |||||
561 | r = self.qrepo() |
|
560 | r = self.qrepo() | |
562 | if r: r.add([patch]) |
|
561 | if r: r.add([patch]) | |
563 | if commitfiles: |
|
562 | if commitfiles: | |
564 |
self.refresh(repo, |
|
563 | self.refresh(repo, short=True) | |
565 |
|
564 | |||
566 | def strip(self, repo, rev, update=True, backup="all", wlock=None): |
|
565 | def strip(self, repo, rev, update=True, backup="all", wlock=None): | |
567 | def limitheads(chlog, stop): |
|
566 | def limitheads(chlog, stop): | |
@@ -888,7 +887,6 b' class queue:' | |||||
888 | top = self.check_toppatch(repo) |
|
887 | top = self.check_toppatch(repo) | |
889 | qp = self.qparents(repo, rev) |
|
888 | qp = self.qparents(repo, rev) | |
890 | changes = repo.changelog.read(qp) |
|
889 | changes = repo.changelog.read(qp) | |
891 | mf1 = repo.manifest.readflags(changes[0]) |
|
|||
892 | mmap = repo.manifest.read(changes[0]) |
|
890 | mmap = repo.manifest.read(changes[0]) | |
893 | (c, a, r, d, u) = repo.changes(qp, top) |
|
891 | (c, a, r, d, u) = repo.changes(qp, top) | |
894 | if d: |
|
892 | if d: | |
@@ -897,7 +895,7 b' class queue:' | |||||
897 | getfile(f, mmap[f]) |
|
895 | getfile(f, mmap[f]) | |
898 | for f in r: |
|
896 | for f in r: | |
899 | getfile(f, mmap[f]) |
|
897 | getfile(f, mmap[f]) | |
900 |
util.set_exec(repo.wjoin(f), mf |
|
898 | util.set_exec(repo.wjoin(f), mmap.execf[f]) | |
901 | repo.dirstate.update(c + r, 'n') |
|
899 | repo.dirstate.update(c + r, 'n') | |
902 | for f in a: |
|
900 | for f in a: | |
903 | try: os.unlink(repo.wjoin(f)) |
|
901 | try: os.unlink(repo.wjoin(f)) | |
@@ -922,7 +920,7 b' class queue:' | |||||
922 | qp = self.qparents(repo, top) |
|
920 | qp = self.qparents(repo, top) | |
923 | commands.dodiff(sys.stdout, self.ui, repo, qp, None, files) |
|
921 | commands.dodiff(sys.stdout, self.ui, repo, qp, None, files) | |
924 |
|
922 | |||
925 |
def refresh(self, repo, msg= |
|
923 | def refresh(self, repo, msg='', short=False): | |
926 | if len(self.applied) == 0: |
|
924 | if len(self.applied) == 0: | |
927 | self.ui.write("No patches applied\n") |
|
925 | self.ui.write("No patches applied\n") | |
928 | return |
|
926 | return | |
@@ -1988,4 +1986,3 b' cmdtable = {' | |||||
1988 | "qtop": (top, [], 'hg qtop'), |
|
1986 | "qtop": (top, [], 'hg qtop'), | |
1989 | "qunapplied": (unapplied, [], 'hg qunapplied [PATCH]'), |
|
1987 | "qunapplied": (unapplied, [], 'hg qunapplied [PATCH]'), | |
1990 | } |
|
1988 | } | |
1991 |
|
@@ -163,12 +163,12 b' def archive(repo, dest, node, kind, deco' | |||||
163 | change = repo.changelog.read(node) |
|
163 | change = repo.changelog.read(node) | |
164 | mn = change[0] |
|
164 | mn = change[0] | |
165 | archiver = archivers[kind](dest, prefix, mtime or change[2][0]) |
|
165 | archiver = archivers[kind](dest, prefix, mtime or change[2][0]) | |
166 |
m |
|
166 | m = repo.manifest.read(mn) | |
167 | mff = repo.manifest.readflags(mn) |
|
167 | items = m.items() | |
168 |
|
|
168 | items.sort() | |
169 | write('.hg_archival.txt', 0644, |
|
169 | write('.hg_archival.txt', 0644, | |
170 | 'repo: %s\nnode: %s\n' % (hex(repo.changelog.node(0)), hex(node))) |
|
170 | 'repo: %s\nnode: %s\n' % (hex(repo.changelog.node(0)), hex(node))) | |
171 |
for filename, filenode in |
|
171 | for filename, filenode in items: | |
172 |
write(filename, m |
|
172 | write(filename, m.execf(filename) and 0755 or 0644, | |
173 | repo.file(filename).read(filenode)) |
|
173 | repo.file(filename).read(filenode)) | |
174 | archiver.done() |
|
174 | archiver.done() |
@@ -1,7 +1,7 b'' | |||||
1 | /* |
|
1 | /* | |
2 | bdiff.c - efficient binary diff extension for Mercurial |
|
2 | bdiff.c - efficient binary diff extension for Mercurial | |
3 |
|
3 | |||
4 | Copyright 2005 Matt Mackall <mpm@selenic.com> |
|
4 | Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> | |
5 |
|
5 | |||
6 | This software may be used and distributed according to the terms of |
|
6 | This software may be used and distributed according to the terms of | |
7 | the GNU General Public License, incorporated herein by reference. |
|
7 | the GNU General Public License, incorporated herein by reference. |
@@ -1,6 +1,6 b'' | |||||
1 | # changelog.py - changelog class for mercurial |
|
1 | # changelog.py - changelog class for mercurial | |
2 | # |
|
2 | # | |
3 | # Copyright 2005 Matt Mackall <mpm@selenic.com> |
|
3 | # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> | |
4 | # |
|
4 | # | |
5 | # This software may be used and distributed according to the terms |
|
5 | # This software may be used and distributed according to the terms | |
6 | # of the GNU General Public License, incorporated herein by reference. |
|
6 | # of the GNU General Public License, incorporated herein by reference. |
@@ -1,6 +1,6 b'' | |||||
1 | # commands.py - command processing for mercurial |
|
1 | # commands.py - command processing for mercurial | |
2 | # |
|
2 | # | |
3 | # Copyright 2005 Matt Mackall <mpm@selenic.com> |
|
3 | # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> | |
4 | # |
|
4 | # | |
5 | # This software may be used and distributed according to the terms |
|
5 | # This software may be used and distributed according to the terms | |
6 | # of the GNU General Public License, incorporated herein by reference. |
|
6 | # of the GNU General Public License, incorporated herein by reference. | |
@@ -10,9 +10,9 b' from node import *' | |||||
10 | from i18n import gettext as _ |
|
10 | from i18n import gettext as _ | |
11 | demandload(globals(), "os re sys signal shutil imp urllib pdb") |
|
11 | demandload(globals(), "os re sys signal shutil imp urllib pdb") | |
12 | demandload(globals(), "fancyopts ui hg util lock revlog templater bundlerepo") |
|
12 | demandload(globals(), "fancyopts ui hg util lock revlog templater bundlerepo") | |
13 | demandload(globals(), "fnmatch mdiff difflib random signal tempfile time") |
|
13 | demandload(globals(), "fnmatch mdiff difflib patch random signal tempfile time") | |
14 | demandload(globals(), "traceback errno socket version struct atexit sets bz2") |
|
14 | demandload(globals(), "traceback errno socket version struct atexit sets bz2") | |
15 |
demandload(globals(), "archival cStringIO changegroup |
|
15 | demandload(globals(), "archival cStringIO changegroup") | |
16 | demandload(globals(), "hgweb.server sshserver") |
|
16 | demandload(globals(), "hgweb.server sshserver") | |
17 |
|
17 | |||
18 | class UnknownCommand(Exception): |
|
18 | class UnknownCommand(Exception): | |
@@ -633,7 +633,7 b' def show_version(ui):' | |||||
633 | ui.write(_("Mercurial Distributed SCM (version %s)\n") |
|
633 | ui.write(_("Mercurial Distributed SCM (version %s)\n") | |
634 | % version.get_version()) |
|
634 | % version.get_version()) | |
635 | ui.status(_( |
|
635 | ui.status(_( | |
636 | "\nCopyright (C) 2005 Matt Mackall <mpm@selenic.com>\n" |
|
636 | "\nCopyright (C) 2005, 2006 Matt Mackall <mpm@selenic.com>\n" | |
637 | "This is free software; see the source for copying conditions. " |
|
637 | "This is free software; see the source for copying conditions. " | |
638 | "There is NO\nwarranty; " |
|
638 | "There is NO\nwarranty; " | |
639 | "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" |
|
639 | "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" | |
@@ -1333,9 +1333,9 b' def debugrebuildstate(ui, repo, rev=None' | |||||
1333 | rev = repo.lookup(rev) |
|
1333 | rev = repo.lookup(rev) | |
1334 | change = repo.changelog.read(rev) |
|
1334 | change = repo.changelog.read(rev) | |
1335 | n = change[0] |
|
1335 | n = change[0] | |
1336 |
files = repo.manifest.read |
|
1336 | files = repo.manifest.read(n) | |
1337 | wlock = repo.wlock() |
|
1337 | wlock = repo.wlock() | |
1338 |
repo.dirstate.rebuild(rev, files |
|
1338 | repo.dirstate.rebuild(rev, files) | |
1339 |
|
1339 | |||
1340 | def debugcheckstate(ui, repo): |
|
1340 | def debugcheckstate(ui, repo): | |
1341 | """validate the correctness of the current dirstate""" |
|
1341 | """validate the correctness of the current dirstate""" | |
@@ -1843,84 +1843,23 b' def import_(ui, repo, patch1, *patches, ' | |||||
1843 | d = opts["base"] |
|
1843 | d = opts["base"] | |
1844 | strip = opts["strip"] |
|
1844 | strip = opts["strip"] | |
1845 |
|
1845 | |||
1846 | mailre = re.compile(r'(?:From |[\w-]+:)') |
|
|||
1847 |
|
||||
1848 | # attempt to detect the start of a patch |
|
|||
1849 | # (this heuristic is borrowed from quilt) |
|
|||
1850 | diffre = re.compile(r'^(?:Index:[ \t]|diff[ \t]|RCS file: |' + |
|
|||
1851 | 'retrieving revision [0-9]+(\.[0-9]+)*$|' + |
|
|||
1852 | '(---|\*\*\*)[ \t])', re.MULTILINE) |
|
|||
1853 |
|
||||
1854 | wlock = repo.wlock() |
|
1846 | wlock = repo.wlock() | |
1855 | lock = repo.lock() |
|
1847 | lock = repo.lock() | |
1856 |
|
1848 | |||
1857 |
for p |
|
1849 | for p in patches: | |
1858 |
pf = os.path.join(d, p |
|
1850 | pf = os.path.join(d, p) | |
1859 |
|
1851 | |||
1860 | message = None |
|
|||
1861 | user = None |
|
|||
1862 | date = None |
|
|||
1863 | hgpatch = False |
|
|||
1864 |
|
||||
1865 | p = email.Parser.Parser() |
|
|||
1866 | if pf == '-': |
|
1852 | if pf == '-': | |
1867 | msg = p.parse(sys.stdin) |
|
|||
1868 | ui.status(_("applying patch from stdin\n")) |
|
1853 | ui.status(_("applying patch from stdin\n")) | |
|
1854 | tmpname, message, user, date = patch.extract(ui, sys.stdin) | |||
1869 | else: |
|
1855 | else: | |
1870 | msg = p.parse(file(pf)) |
|
1856 | ui.status(_("applying %s\n") % p) | |
1871 | ui.status(_("applying %s\n") % patch) |
|
1857 | tmpname, message, user, date = patch.extract(ui, file(pf)) | |
1872 |
|
1858 | |||
1873 | fd, tmpname = tempfile.mkstemp(prefix='hg-patch-') |
|
1859 | if tmpname is None: | |
1874 | tmpfp = os.fdopen(fd, 'w') |
|
1860 | raise util.Abort(_('no diffs found')) | |
|
1861 | ||||
1875 | try: |
|
1862 | try: | |
1876 | message = msg['Subject'] |
|
|||
1877 | if message: |
|
|||
1878 | message = message.replace('\n\t', ' ') |
|
|||
1879 | ui.debug('Subject: %s\n' % message) |
|
|||
1880 | user = msg['From'] |
|
|||
1881 | if user: |
|
|||
1882 | ui.debug('From: %s\n' % user) |
|
|||
1883 | diffs_seen = 0 |
|
|||
1884 | ok_types = ('text/plain', 'text/x-diff', 'text/x-patch') |
|
|||
1885 | for part in msg.walk(): |
|
|||
1886 | content_type = part.get_content_type() |
|
|||
1887 | ui.debug('Content-Type: %s\n' % content_type) |
|
|||
1888 | if content_type not in ok_types: |
|
|||
1889 | continue |
|
|||
1890 | payload = part.get_payload(decode=True) |
|
|||
1891 | m = diffre.search(payload) |
|
|||
1892 | if m: |
|
|||
1893 | ui.debug(_('found patch at byte %d\n') % m.start(0)) |
|
|||
1894 | diffs_seen += 1 |
|
|||
1895 | hgpatch = False |
|
|||
1896 | fp = cStringIO.StringIO() |
|
|||
1897 | if message: |
|
|||
1898 | fp.write(message) |
|
|||
1899 | fp.write('\n') |
|
|||
1900 | for line in payload[:m.start(0)].splitlines(): |
|
|||
1901 | if line.startswith('# HG changeset patch'): |
|
|||
1902 | ui.debug(_('patch generated by hg export\n')) |
|
|||
1903 | hgpatch = True |
|
|||
1904 | # drop earlier commit message content |
|
|||
1905 | fp.seek(0) |
|
|||
1906 | fp.truncate() |
|
|||
1907 | elif hgpatch: |
|
|||
1908 | if line.startswith('# User '): |
|
|||
1909 | user = line[7:] |
|
|||
1910 | ui.debug('From: %s\n' % user) |
|
|||
1911 | elif line.startswith("# Date "): |
|
|||
1912 | date = line[7:] |
|
|||
1913 | if not line.startswith('# '): |
|
|||
1914 | fp.write(line) |
|
|||
1915 | fp.write('\n') |
|
|||
1916 | message = fp.getvalue() |
|
|||
1917 | if tmpfp: |
|
|||
1918 | tmpfp.write(payload) |
|
|||
1919 | if not payload.endswith('\n'): |
|
|||
1920 | tmpfp.write('\n') |
|
|||
1921 | elif not diffs_seen and message and content_type == 'text/plain': |
|
|||
1922 | message += '\n' + payload |
|
|||
1923 |
|
||||
1924 | if opts['message']: |
|
1863 | if opts['message']: | |
1925 | # pickup the cmdline msg |
|
1864 | # pickup the cmdline msg | |
1926 | message = opts['message'] |
|
1865 | message = opts['message'] | |
@@ -1932,17 +1871,45 b' def import_(ui, repo, patch1, *patches, ' | |||||
1932 | message = None |
|
1871 | message = None | |
1933 | ui.debug(_('message:\n%s\n') % message) |
|
1872 | ui.debug(_('message:\n%s\n') % message) | |
1934 |
|
1873 | |||
1935 | tmpfp.close() |
|
1874 | files = patch.patch(strip, tmpname, ui, cwd=repo.root) | |
1936 | if not diffs_seen: |
|
1875 | removes = [] | |
1937 | raise util.Abort(_('no diffs found')) |
|
|||
1938 |
|
||||
1939 | files = util.patch(strip, tmpname, ui, cwd=repo.root) |
|
|||
1940 | if len(files) > 0: |
|
1876 | if len(files) > 0: | |
1941 | cfiles = files |
|
1877 | cfiles = files.keys() | |
|
1878 | copies = [] | |||
|
1879 | copts = {'after': False, 'force': False} | |||
1942 | cwd = repo.getcwd() |
|
1880 | cwd = repo.getcwd() | |
1943 | if cwd: |
|
1881 | if cwd: | |
1944 | cfiles = [util.pathto(cwd, f) for f in files] |
|
1882 | cfiles = [util.pathto(cwd, f) for f in files.keys()] | |
|
1883 | for f in files: | |||
|
1884 | ctype, gp = files[f] | |||
|
1885 | if ctype == 'RENAME': | |||
|
1886 | copies.append((gp.oldpath, gp.path, gp.copymod)) | |||
|
1887 | removes.append(gp.oldpath) | |||
|
1888 | elif ctype == 'COPY': | |||
|
1889 | copies.append((gp.oldpath, gp.path, gp.copymod)) | |||
|
1890 | elif ctype == 'DELETE': | |||
|
1891 | removes.append(gp.path) | |||
|
1892 | for src, dst, after in copies: | |||
|
1893 | absdst = os.path.join(repo.root, dst) | |||
|
1894 | if not after and os.path.exists(absdst): | |||
|
1895 | raise util.Abort(_('patch creates existing file %s') % dst) | |||
|
1896 | if cwd: | |||
|
1897 | src, dst = [util.pathto(cwd, f) for f in (src, dst)] | |||
|
1898 | copts['after'] = after | |||
|
1899 | errs, copied = docopy(ui, repo, (src, dst), copts, wlock=wlock) | |||
|
1900 | if errs: | |||
|
1901 | raise util.Abort(errs) | |||
|
1902 | if removes: | |||
|
1903 | repo.remove(removes, True, wlock=wlock) | |||
|
1904 | for f in files: | |||
|
1905 | ctype, gp = files[f] | |||
|
1906 | if gp and gp.mode: | |||
|
1907 | x = gp.mode & 0100 != 0 | |||
|
1908 | dst = os.path.join(repo.root, gp.path) | |||
|
1909 | util.set_exec(dst, x) | |||
1945 | addremove_lock(ui, repo, cfiles, {}, wlock=wlock) |
|
1910 | addremove_lock(ui, repo, cfiles, {}, wlock=wlock) | |
|
1911 | files = files.keys() | |||
|
1912 | files.extend([r for r in removes if r not in files]) | |||
1946 | repo.commit(files, message, user, date, wlock=wlock, lock=lock) |
|
1913 | repo.commit(files, message, user, date, wlock=wlock, lock=lock) | |
1947 | finally: |
|
1914 | finally: | |
1948 | os.unlink(tmpname) |
|
1915 | os.unlink(tmpname) | |
@@ -2178,12 +2145,12 b' def manifest(ui, repo, rev=None):' | |||||
2178 | else: |
|
2145 | else: | |
2179 | n = repo.manifest.tip() |
|
2146 | n = repo.manifest.tip() | |
2180 | m = repo.manifest.read(n) |
|
2147 | m = repo.manifest.read(n) | |
2181 | mf = repo.manifest.readflags(n) |
|
|||
2182 | files = m.keys() |
|
2148 | files = m.keys() | |
2183 | files.sort() |
|
2149 | files.sort() | |
2184 |
|
2150 | |||
2185 | for f in files: |
|
2151 | for f in files: | |
2186 |
ui.write("%40s %3s %s\n" % (hex(m[f]), |
|
2152 | ui.write("%40s %3s %s\n" % (hex(m[f]), | |
|
2153 | m.execf(f) and "755" or "644", f)) | |||
2187 |
|
2154 | |||
2188 | def merge(ui, repo, node=None, force=None, branch=None): |
|
2155 | def merge(ui, repo, node=None, force=None, branch=None): | |
2189 | """Merge working directory with another revision |
|
2156 | """Merge working directory with another revision |
@@ -1,6 +1,6 b'' | |||||
1 | # context.py - changeset and file context objects for mercurial |
|
1 | # context.py - changeset and file context objects for mercurial | |
2 | # |
|
2 | # | |
3 |
# Copyright 200 |
|
3 | # Copyright 2006 Matt Mackall <mpm@selenic.com> | |
4 | # |
|
4 | # | |
5 | # This software may be used and distributed according to the terms |
|
5 | # This software may be used and distributed according to the terms | |
6 | # of the GNU General Public License, incorporated herein by reference. |
|
6 | # of the GNU General Public License, incorporated herein by reference. |
@@ -1,7 +1,7 b'' | |||||
1 | """ |
|
1 | """ | |
2 | dirstate.py - working directory tracking for mercurial |
|
2 | dirstate.py - working directory tracking for mercurial | |
3 |
|
3 | |||
4 | Copyright 2005 Matt Mackall <mpm@selenic.com> |
|
4 | Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> | |
5 |
|
5 | |||
6 | This software may be used and distributed according to the terms |
|
6 | This software may be used and distributed according to the terms | |
7 | of the GNU General Public License, incorporated herein by reference. |
|
7 | of the GNU General Public License, incorporated herein by reference. | |
@@ -238,8 +238,8 b' class dirstate(object):' | |||||
238 | self.clear() |
|
238 | self.clear() | |
239 | umask = os.umask(0) |
|
239 | umask = os.umask(0) | |
240 | os.umask(umask) |
|
240 | os.umask(umask) | |
241 |
for f |
|
241 | for f in files: | |
242 |
if |
|
242 | if files.execf(f): | |
243 | self.map[f] = ('n', ~umask, -1, 0) |
|
243 | self.map[f] = ('n', ~umask, -1, 0) | |
244 | else: |
|
244 | else: | |
245 | self.map[f] = ('n', ~umask & 0666, -1, 0) |
|
245 | self.map[f] = ('n', ~umask & 0666, -1, 0) |
@@ -1,6 +1,6 b'' | |||||
1 | # filelog.py - file history class for mercurial |
|
1 | # filelog.py - file history class for mercurial | |
2 | # |
|
2 | # | |
3 | # Copyright 2005 Matt Mackall <mpm@selenic.com> |
|
3 | # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> | |
4 | # |
|
4 | # | |
5 | # This software may be used and distributed according to the terms |
|
5 | # This software may be used and distributed according to the terms | |
6 | # of the GNU General Public License, incorporated herein by reference. |
|
6 | # of the GNU General Public License, incorporated herein by reference. |
@@ -1,6 +1,7 b'' | |||||
1 | # hg.py - repository classes for mercurial |
|
1 | # hg.py - repository classes for mercurial | |
2 | # |
|
2 | # | |
3 | # Copyright 2005 Matt Mackall <mpm@selenic.com> |
|
3 | # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> | |
|
4 | # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com> | |||
4 | # |
|
5 | # | |
5 | # This software may be used and distributed according to the terms |
|
6 | # This software may be used and distributed according to the terms | |
6 | # of the GNU General Public License, incorporated herein by reference. |
|
7 | # of the GNU General Public License, incorporated herein by reference. |
@@ -1,7 +1,7 b'' | |||||
1 | # hgweb/common.py - Utility functions needed by hgweb_mod and hgwebdir_mod |
|
1 | # hgweb/common.py - Utility functions needed by hgweb_mod and hgwebdir_mod | |
2 | # |
|
2 | # | |
3 | # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net> |
|
3 | # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net> | |
4 | # Copyright 2005 Matt Mackall <mpm@selenic.com> |
|
4 | # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> | |
5 | # |
|
5 | # | |
6 | # This software may be used and distributed according to the terms |
|
6 | # This software may be used and distributed according to the terms | |
7 | # of the GNU General Public License, incorporated herein by reference. |
|
7 | # of the GNU General Public License, incorporated herein by reference. |
@@ -1,7 +1,7 b'' | |||||
1 | # hgweb/hgweb_mod.py - Web interface for a repository. |
|
1 | # hgweb/hgweb_mod.py - Web interface for a repository. | |
2 | # |
|
2 | # | |
3 | # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net> |
|
3 | # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net> | |
4 | # Copyright 2005 Matt Mackall <mpm@selenic.com> |
|
4 | # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> | |
5 | # |
|
5 | # | |
6 | # This software may be used and distributed according to the terms |
|
6 | # This software may be used and distributed according to the terms | |
7 | # of the GNU General Public License, incorporated herein by reference. |
|
7 | # of the GNU General Public License, incorporated herein by reference. | |
@@ -398,7 +398,7 b' class hgweb(object):' | |||||
398 | parent=self.siblings(fl.parents(n), fl.rev, file=f), |
|
398 | parent=self.siblings(fl.parents(n), fl.rev, file=f), | |
399 | child=self.siblings(fl.children(n), fl.rev, file=f), |
|
399 | child=self.siblings(fl.children(n), fl.rev, file=f), | |
400 | rename=self.renamelink(fl, n), |
|
400 | rename=self.renamelink(fl, n), | |
401 |
permissions=self.repo.manifest.read |
|
401 | permissions=self.repo.manifest.read(mfn).execf(f)) | |
402 |
|
402 | |||
403 | def fileannotate(self, f, node): |
|
403 | def fileannotate(self, f, node): | |
404 | bcache = {} |
|
404 | bcache = {} | |
@@ -452,7 +452,7 b' class hgweb(object):' | |||||
452 | rename=self.renamelink(fl, n), |
|
452 | rename=self.renamelink(fl, n), | |
453 | parent=self.siblings(fl.parents(n), fl.rev, file=f), |
|
453 | parent=self.siblings(fl.parents(n), fl.rev, file=f), | |
454 | child=self.siblings(fl.children(n), fl.rev, file=f), |
|
454 | child=self.siblings(fl.children(n), fl.rev, file=f), | |
455 |
permissions=self.repo.manifest.read |
|
455 | permissions=self.repo.manifest.read(mfn).execf(f)) | |
456 |
|
456 | |||
457 | def manifest(self, mnode, path): |
|
457 | def manifest(self, mnode, path): | |
458 | man = self.repo.manifest |
|
458 | man = self.repo.manifest | |
@@ -462,7 +462,6 b' class hgweb(object):' | |||||
462 | rev = man.rev(mn) |
|
462 | rev = man.rev(mn) | |
463 | changerev = man.linkrev(mn) |
|
463 | changerev = man.linkrev(mn) | |
464 | node = self.repo.changelog.node(changerev) |
|
464 | node = self.repo.changelog.node(changerev) | |
465 | mff = man.readflags(mn) |
|
|||
466 |
|
465 | |||
467 | files = {} |
|
466 | files = {} | |
468 |
|
467 | |||
@@ -496,7 +495,7 b' class hgweb(object):' | |||||
496 | "filenode": hex(fnode), |
|
495 | "filenode": hex(fnode), | |
497 | "parity": self.stripes(parity), |
|
496 | "parity": self.stripes(parity), | |
498 | "basename": f, |
|
497 | "basename": f, | |
499 |
"permissions": mf |
|
498 | "permissions": mf.execf(full)} | |
500 | parity += 1 |
|
499 | parity += 1 | |
501 |
|
500 | |||
502 | def dirlist(**map): |
|
501 | def dirlist(**map): |
@@ -1,7 +1,7 b'' | |||||
1 | # hgweb/hgwebdir_mod.py - Web interface for a directory of repositories. |
|
1 | # hgweb/hgwebdir_mod.py - Web interface for a directory of repositories. | |
2 | # |
|
2 | # | |
3 | # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net> |
|
3 | # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net> | |
4 | # Copyright 2005 Matt Mackall <mpm@selenic.com> |
|
4 | # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> | |
5 | # |
|
5 | # | |
6 | # This software may be used and distributed according to the terms |
|
6 | # This software may be used and distributed according to the terms | |
7 | # of the GNU General Public License, incorporated herein by reference. |
|
7 | # of the GNU General Public License, incorporated herein by reference. |
@@ -1,7 +1,7 b'' | |||||
1 | # hgweb/request.py - An http request from either CGI or the standalone server. |
|
1 | # hgweb/request.py - An http request from either CGI or the standalone server. | |
2 | # |
|
2 | # | |
3 | # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net> |
|
3 | # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net> | |
4 | # Copyright 2005 Matt Mackall <mpm@selenic.com> |
|
4 | # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> | |
5 | # |
|
5 | # | |
6 | # This software may be used and distributed according to the terms |
|
6 | # This software may be used and distributed according to the terms | |
7 | # of the GNU General Public License, incorporated herein by reference. |
|
7 | # of the GNU General Public License, incorporated herein by reference. |
@@ -1,7 +1,7 b'' | |||||
1 | # hgweb/server.py - The standalone hg web server. |
|
1 | # hgweb/server.py - The standalone hg web server. | |
2 | # |
|
2 | # | |
3 | # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net> |
|
3 | # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net> | |
4 | # Copyright 2005 Matt Mackall <mpm@selenic.com> |
|
4 | # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> | |
5 | # |
|
5 | # | |
6 | # This software may be used and distributed according to the terms |
|
6 | # This software may be used and distributed according to the terms | |
7 | # of the GNU General Public License, incorporated herein by reference. |
|
7 | # of the GNU General Public License, incorporated herein by reference. |
@@ -1,6 +1,6 b'' | |||||
1 | # httprangereader.py - just what it says |
|
1 | # httprangereader.py - just what it says | |
2 | # |
|
2 | # | |
3 | # Copyright 2005 Matt Mackall <mpm@selenic.com> |
|
3 | # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> | |
4 | # |
|
4 | # | |
5 | # This software may be used and distributed according to the terms |
|
5 | # This software may be used and distributed according to the terms | |
6 | # of the GNU General Public License, incorporated herein by reference. |
|
6 | # of the GNU General Public License, incorporated herein by reference. |
@@ -1,6 +1,7 b'' | |||||
1 | # httprepo.py - HTTP repository proxy classes for mercurial |
|
1 | # httprepo.py - HTTP repository proxy classes for mercurial | |
2 | # |
|
2 | # | |
3 | # Copyright 2005 Matt Mackall <mpm@selenic.com> |
|
3 | # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> | |
|
4 | # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com> | |||
4 | # |
|
5 | # | |
5 | # This software may be used and distributed according to the terms |
|
6 | # This software may be used and distributed according to the terms | |
6 | # of the GNU General Public License, incorporated herein by reference. |
|
7 | # of the GNU General Public License, incorporated herein by reference. |
@@ -1,7 +1,7 b'' | |||||
1 | """ |
|
1 | """ | |
2 | i18n.py - internationalization support for mercurial |
|
2 | i18n.py - internationalization support for mercurial | |
3 |
|
3 | |||
4 | Copyright 2005 Matt Mackall <mpm@selenic.com> |
|
4 | Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> | |
5 |
|
5 | |||
6 | This software may be used and distributed according to the terms |
|
6 | This software may be used and distributed according to the terms | |
7 | of the GNU General Public License, incorporated herein by reference. |
|
7 | of the GNU General Public License, incorporated herein by reference. |
@@ -1,6 +1,6 b'' | |||||
1 | # localrepo.py - read/write repository class for mercurial |
|
1 | # localrepo.py - read/write repository class for mercurial | |
2 | # |
|
2 | # | |
3 | # Copyright 2005 Matt Mackall <mpm@selenic.com> |
|
3 | # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> | |
4 | # |
|
4 | # | |
5 | # This software may be used and distributed according to the terms |
|
5 | # This software may be used and distributed according to the terms | |
6 | # of the GNU General Public License, incorporated herein by reference. |
|
6 | # of the GNU General Public License, incorporated herein by reference. | |
@@ -470,8 +470,7 b' class localrepository(repo.repository):' | |||||
470 | p2 = p2 or self.dirstate.parents()[1] or nullid |
|
470 | p2 = p2 or self.dirstate.parents()[1] or nullid | |
471 | c1 = self.changelog.read(p1) |
|
471 | c1 = self.changelog.read(p1) | |
472 | c2 = self.changelog.read(p2) |
|
472 | c2 = self.changelog.read(p2) | |
473 | m1 = self.manifest.read(c1[0]) |
|
473 | m1 = self.manifest.read(c1[0]).copy() | |
474 | mf1 = self.manifest.readflags(c1[0]) |
|
|||
475 | m2 = self.manifest.read(c2[0]) |
|
474 | m2 = self.manifest.read(c2[0]) | |
476 | changed = [] |
|
475 | changed = [] | |
477 |
|
476 | |||
@@ -484,36 +483,32 b' class localrepository(repo.repository):' | |||||
484 | wlock = self.wlock() |
|
483 | wlock = self.wlock() | |
485 | l = self.lock() |
|
484 | l = self.lock() | |
486 | tr = self.transaction() |
|
485 | tr = self.transaction() | |
487 | mm = m1.copy() |
|
|||
488 | mfm = mf1.copy() |
|
|||
489 | linkrev = self.changelog.count() |
|
486 | linkrev = self.changelog.count() | |
490 | for f in files: |
|
487 | for f in files: | |
491 | try: |
|
488 | try: | |
492 | t = self.wread(f) |
|
489 | t = self.wread(f) | |
493 |
|
|
490 | m1.set(f, util.is_exec(self.wjoin(f), m1.execf(f))) | |
494 | r = self.file(f) |
|
491 | r = self.file(f) | |
495 | mfm[f] = tm |
|
|||
496 |
|
492 | |||
497 | (entry, fp1, fp2) = self.checkfilemerge(f, t, r, m1, m2) |
|
493 | (entry, fp1, fp2) = self.checkfilemerge(f, t, r, m1, m2) | |
498 | if entry: |
|
494 | if entry: | |
499 |
m |
|
495 | m1[f] = entry | |
500 | continue |
|
496 | continue | |
501 |
|
497 | |||
502 |
m |
|
498 | m1[f] = r.add(t, {}, tr, linkrev, fp1, fp2) | |
503 | changed.append(f) |
|
499 | changed.append(f) | |
504 | if update_dirstate: |
|
500 | if update_dirstate: | |
505 | self.dirstate.update([f], "n") |
|
501 | self.dirstate.update([f], "n") | |
506 | except IOError: |
|
502 | except IOError: | |
507 | try: |
|
503 | try: | |
508 |
del m |
|
504 | del m1[f] | |
509 | del mfm[f] |
|
|||
510 | if update_dirstate: |
|
505 | if update_dirstate: | |
511 | self.dirstate.forget([f]) |
|
506 | self.dirstate.forget([f]) | |
512 | except: |
|
507 | except: | |
513 | # deleted from p2? |
|
508 | # deleted from p2? | |
514 | pass |
|
509 | pass | |
515 |
|
510 | |||
516 |
mnode = self.manifest.add(m |
|
511 | mnode = self.manifest.add(m1, tr, linkrev, c1[0], c2[0]) | |
517 | user = user or self.ui.username() |
|
512 | user = user or self.ui.username() | |
518 | n = self.changelog.add(mnode, changed, text, tr, p1, p2, user, date) |
|
513 | n = self.changelog.add(mnode, changed, text, tr, p1, p2, user, date) | |
519 | tr.close() |
|
514 | tr.close() | |
@@ -544,8 +539,7 b' class localrepository(repo.repository):' | |||||
544 | p1, p2 = self.dirstate.parents() |
|
539 | p1, p2 = self.dirstate.parents() | |
545 | c1 = self.changelog.read(p1) |
|
540 | c1 = self.changelog.read(p1) | |
546 | c2 = self.changelog.read(p2) |
|
541 | c2 = self.changelog.read(p2) | |
547 | m1 = self.manifest.read(c1[0]) |
|
542 | m1 = self.manifest.read(c1[0]).copy() | |
548 | mf1 = self.manifest.readflags(c1[0]) |
|
|||
549 | m2 = self.manifest.read(c2[0]) |
|
543 | m2 = self.manifest.read(c2[0]) | |
550 |
|
544 | |||
551 | if not commit and not remove and not force and p2 == nullid: |
|
545 | if not commit and not remove and not force and p2 == nullid: | |
@@ -571,7 +565,7 b' class localrepository(repo.repository):' | |||||
571 | for f in commit: |
|
565 | for f in commit: | |
572 | self.ui.note(f + "\n") |
|
566 | self.ui.note(f + "\n") | |
573 | try: |
|
567 | try: | |
574 |
m |
|
568 | m1.set(f, util.is_exec(self.wjoin(f), m1.execf(f))) | |
575 | t = self.wread(f) |
|
569 | t = self.wread(f) | |
576 | except IOError: |
|
570 | except IOError: | |
577 | self.ui.warn(_("trouble committing %s!\n") % f) |
|
571 | self.ui.warn(_("trouble committing %s!\n") % f) | |
@@ -598,12 +592,11 b' class localrepository(repo.repository):' | |||||
598 | changed.append(f) |
|
592 | changed.append(f) | |
599 |
|
593 | |||
600 | # update manifest |
|
594 | # update manifest | |
601 | m1 = m1.copy() |
|
|||
602 | m1.update(new) |
|
595 | m1.update(new) | |
603 | for f in remove: |
|
596 | for f in remove: | |
604 | if f in m1: |
|
597 | if f in m1: | |
605 | del m1[f] |
|
598 | del m1[f] | |
606 |
mn = self.manifest.add(m1 |
|
599 | mn = self.manifest.add(m1, tr, linkrev, c1[0], c2[0], | |
607 | (new, remove)) |
|
600 | (new, remove)) | |
608 |
|
601 | |||
609 | # add changeset |
|
602 | # add changeset | |
@@ -816,7 +809,6 b' class localrepository(repo.repository):' | |||||
816 | def undelete(self, list, wlock=None): |
|
809 | def undelete(self, list, wlock=None): | |
817 | p = self.dirstate.parents()[0] |
|
810 | p = self.dirstate.parents()[0] | |
818 | mn = self.changelog.read(p)[0] |
|
811 | mn = self.changelog.read(p)[0] | |
819 | mf = self.manifest.readflags(mn) |
|
|||
820 | m = self.manifest.read(mn) |
|
812 | m = self.manifest.read(mn) | |
821 | if not wlock: |
|
813 | if not wlock: | |
822 | wlock = self.wlock() |
|
814 | wlock = self.wlock() | |
@@ -826,7 +818,7 b' class localrepository(repo.repository):' | |||||
826 | else: |
|
818 | else: | |
827 | t = self.file(f).read(m[f]) |
|
819 | t = self.file(f).read(m[f]) | |
828 | self.wwrite(f, t) |
|
820 | self.wwrite(f, t) | |
829 |
util.set_exec(self.wjoin(f), m |
|
821 | util.set_exec(self.wjoin(f), m.execf(f)) | |
830 | self.dirstate.update([f], "n") |
|
822 | self.dirstate.update([f], "n") | |
831 |
|
823 | |||
832 | def copy(self, source, dest, wlock=None): |
|
824 | def copy(self, source, dest, wlock=None): |
@@ -1,6 +1,6 b'' | |||||
1 | # lock.py - simple locking scheme for mercurial |
|
1 | # lock.py - simple locking scheme for mercurial | |
2 | # |
|
2 | # | |
3 | # Copyright 2005 Matt Mackall <mpm@selenic.com> |
|
3 | # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> | |
4 | # |
|
4 | # | |
5 | # This software may be used and distributed according to the terms |
|
5 | # This software may be used and distributed according to the terms | |
6 | # of the GNU General Public License, incorporated herein by reference. |
|
6 | # of the GNU General Public License, incorporated herein by reference. |
@@ -1,6 +1,6 b'' | |||||
1 | # manifest.py - manifest revision class for mercurial |
|
1 | # manifest.py - manifest revision class for mercurial | |
2 | # |
|
2 | # | |
3 | # Copyright 2005 Matt Mackall <mpm@selenic.com> |
|
3 | # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> | |
4 | # |
|
4 | # | |
5 | # This software may be used and distributed according to the terms |
|
5 | # This software may be used and distributed according to the terms | |
6 | # of the GNU General Public License, incorporated herein by reference. |
|
6 | # of the GNU General Public License, incorporated herein by reference. | |
@@ -10,6 +10,31 b' from i18n import gettext as _' | |||||
10 | from demandload import * |
|
10 | from demandload import * | |
11 | demandload(globals(), "array bisect struct") |
|
11 | demandload(globals(), "array bisect struct") | |
12 |
|
12 | |||
|
13 | class manifestdict(dict): | |||
|
14 | def __init__(self, mapping=None, flags=None): | |||
|
15 | if mapping is None: mapping = {} | |||
|
16 | if flags is None: flags = {} | |||
|
17 | dict.__init__(self, mapping) | |||
|
18 | self._flags = flags | |||
|
19 | def flags(self, f): | |||
|
20 | return self._flags.get(f, "") | |||
|
21 | def execf(self, f): | |||
|
22 | "test for executable in manifest flags" | |||
|
23 | return "x" in self.flags(f) | |||
|
24 | def linkf(self, f): | |||
|
25 | "test for symlink in manifest flags" | |||
|
26 | return "l" in self.flags(f) | |||
|
27 | def rawset(self, f, entry): | |||
|
28 | self[f] = bin(entry[:40]) | |||
|
29 | fl = entry[40:-1] | |||
|
30 | if fl: self._flags[f] = fl | |||
|
31 | def set(self, f, execf=False, linkf=False): | |||
|
32 | if linkf: self._flags[f] = "l" | |||
|
33 | elif execf: self._flags[f] = "x" | |||
|
34 | else: self._flags[f] = "" | |||
|
35 | def copy(self): | |||
|
36 | return manifestdict(dict.copy(self), dict.copy(self._flags)) | |||
|
37 | ||||
13 | class manifest(revlog): |
|
38 | class manifest(revlog): | |
14 | def __init__(self, opener, defversion=REVLOGV0): |
|
39 | def __init__(self, opener, defversion=REVLOGV0): | |
15 | self.mapcache = None |
|
40 | self.mapcache = None | |
@@ -18,26 +43,18 b' class manifest(revlog):' | |||||
18 | defversion) |
|
43 | defversion) | |
19 |
|
44 | |||
20 | def read(self, node): |
|
45 | def read(self, node): | |
21 |
if node == nullid: return |
|
46 | if node == nullid: return manifestdict() # don't upset local cache | |
22 | if self.mapcache and self.mapcache[0] == node: |
|
47 | if self.mapcache and self.mapcache[0] == node: | |
23 | return self.mapcache[1] |
|
48 | return self.mapcache[1] | |
24 | text = self.revision(node) |
|
49 | text = self.revision(node) | |
25 | map = {} |
|
|||
26 | flag = {} |
|
|||
27 | self.listcache = array.array('c', text) |
|
50 | self.listcache = array.array('c', text) | |
28 | lines = text.splitlines(1) |
|
51 | lines = text.splitlines(1) | |
|
52 | mapping = manifestdict() | |||
29 | for l in lines: |
|
53 | for l in lines: | |
30 | (f, n) = l.split('\0') |
|
54 | (f, n) = l.split('\0') | |
31 |
map |
|
55 | mapping.rawset(f, n) | |
32 | flag[f] = (n[40:-1] == "x") |
|
56 | self.mapcache = (node, mapping) | |
33 | self.mapcache = (node, map, flag) |
|
57 | return mapping | |
34 | return map |
|
|||
35 |
|
||||
36 | def readflags(self, node): |
|
|||
37 | if node == nullid: return {} # don't upset local cache |
|
|||
38 | if not self.mapcache or self.mapcache[0] != node: |
|
|||
39 | self.read(node) |
|
|||
40 | return self.mapcache[2] |
|
|||
41 |
|
58 | |||
42 | def diff(self, a, b): |
|
59 | def diff(self, a, b): | |
43 | return mdiff.textdiff(str(a), str(b)) |
|
60 | return mdiff.textdiff(str(a), str(b)) | |
@@ -86,7 +103,7 b' class manifest(revlog):' | |||||
86 | '''look up entry for a single file efficiently. |
|
103 | '''look up entry for a single file efficiently. | |
87 | return (node, flag) pair if found, (None, None) if not.''' |
|
104 | return (node, flag) pair if found, (None, None) if not.''' | |
88 | if self.mapcache and node == self.mapcache[0]: |
|
105 | if self.mapcache and node == self.mapcache[0]: | |
89 |
return self.mapcache[1].get(f), self.mapcache[ |
|
106 | return self.mapcache[1].get(f), self.mapcache[1].flags(f) | |
90 | text = self.revision(node) |
|
107 | text = self.revision(node) | |
91 | start, end = self._search(text, f) |
|
108 | start, end = self._search(text, f) | |
92 | if start == end: |
|
109 | if start == end: | |
@@ -95,7 +112,7 b' class manifest(revlog):' | |||||
95 | f, n = l.split('\0') |
|
112 | f, n = l.split('\0') | |
96 | return bin(n[:40]), n[40:-1] == 'x' |
|
113 | return bin(n[:40]), n[40:-1] == 'x' | |
97 |
|
114 | |||
98 |
def add(self, map |
|
115 | def add(self, map, transaction, link, p1=None, p2=None, | |
99 | changed=None): |
|
116 | changed=None): | |
100 | # apply the changes collected during the bisect loop to our addlist |
|
117 | # apply the changes collected during the bisect loop to our addlist | |
101 | # return a delta suitable for addrevision |
|
118 | # return a delta suitable for addrevision | |
@@ -123,9 +140,7 b' class manifest(revlog):' | |||||
123 |
|
140 | |||
124 | # if this is changed to support newlines in filenames, |
|
141 | # if this is changed to support newlines in filenames, | |
125 | # be sure to check the templates/ dir again (especially *-raw.tmpl) |
|
142 | # be sure to check the templates/ dir again (especially *-raw.tmpl) | |
126 | text = ["%s\000%s%s\n" % |
|
143 | text = ["%s\000%s%s\n" % (f, hex(map[f]), map.flags(f)) for f in files] | |
127 | (f, hex(map[f]), flags[f] and "x" or '') |
|
|||
128 | for f in files] |
|
|||
129 | self.listcache = array.array('c', "".join(text)) |
|
144 | self.listcache = array.array('c', "".join(text)) | |
130 | cachedelta = None |
|
145 | cachedelta = None | |
131 | else: |
|
146 | else: | |
@@ -151,8 +166,7 b' class manifest(revlog):' | |||||
151 | # bs will either be the index of the item or the insert point |
|
166 | # bs will either be the index of the item or the insert point | |
152 | start, end = self._search(addbuf, f, start) |
|
167 | start, end = self._search(addbuf, f, start) | |
153 | if w[1] == 0: |
|
168 | if w[1] == 0: | |
154 | l = "%s\000%s%s\n" % (f, hex(map[f]), |
|
169 | l = "%s\000%s%s\n" % (f, hex(map[f]), map.flags(f)) | |
155 | flags[f] and "x" or '') |
|
|||
156 | else: |
|
170 | else: | |
157 | l = "" |
|
171 | l = "" | |
158 | if start == end and w[1] == 1: |
|
172 | if start == end and w[1] == 1: | |
@@ -183,6 +197,6 b' class manifest(revlog):' | |||||
183 |
|
197 | |||
184 | n = self.addrevision(buffer(self.listcache), transaction, link, p1, \ |
|
198 | n = self.addrevision(buffer(self.listcache), transaction, link, p1, \ | |
185 | p2, cachedelta) |
|
199 | p2, cachedelta) | |
186 |
self.mapcache = (n, map |
|
200 | self.mapcache = (n, map) | |
187 |
|
201 | |||
188 | return n |
|
202 | return n |
@@ -1,6 +1,6 b'' | |||||
1 | # mdiff.py - diff and patch routines for mercurial |
|
1 | # mdiff.py - diff and patch routines for mercurial | |
2 | # |
|
2 | # | |
3 | # Copyright 2005 Matt Mackall <mpm@selenic.com> |
|
3 | # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> | |
4 | # |
|
4 | # | |
5 | # This software may be used and distributed according to the terms |
|
5 | # This software may be used and distributed according to the terms | |
6 | # of the GNU General Public License, incorporated herein by reference. |
|
6 | # of the GNU General Public License, incorporated herein by reference. |
@@ -84,11 +84,8 b' def update(repo, node, branchmerge=False' | |||||
84 | m2n = repo.changelog.read(p2)[0] |
|
84 | m2n = repo.changelog.read(p2)[0] | |
85 | man = repo.manifest.ancestor(m1n, m2n) |
|
85 | man = repo.manifest.ancestor(m1n, m2n) | |
86 | m1 = repo.manifest.read(m1n) |
|
86 | m1 = repo.manifest.read(m1n) | |
87 | mf1 = repo.manifest.readflags(m1n) |
|
|||
88 | m2 = repo.manifest.read(m2n).copy() |
|
87 | m2 = repo.manifest.read(m2n).copy() | |
89 | mf2 = repo.manifest.readflags(m2n) |
|
|||
90 | ma = repo.manifest.read(man) |
|
88 | ma = repo.manifest.read(man) | |
91 | mfa = repo.manifest.readflags(man) |
|
|||
92 |
|
89 | |||
93 | if not forcemerge and not overwrite: |
|
90 | if not forcemerge and not overwrite: | |
94 | for f in unknown: |
|
91 | for f in unknown: | |
@@ -113,12 +110,11 b' def update(repo, node, branchmerge=False' | |||||
113 |
|
110 | |||
114 | # construct a working dir manifest |
|
111 | # construct a working dir manifest | |
115 | mw = m1.copy() |
|
112 | mw = m1.copy() | |
116 | mfw = mf1.copy() |
|
|||
117 | umap = dict.fromkeys(unknown) |
|
113 | umap = dict.fromkeys(unknown) | |
118 |
|
114 | |||
119 | for f in added + modified + unknown: |
|
115 | for f in added + modified + unknown: | |
120 | mw[f] = "" |
|
116 | mw[f] = "" | |
121 |
m |
|
117 | mw.set(f, util.is_exec(repo.wjoin(f), mw.execf(f))) | |
122 |
|
118 | |||
123 | for f in deleted + removed: |
|
119 | for f in deleted + removed: | |
124 | if f in mw: |
|
120 | if f in mw: | |
@@ -155,28 +151,28 b' def update(repo, node, branchmerge=False' | |||||
155 | repo.ui.debug(_(" %s versions differ, resolve\n") % f) |
|
151 | repo.ui.debug(_(" %s versions differ, resolve\n") % f) | |
156 | # merge executable bits |
|
152 | # merge executable bits | |
157 | # "if we changed or they changed, change in merge" |
|
153 | # "if we changed or they changed, change in merge" | |
158 |
a, b, c = m |
|
154 | a, b, c = ma.execf(f), mw.execf(f), m2.execf(f) | |
159 | mode = ((a^b) | (a^c)) ^ a |
|
155 | mode = ((a^b) | (a^c)) ^ a | |
160 |
merge[f] = (m1.get(f, nullid), m2[f] |
|
156 | merge[f] = (mode, m1.get(f, nullid), m2[f]) | |
161 | s = 1 |
|
157 | s = 1 | |
162 | # are we clobbering? |
|
158 | # are we clobbering? | |
163 | # is remote's version newer? |
|
159 | # is remote's version newer? | |
164 | # or are we going back in time? |
|
160 | # or are we going back in time? | |
165 | elif overwrite or m2[f] != a or (p2 == pa and mw[f] == m1[f]): |
|
161 | elif overwrite or m2[f] != a or (p2 == pa and mw[f] == m1[f]): | |
166 | repo.ui.debug(_(" remote %s is newer, get\n") % f) |
|
162 | repo.ui.debug(_(" remote %s is newer, get\n") % f) | |
167 | get[f] = m2[f] |
|
163 | get[f] = (m2.execf(f), m2[f]) | |
168 | s = 1 |
|
164 | s = 1 | |
169 | elif f in umap or f in added: |
|
165 | elif f in umap or f in added: | |
170 | # this unknown file is the same as the checkout |
|
166 | # this unknown file is the same as the checkout | |
171 | # we need to reset the dirstate if the file was added |
|
167 | # we need to reset the dirstate if the file was added | |
172 | get[f] = m2[f] |
|
168 | get[f] = (m2.execf(f), m2[f]) | |
173 |
|
169 | |||
174 |
if not s and m |
|
170 | if not s and mw.execf(f) != m2.execf(f): | |
175 | if overwrite: |
|
171 | if overwrite: | |
176 | repo.ui.debug(_(" updating permissions for %s\n") % f) |
|
172 | repo.ui.debug(_(" updating permissions for %s\n") % f) | |
177 |
util.set_exec(repo.wjoin(f), m |
|
173 | util.set_exec(repo.wjoin(f), m2.execf(f)) | |
178 | else: |
|
174 | else: | |
179 |
a, b, c = m |
|
175 | a, b, c = ma.execf(f), mw.execf(f), m2.execf(f) | |
180 | mode = ((a^b) | (a^c)) ^ a |
|
176 | mode = ((a^b) | (a^c)) ^ a | |
181 | if mode != b: |
|
177 | if mode != b: | |
182 | repo.ui.debug(_(" updating permissions for %s\n") |
|
178 | repo.ui.debug(_(" updating permissions for %s\n") | |
@@ -221,14 +217,14 b' def update(repo, node, branchmerge=False' | |||||
221 | (_("remote changed %s which local deleted\n") % f) + |
|
217 | (_("remote changed %s which local deleted\n") % f) + | |
222 | _("(k)eep or (d)elete?"), _("[kd]"), _("k")) |
|
218 | _("(k)eep or (d)elete?"), _("[kd]"), _("k")) | |
223 | if r == _("k"): |
|
219 | if r == _("k"): | |
224 | get[f] = n |
|
220 | get[f] = (m2.execf(f), n) | |
225 | elif f not in ma: |
|
221 | elif f not in ma: | |
226 | repo.ui.debug(_("remote created %s\n") % f) |
|
222 | repo.ui.debug(_("remote created %s\n") % f) | |
227 | get[f] = n |
|
223 | get[f] = (m2.execf(f), n) | |
228 | else: |
|
224 | else: | |
229 | if overwrite or p2 == pa: # going backwards? |
|
225 | if overwrite or p2 == pa: # going backwards? | |
230 | repo.ui.debug(_("local deleted %s, recreating\n") % f) |
|
226 | repo.ui.debug(_("local deleted %s, recreating\n") % f) | |
231 | get[f] = n |
|
227 | get[f] = (m2.execf(f), n) | |
232 | else: |
|
228 | else: | |
233 | repo.ui.debug(_("local deleted %s\n") % f) |
|
229 | repo.ui.debug(_("local deleted %s\n") % f) | |
234 |
|
230 | |||
@@ -236,7 +232,7 b' def update(repo, node, branchmerge=False' | |||||
236 |
|
232 | |||
237 | if overwrite: |
|
233 | if overwrite: | |
238 | for f in merge: |
|
234 | for f in merge: | |
239 |
get[f] = merge[f][ |
|
235 | get[f] = merge[f][:2] | |
240 | merge = {} |
|
236 | merge = {} | |
241 |
|
237 | |||
242 | if linear_path or overwrite: |
|
238 | if linear_path or overwrite: | |
@@ -254,12 +250,13 b' def update(repo, node, branchmerge=False' | |||||
254 | files = get.keys() |
|
250 | files = get.keys() | |
255 | files.sort() |
|
251 | files.sort() | |
256 | for f in files: |
|
252 | for f in files: | |
|
253 | flag, node = get[f] | |||
257 | if f[0] == "/": |
|
254 | if f[0] == "/": | |
258 | continue |
|
255 | continue | |
259 | repo.ui.note(_("getting %s\n") % f) |
|
256 | repo.ui.note(_("getting %s\n") % f) | |
260 |
t = repo.file(f).read( |
|
257 | t = repo.file(f).read(node) | |
261 | repo.wwrite(f, t) |
|
258 | repo.wwrite(f, t) | |
262 |
util.set_exec(repo.wjoin(f), |
|
259 | util.set_exec(repo.wjoin(f), flag) | |
263 | if not partial: |
|
260 | if not partial: | |
264 | if branchmerge: |
|
261 | if branchmerge: | |
265 | repo.dirstate.update([f], 'n', st_mtime=-1) |
|
262 | repo.dirstate.update([f], 'n', st_mtime=-1) | |
@@ -272,7 +269,7 b' def update(repo, node, branchmerge=False' | |||||
272 | files.sort() |
|
269 | files.sort() | |
273 | for f in files: |
|
270 | for f in files: | |
274 | repo.ui.status(_("merging %s\n") % f) |
|
271 | repo.ui.status(_("merging %s\n") % f) | |
275 |
my, other |
|
272 | flag, my, other = merge[f] | |
276 | ret = merge3(repo, f, my, other, xp1, xp2) |
|
273 | ret = merge3(repo, f, my, other, xp1, xp2) | |
277 | if ret: |
|
274 | if ret: | |
278 | unresolved.append(f) |
|
275 | unresolved.append(f) |
@@ -14,7 +14,7 b'' | |||||
14 | allocation of intermediate Python objects. Working memory is about 2x |
|
14 | allocation of intermediate Python objects. Working memory is about 2x | |
15 | the total number of hunks. |
|
15 | the total number of hunks. | |
16 |
|
16 | |||
17 | Copyright 2005 Matt Mackall <mpm@selenic.com> |
|
17 | Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> | |
18 |
|
18 | |||
19 | This software may be used and distributed according to the terms |
|
19 | This software may be used and distributed according to the terms | |
20 | of the GNU General Public License, incorporated herein by reference. |
|
20 | of the GNU General Public License, incorporated herein by reference. |
@@ -1,7 +1,7 b'' | |||||
1 | """ |
|
1 | """ | |
2 | node.py - basic nodeid manipulation for mercurial |
|
2 | node.py - basic nodeid manipulation for mercurial | |
3 |
|
3 | |||
4 | Copyright 2005 Matt Mackall <mpm@selenic.com> |
|
4 | Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> | |
5 |
|
5 | |||
6 | This software may be used and distributed according to the terms |
|
6 | This software may be used and distributed according to the terms | |
7 | of the GNU General Public License, incorporated herein by reference. |
|
7 | of the GNU General Public License, incorporated herein by reference. |
@@ -2,7 +2,7 b'' | |||||
2 | # Used for the py2exe distutil. |
|
2 | # Used for the py2exe distutil. | |
3 | # This module must be the first mercurial module imported in setup.py |
|
3 | # This module must be the first mercurial module imported in setup.py | |
4 | # |
|
4 | # | |
5 | # Copyright 2005 Volker Kleinfeld <Volker.Kleinfeld@gmx.de> |
|
5 | # Copyright 2005, 2006 Volker Kleinfeld <Volker.Kleinfeld@gmx.de> | |
6 | # |
|
6 | # | |
7 | # This software may be used and distributed according to the terms |
|
7 | # This software may be used and distributed according to the terms | |
8 | # of the GNU General Public License, incorporated herein by reference. |
|
8 | # of the GNU General Public License, incorporated herein by reference. |
@@ -1,6 +1,6 b'' | |||||
1 |
# remoterepo - remote repositor |
|
1 | # remoterepo - remote repository proxy classes for mercurial | |
2 | # |
|
2 | # | |
3 | # Copyright 2005 Matt Mackall <mpm@selenic.com> |
|
3 | # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> | |
4 | # |
|
4 | # | |
5 | # This software may be used and distributed according to the terms |
|
5 | # This software may be used and distributed according to the terms | |
6 | # of the GNU General Public License, incorporated herein by reference. |
|
6 | # of the GNU General Public License, incorporated herein by reference. |
@@ -1,6 +1,7 b'' | |||||
1 | # repo.py - repository base classes for mercurial |
|
1 | # repo.py - repository base classes for mercurial | |
2 | # |
|
2 | # | |
3 | # Copyright 2005 Matt Mackall <mpm@selenic.com> |
|
3 | # Copyright 2005 Matt Mackall <mpm@selenic.com> | |
|
4 | # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com> | |||
4 | # |
|
5 | # | |
5 | # This software may be used and distributed according to the terms |
|
6 | # This software may be used and distributed according to the terms | |
6 | # of the GNU General Public License, incorporated herein by reference. |
|
7 | # of the GNU General Public License, incorporated herein by reference. |
@@ -4,7 +4,7 b' revlog.py - storage back-end for mercuri' | |||||
4 | This provides efficient delta storage with O(1) retrieve and append |
|
4 | This provides efficient delta storage with O(1) retrieve and append | |
5 | and O(changes) merge between branches |
|
5 | and O(changes) merge between branches | |
6 |
|
6 | |||
7 | Copyright 2005 Matt Mackall <mpm@selenic.com> |
|
7 | Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> | |
8 |
|
8 | |||
9 | This software may be used and distributed according to the terms |
|
9 | This software may be used and distributed according to the terms | |
10 | of the GNU General Public License, incorporated herein by reference. |
|
10 | of the GNU General Public License, incorporated herein by reference. |
@@ -1,6 +1,6 b'' | |||||
1 | # sshrepo.py - ssh repository proxy class for mercurial |
|
1 | # sshrepo.py - ssh repository proxy class for mercurial | |
2 | # |
|
2 | # | |
3 | # Copyright 2005 Matt Mackall <mpm@selenic.com> |
|
3 | # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> | |
4 | # |
|
4 | # | |
5 | # This software may be used and distributed according to the terms |
|
5 | # This software may be used and distributed according to the terms | |
6 | # of the GNU General Public License, incorporated herein by reference. |
|
6 | # of the GNU General Public License, incorporated herein by reference. |
@@ -1,6 +1,7 b'' | |||||
1 | # sshserver.py - ssh protocol server support for mercurial |
|
1 | # sshserver.py - ssh protocol server support for mercurial | |
2 | # |
|
2 | # | |
3 | # Copyright 2005 Matt Mackall <mpm@selenic.com> |
|
3 | # Copyright 2005 Matt Mackall <mpm@selenic.com> | |
|
4 | # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com> | |||
4 | # |
|
5 | # | |
5 | # This software may be used and distributed according to the terms |
|
6 | # This software may be used and distributed according to the terms | |
6 | # of the GNU General Public License, incorporated herein by reference. |
|
7 | # of the GNU General Public License, incorporated herein by reference. |
@@ -2,7 +2,7 b'' | |||||
2 | # |
|
2 | # | |
3 | # This provides read-only repo access to repositories exported via static http |
|
3 | # This provides read-only repo access to repositories exported via static http | |
4 | # |
|
4 | # | |
5 | # Copyright 2005 Matt Mackall <mpm@selenic.com> |
|
5 | # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> | |
6 | # |
|
6 | # | |
7 | # This software may be used and distributed according to the terms |
|
7 | # This software may be used and distributed according to the terms | |
8 | # of the GNU General Public License, incorporated herein by reference. |
|
8 | # of the GNU General Public License, incorporated herein by reference. |
@@ -6,7 +6,7 b'' | |||||
6 | # effectively log-structured, this should amount to simply truncating |
|
6 | # effectively log-structured, this should amount to simply truncating | |
7 | # anything that isn't referenced in the changelog. |
|
7 | # anything that isn't referenced in the changelog. | |
8 | # |
|
8 | # | |
9 | # Copyright 2005 Matt Mackall <mpm@selenic.com> |
|
9 | # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> | |
10 | # |
|
10 | # | |
11 | # This software may be used and distributed according to the terms |
|
11 | # This software may be used and distributed according to the terms | |
12 | # of the GNU General Public License, incorporated herein by reference. |
|
12 | # of the GNU General Public License, incorporated herein by reference. |
@@ -1,6 +1,6 b'' | |||||
1 | # ui.py - user interface bits for mercurial |
|
1 | # ui.py - user interface bits for mercurial | |
2 | # |
|
2 | # | |
3 | # Copyright 2005 Matt Mackall <mpm@selenic.com> |
|
3 | # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> | |
4 | # |
|
4 | # | |
5 | # This software may be used and distributed according to the terms |
|
5 | # This software may be used and distributed according to the terms | |
6 | # of the GNU General Public License, incorporated herein by reference. |
|
6 | # of the GNU General Public License, incorporated herein by reference. |
@@ -2,6 +2,8 b'' | |||||
2 | util.py - Mercurial utility functions and platform specfic implementations |
|
2 | util.py - Mercurial utility functions and platform specfic implementations | |
3 |
|
3 | |||
4 | Copyright 2005 K. Thananchayan <thananck@yahoo.com> |
|
4 | Copyright 2005 K. Thananchayan <thananck@yahoo.com> | |
|
5 | Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> | |||
|
6 | Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com> | |||
5 |
|
7 | |||
6 | This software may be used and distributed according to the terms |
|
8 | This software may be used and distributed according to the terms | |
7 | of the GNU General Public License, incorporated herein by reference. |
|
9 | of the GNU General Public License, incorporated herein by reference. | |
@@ -93,27 +95,6 b' def find_in_path(name, path, default=Non' | |||||
93 | return p_name |
|
95 | return p_name | |
94 | return default |
|
96 | return default | |
95 |
|
97 | |||
96 | def patch(strip, patchname, ui, cwd=None): |
|
|||
97 | """apply the patch <patchname> to the working directory. |
|
|||
98 | a list of patched files is returned""" |
|
|||
99 | patcher = find_in_path('gpatch', os.environ.get('PATH', ''), 'patch') |
|
|||
100 | args = [] |
|
|||
101 | if cwd: |
|
|||
102 | args.append('-d %s' % shellquote(cwd)) |
|
|||
103 | fp = os.popen('%s %s -p%d < %s' % (patcher, ' '.join(args), strip, |
|
|||
104 | shellquote(patchname))) |
|
|||
105 | files = {} |
|
|||
106 | for line in fp: |
|
|||
107 | line = line.rstrip() |
|
|||
108 | ui.status("%s\n" % line) |
|
|||
109 | if line.startswith('patching file '): |
|
|||
110 | pf = parse_patch_output(line) |
|
|||
111 | files.setdefault(pf, 1) |
|
|||
112 | code = fp.close() |
|
|||
113 | if code: |
|
|||
114 | raise Abort(_("patch command failed: %s") % explain_exit(code)[0]) |
|
|||
115 | return files.keys() |
|
|||
116 |
|
||||
117 | def binary(s): |
|
98 | def binary(s): | |
118 | """return true if a string is binary data using diff's heuristic""" |
|
99 | """return true if a string is binary data using diff's heuristic""" | |
119 | if s and '\0' in s[:4096]: |
|
100 | if s and '\0' in s[:4096]: |
General Comments 0
You need to be logged in to leave comments.
Login now