Show More
@@ -0,0 +1,145 b'' | |||||
|
1 | # cmdutil.py - help for command processing in mercurial | |||
|
2 | # | |||
|
3 | # Copyright 2005, 2006 Matt Mackall <mpm@selenic.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 node import * | |||
|
10 | from i18n import gettext as _ | |||
|
11 | demandload(globals(), 'mdiff util') | |||
|
12 | demandload(globals(), 'os sys') | |||
|
13 | ||||
|
14 | def make_filename(repo, pat, node, | |||
|
15 | total=None, seqno=None, revwidth=None, pathname=None): | |||
|
16 | node_expander = { | |||
|
17 | 'H': lambda: hex(node), | |||
|
18 | 'R': lambda: str(repo.changelog.rev(node)), | |||
|
19 | 'h': lambda: short(node), | |||
|
20 | } | |||
|
21 | expander = { | |||
|
22 | '%': lambda: '%', | |||
|
23 | 'b': lambda: os.path.basename(repo.root), | |||
|
24 | } | |||
|
25 | ||||
|
26 | try: | |||
|
27 | if node: | |||
|
28 | expander.update(node_expander) | |||
|
29 | if node and revwidth is not None: | |||
|
30 | expander['r'] = (lambda: | |||
|
31 | str(repo.changelog.rev(node)).zfill(revwidth)) | |||
|
32 | if total is not None: | |||
|
33 | expander['N'] = lambda: str(total) | |||
|
34 | if seqno is not None: | |||
|
35 | expander['n'] = lambda: str(seqno) | |||
|
36 | if total is not None and seqno is not None: | |||
|
37 | expander['n'] = lambda:str(seqno).zfill(len(str(total))) | |||
|
38 | if pathname is not None: | |||
|
39 | expander['s'] = lambda: os.path.basename(pathname) | |||
|
40 | expander['d'] = lambda: os.path.dirname(pathname) or '.' | |||
|
41 | expander['p'] = lambda: pathname | |||
|
42 | ||||
|
43 | newname = [] | |||
|
44 | patlen = len(pat) | |||
|
45 | i = 0 | |||
|
46 | while i < patlen: | |||
|
47 | c = pat[i] | |||
|
48 | if c == '%': | |||
|
49 | i += 1 | |||
|
50 | c = pat[i] | |||
|
51 | c = expander[c]() | |||
|
52 | newname.append(c) | |||
|
53 | i += 1 | |||
|
54 | return ''.join(newname) | |||
|
55 | except KeyError, inst: | |||
|
56 | raise util.Abort(_("invalid format spec '%%%s' in output file name"), | |||
|
57 | inst.args[0]) | |||
|
58 | ||||
|
59 | def make_file(repo, pat, node=None, | |||
|
60 | total=None, seqno=None, revwidth=None, mode='wb', pathname=None): | |||
|
61 | if not pat or pat == '-': | |||
|
62 | return 'w' in mode and sys.stdout or sys.stdin | |||
|
63 | if hasattr(pat, 'write') and 'w' in mode: | |||
|
64 | return pat | |||
|
65 | if hasattr(pat, 'read') and 'r' in mode: | |||
|
66 | return pat | |||
|
67 | return open(make_filename(repo, pat, node, total, seqno, revwidth, | |||
|
68 | pathname), | |||
|
69 | mode) | |||
|
70 | ||||
|
71 | def matchpats(repo, pats=[], opts={}, head=''): | |||
|
72 | cwd = repo.getcwd() | |||
|
73 | if not pats and cwd: | |||
|
74 | opts['include'] = [os.path.join(cwd, i) | |||
|
75 | for i in opts.get('include', [])] | |||
|
76 | opts['exclude'] = [os.path.join(cwd, x) | |||
|
77 | for x in opts.get('exclude', [])] | |||
|
78 | cwd = '' | |||
|
79 | return util.cmdmatcher(repo.root, cwd, pats or ['.'], opts.get('include'), | |||
|
80 | opts.get('exclude'), head) | |||
|
81 | ||||
|
82 | def makewalk(repo, pats=[], opts={}, node=None, head='', badmatch=None): | |||
|
83 | files, matchfn, anypats = matchpats(repo, pats, opts, head) | |||
|
84 | exact = dict(zip(files, files)) | |||
|
85 | def walk(): | |||
|
86 | for src, fn in repo.walk(node=node, files=files, match=matchfn, | |||
|
87 | badmatch=badmatch): | |||
|
88 | yield src, fn, util.pathto(repo.getcwd(), fn), fn in exact | |||
|
89 | return files, matchfn, walk() | |||
|
90 | ||||
|
91 | def walk(repo, pats=[], opts={}, node=None, head='', badmatch=None): | |||
|
92 | files, matchfn, results = makewalk(repo, pats, opts, node, head, badmatch) | |||
|
93 | for r in results: | |||
|
94 | yield r | |||
|
95 | ||||
|
96 | def findrenames(repo, added=None, removed=None, threshold=0.5): | |||
|
97 | if added is None or removed is None: | |||
|
98 | added, removed = repo.status()[1:3] | |||
|
99 | changes = repo.changelog.read(repo.dirstate.parents()[0]) | |||
|
100 | mf = repo.manifest.read(changes[0]) | |||
|
101 | for a in added: | |||
|
102 | aa = repo.wread(a) | |||
|
103 | bestscore, bestname = None, None | |||
|
104 | for r in removed: | |||
|
105 | rr = repo.file(r).read(mf[r]) | |||
|
106 | delta = mdiff.textdiff(aa, rr) | |||
|
107 | if len(delta) < len(aa): | |||
|
108 | myscore = 1.0 - (float(len(delta)) / len(aa)) | |||
|
109 | if bestscore is None or myscore > bestscore: | |||
|
110 | bestscore, bestname = myscore, r | |||
|
111 | if bestname and bestscore >= threshold: | |||
|
112 | yield bestname, a, bestscore | |||
|
113 | ||||
|
114 | def addremove(repo, pats=[], opts={}, wlock=None, dry_run=None, | |||
|
115 | similarity=None): | |||
|
116 | if dry_run is None: | |||
|
117 | dry_run = opts.get('dry_run') | |||
|
118 | if similarity is None: | |||
|
119 | similarity = float(opts.get('similarity') or 0) | |||
|
120 | add, remove = [], [] | |||
|
121 | mapping = {} | |||
|
122 | for src, abs, rel, exact in walk(repo, pats, opts): | |||
|
123 | if src == 'f' and repo.dirstate.state(abs) == '?': | |||
|
124 | add.append(abs) | |||
|
125 | mapping[abs] = rel, exact | |||
|
126 | if repo.ui.verbose or not exact: | |||
|
127 | repo.ui.status(_('adding %s\n') % ((pats and rel) or abs)) | |||
|
128 | if repo.dirstate.state(abs) != 'r' and not os.path.exists(rel): | |||
|
129 | remove.append(abs) | |||
|
130 | mapping[abs] = rel, exact | |||
|
131 | if repo.ui.verbose or not exact: | |||
|
132 | repo.ui.status(_('removing %s\n') % ((pats and rel) or abs)) | |||
|
133 | if not dry_run: | |||
|
134 | repo.add(add, wlock=wlock) | |||
|
135 | repo.remove(remove, wlock=wlock) | |||
|
136 | if similarity > 0: | |||
|
137 | for old, new, score in findrenames(repo, add, remove, similarity): | |||
|
138 | oldrel, oldexact = mapping[old] | |||
|
139 | newrel, newexact = mapping[new] | |||
|
140 | if repo.ui.verbose or not oldexact or not newexact: | |||
|
141 | repo.ui.status(_('recording removal of %s as rename to %s ' | |||
|
142 | '(%d%% similar)\n') % | |||
|
143 | (oldrel, newrel, score * 100)) | |||
|
144 | if not dry_run: | |||
|
145 | repo.copy(old, new, wlock=wlock) |
@@ -0,0 +1,68 b'' | |||||
|
1 | # mail.py - mail sending bits for mercurial | |||
|
2 | # | |||
|
3 | # Copyright 2006 Matt Mackall <mpm@selenic.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 i18n import gettext as _ | |||
|
9 | from demandload import * | |||
|
10 | demandload(globals(), "os re smtplib templater util") | |||
|
11 | ||||
|
12 | def _smtp(ui): | |||
|
13 | '''send mail using smtp.''' | |||
|
14 | ||||
|
15 | local_hostname = ui.config('smtp', 'local_hostname') | |||
|
16 | s = smtplib.SMTP(local_hostname=local_hostname) | |||
|
17 | mailhost = ui.config('smtp', 'host') | |||
|
18 | if not mailhost: | |||
|
19 | raise util.Abort(_('no [smtp]host in hgrc - cannot send mail')) | |||
|
20 | mailport = int(ui.config('smtp', 'port', 25)) | |||
|
21 | ui.note(_('sending mail: smtp host %s, port %s\n') % | |||
|
22 | (mailhost, mailport)) | |||
|
23 | s.connect(host=mailhost, port=mailport) | |||
|
24 | if ui.configbool('smtp', 'tls'): | |||
|
25 | ui.note(_('(using tls)\n')) | |||
|
26 | s.ehlo() | |||
|
27 | s.starttls() | |||
|
28 | s.ehlo() | |||
|
29 | username = ui.config('smtp', 'username') | |||
|
30 | password = ui.config('smtp', 'password') | |||
|
31 | if username and password: | |||
|
32 | ui.note(_('(authenticating to mail server as %s)\n') % | |||
|
33 | (username)) | |||
|
34 | s.login(username, password) | |||
|
35 | return s | |||
|
36 | ||||
|
37 | class _sendmail(object): | |||
|
38 | '''send mail using sendmail.''' | |||
|
39 | ||||
|
40 | def __init__(self, ui, program): | |||
|
41 | self.ui = ui | |||
|
42 | self.program = program | |||
|
43 | ||||
|
44 | def sendmail(self, sender, recipients, msg): | |||
|
45 | cmdline = '%s -f %s %s' % ( | |||
|
46 | self.program, templater.email(sender), | |||
|
47 | ' '.join(map(templater.email, recipients))) | |||
|
48 | self.ui.note(_('sending mail: %s\n') % cmdline) | |||
|
49 | fp = os.popen(cmdline, 'w') | |||
|
50 | fp.write(msg) | |||
|
51 | ret = fp.close() | |||
|
52 | if ret: | |||
|
53 | raise util.Abort('%s %s' % ( | |||
|
54 | os.path.basename(self.program.split(None, 1)[0]), | |||
|
55 | util.explain_exit(ret)[0])) | |||
|
56 | ||||
|
57 | def connect(ui): | |||
|
58 | '''make a mail connection. object returned has one method, sendmail. | |||
|
59 | call as sendmail(sender, list-of-recipients, msg).''' | |||
|
60 | ||||
|
61 | method = ui.config('email', 'method', 'smtp') | |||
|
62 | if method == 'smtp': | |||
|
63 | return _smtp(ui) | |||
|
64 | ||||
|
65 | return _sendmail(ui, method) | |||
|
66 | ||||
|
67 | def sendmail(ui, sender, recipients, msg): | |||
|
68 | return connect(ui).sendmail(sender, recipients, msg) |
This diff has been collapsed as it changes many lines, (539 lines changed) Show them Hide them | |||||
@@ -0,0 +1,539 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 | from node import * | |||
|
11 | demandload(globals(), "cmdutil mdiff util") | |||
|
12 | demandload(globals(), "cStringIO email.Parser errno os re shutil sys tempfile") | |||
|
13 | ||||
|
14 | # helper functions | |||
|
15 | ||||
|
16 | def copyfile(src, dst, basedir=None): | |||
|
17 | if not basedir: | |||
|
18 | basedir = os.getcwd() | |||
|
19 | ||||
|
20 | abssrc, absdst = [os.path.join(basedir, n) for n in (src, dst)] | |||
|
21 | if os.path.exists(absdst): | |||
|
22 | raise util.Abort(_("cannot create %s: destination already exists") % | |||
|
23 | dst) | |||
|
24 | ||||
|
25 | targetdir = os.path.dirname(absdst) | |||
|
26 | if not os.path.isdir(targetdir): | |||
|
27 | os.makedirs(targetdir) | |||
|
28 | try: | |||
|
29 | shutil.copyfile(abssrc, absdst) | |||
|
30 | shutil.copymode(abssrc, absdst) | |||
|
31 | except shutil.Error, inst: | |||
|
32 | raise util.Abort(str(inst)) | |||
|
33 | ||||
|
34 | # public functions | |||
|
35 | ||||
|
36 | def extract(ui, fileobj): | |||
|
37 | '''extract patch from data read from fileobj. | |||
|
38 | ||||
|
39 | patch can be normal patch or contained in email message. | |||
|
40 | ||||
|
41 | return tuple (filename, message, user, date). any item in returned | |||
|
42 | tuple can be None. if filename is None, fileobj did not contain | |||
|
43 | patch. caller must unlink filename when done.''' | |||
|
44 | ||||
|
45 | # attempt to detect the start of a patch | |||
|
46 | # (this heuristic is borrowed from quilt) | |||
|
47 | diffre = re.compile(r'^(?:Index:[ \t]|diff[ \t]|RCS file: |' + | |||
|
48 | 'retrieving revision [0-9]+(\.[0-9]+)*$|' + | |||
|
49 | '(---|\*\*\*)[ \t])', re.MULTILINE) | |||
|
50 | ||||
|
51 | fd, tmpname = tempfile.mkstemp(prefix='hg-patch-') | |||
|
52 | tmpfp = os.fdopen(fd, 'w') | |||
|
53 | try: | |||
|
54 | hgpatch = False | |||
|
55 | ||||
|
56 | msg = email.Parser.Parser().parse(fileobj) | |||
|
57 | ||||
|
58 | message = msg['Subject'] | |||
|
59 | user = msg['From'] | |||
|
60 | # should try to parse msg['Date'] | |||
|
61 | date = None | |||
|
62 | ||||
|
63 | if message: | |||
|
64 | message = message.replace('\n\t', ' ') | |||
|
65 | ui.debug('Subject: %s\n' % message) | |||
|
66 | if user: | |||
|
67 | ui.debug('From: %s\n' % user) | |||
|
68 | diffs_seen = 0 | |||
|
69 | ok_types = ('text/plain', 'text/x-diff', 'text/x-patch') | |||
|
70 | ||||
|
71 | for part in msg.walk(): | |||
|
72 | content_type = part.get_content_type() | |||
|
73 | ui.debug('Content-Type: %s\n' % content_type) | |||
|
74 | if content_type not in ok_types: | |||
|
75 | continue | |||
|
76 | payload = part.get_payload(decode=True) | |||
|
77 | m = diffre.search(payload) | |||
|
78 | if m: | |||
|
79 | ui.debug(_('found patch at byte %d\n') % m.start(0)) | |||
|
80 | diffs_seen += 1 | |||
|
81 | cfp = cStringIO.StringIO() | |||
|
82 | if message: | |||
|
83 | cfp.write(message) | |||
|
84 | cfp.write('\n') | |||
|
85 | for line in payload[:m.start(0)].splitlines(): | |||
|
86 | if line.startswith('# HG changeset patch'): | |||
|
87 | ui.debug(_('patch generated by hg export\n')) | |||
|
88 | hgpatch = True | |||
|
89 | # drop earlier commit message content | |||
|
90 | cfp.seek(0) | |||
|
91 | cfp.truncate() | |||
|
92 | elif hgpatch: | |||
|
93 | if line.startswith('# User '): | |||
|
94 | user = line[7:] | |||
|
95 | ui.debug('From: %s\n' % user) | |||
|
96 | elif line.startswith("# Date "): | |||
|
97 | date = line[7:] | |||
|
98 | if not line.startswith('# '): | |||
|
99 | cfp.write(line) | |||
|
100 | cfp.write('\n') | |||
|
101 | message = cfp.getvalue() | |||
|
102 | if tmpfp: | |||
|
103 | tmpfp.write(payload) | |||
|
104 | if not payload.endswith('\n'): | |||
|
105 | tmpfp.write('\n') | |||
|
106 | elif not diffs_seen and message and content_type == 'text/plain': | |||
|
107 | message += '\n' + payload | |||
|
108 | except: | |||
|
109 | tmpfp.close() | |||
|
110 | os.unlink(tmpname) | |||
|
111 | raise | |||
|
112 | ||||
|
113 | tmpfp.close() | |||
|
114 | if not diffs_seen: | |||
|
115 | os.unlink(tmpname) | |||
|
116 | return None, message, user, date | |||
|
117 | return tmpname, message, user, date | |||
|
118 | ||||
|
119 | def readgitpatch(patchname): | |||
|
120 | """extract git-style metadata about patches from <patchname>""" | |||
|
121 | class gitpatch: | |||
|
122 | "op is one of ADD, DELETE, RENAME, MODIFY or COPY" | |||
|
123 | def __init__(self, path): | |||
|
124 | self.path = path | |||
|
125 | self.oldpath = None | |||
|
126 | self.mode = None | |||
|
127 | self.op = 'MODIFY' | |||
|
128 | self.copymod = False | |||
|
129 | self.lineno = 0 | |||
|
130 | ||||
|
131 | # Filter patch for git information | |||
|
132 | gitre = re.compile('diff --git a/(.*) b/(.*)') | |||
|
133 | pf = file(patchname) | |||
|
134 | gp = None | |||
|
135 | gitpatches = [] | |||
|
136 | # Can have a git patch with only metadata, causing patch to complain | |||
|
137 | dopatch = False | |||
|
138 | ||||
|
139 | lineno = 0 | |||
|
140 | for line in pf: | |||
|
141 | lineno += 1 | |||
|
142 | if line.startswith('diff --git'): | |||
|
143 | m = gitre.match(line) | |||
|
144 | if m: | |||
|
145 | if gp: | |||
|
146 | gitpatches.append(gp) | |||
|
147 | src, dst = m.group(1,2) | |||
|
148 | gp = gitpatch(dst) | |||
|
149 | gp.lineno = lineno | |||
|
150 | elif gp: | |||
|
151 | if line.startswith('--- '): | |||
|
152 | if gp.op in ('COPY', 'RENAME'): | |||
|
153 | gp.copymod = True | |||
|
154 | dopatch = 'filter' | |||
|
155 | gitpatches.append(gp) | |||
|
156 | gp = None | |||
|
157 | if not dopatch: | |||
|
158 | dopatch = True | |||
|
159 | continue | |||
|
160 | if line.startswith('rename from '): | |||
|
161 | gp.op = 'RENAME' | |||
|
162 | gp.oldpath = line[12:].rstrip() | |||
|
163 | elif line.startswith('rename to '): | |||
|
164 | gp.path = line[10:].rstrip() | |||
|
165 | elif line.startswith('copy from '): | |||
|
166 | gp.op = 'COPY' | |||
|
167 | gp.oldpath = line[10:].rstrip() | |||
|
168 | elif line.startswith('copy to '): | |||
|
169 | gp.path = line[8:].rstrip() | |||
|
170 | elif line.startswith('deleted file'): | |||
|
171 | gp.op = 'DELETE' | |||
|
172 | elif line.startswith('new file mode '): | |||
|
173 | gp.op = 'ADD' | |||
|
174 | gp.mode = int(line.rstrip()[-3:], 8) | |||
|
175 | elif line.startswith('new mode '): | |||
|
176 | gp.mode = int(line.rstrip()[-3:], 8) | |||
|
177 | if gp: | |||
|
178 | gitpatches.append(gp) | |||
|
179 | ||||
|
180 | if not gitpatches: | |||
|
181 | dopatch = True | |||
|
182 | ||||
|
183 | return (dopatch, gitpatches) | |||
|
184 | ||||
|
185 | def dogitpatch(patchname, gitpatches): | |||
|
186 | """Preprocess git patch so that vanilla patch can handle it""" | |||
|
187 | pf = file(patchname) | |||
|
188 | pfline = 1 | |||
|
189 | ||||
|
190 | fd, patchname = tempfile.mkstemp(prefix='hg-patch-') | |||
|
191 | tmpfp = os.fdopen(fd, 'w') | |||
|
192 | ||||
|
193 | try: | |||
|
194 | for i in range(len(gitpatches)): | |||
|
195 | p = gitpatches[i] | |||
|
196 | if not p.copymod: | |||
|
197 | continue | |||
|
198 | ||||
|
199 | copyfile(p.oldpath, p.path) | |||
|
200 | ||||
|
201 | # rewrite patch hunk | |||
|
202 | while pfline < p.lineno: | |||
|
203 | tmpfp.write(pf.readline()) | |||
|
204 | pfline += 1 | |||
|
205 | tmpfp.write('diff --git a/%s b/%s\n' % (p.path, p.path)) | |||
|
206 | line = pf.readline() | |||
|
207 | pfline += 1 | |||
|
208 | while not line.startswith('--- a/'): | |||
|
209 | tmpfp.write(line) | |||
|
210 | line = pf.readline() | |||
|
211 | pfline += 1 | |||
|
212 | tmpfp.write('--- a/%s\n' % p.path) | |||
|
213 | ||||
|
214 | line = pf.readline() | |||
|
215 | while line: | |||
|
216 | tmpfp.write(line) | |||
|
217 | line = pf.readline() | |||
|
218 | except: | |||
|
219 | tmpfp.close() | |||
|
220 | os.unlink(patchname) | |||
|
221 | raise | |||
|
222 | ||||
|
223 | tmpfp.close() | |||
|
224 | return patchname | |||
|
225 | ||||
|
226 | def patch(patchname, ui, strip=1, cwd=None): | |||
|
227 | """apply the patch <patchname> to the working directory. | |||
|
228 | a list of patched files is returned""" | |||
|
229 | ||||
|
230 | (dopatch, gitpatches) = readgitpatch(patchname) | |||
|
231 | ||||
|
232 | files = {} | |||
|
233 | fuzz = False | |||
|
234 | if dopatch: | |||
|
235 | if dopatch == 'filter': | |||
|
236 | patchname = dogitpatch(patchname, gitpatches) | |||
|
237 | patcher = util.find_in_path('gpatch', os.environ.get('PATH', ''), 'patch') | |||
|
238 | args = [] | |||
|
239 | if cwd: | |||
|
240 | args.append('-d %s' % util.shellquote(cwd)) | |||
|
241 | fp = os.popen('%s %s -p%d < %s' % (patcher, ' '.join(args), strip, | |||
|
242 | util.shellquote(patchname))) | |||
|
243 | ||||
|
244 | if dopatch == 'filter': | |||
|
245 | False and os.unlink(patchname) | |||
|
246 | ||||
|
247 | for line in fp: | |||
|
248 | line = line.rstrip() | |||
|
249 | ui.note(line + '\n') | |||
|
250 | if line.startswith('patching file '): | |||
|
251 | pf = util.parse_patch_output(line) | |||
|
252 | printed_file = False | |||
|
253 | files.setdefault(pf, (None, None)) | |||
|
254 | elif line.find('with fuzz') >= 0: | |||
|
255 | fuzz = True | |||
|
256 | if not printed_file: | |||
|
257 | ui.warn(pf + '\n') | |||
|
258 | printed_file = True | |||
|
259 | ui.warn(line + '\n') | |||
|
260 | elif line.find('saving rejects to file') >= 0: | |||
|
261 | ui.warn(line + '\n') | |||
|
262 | elif line.find('FAILED') >= 0: | |||
|
263 | if not printed_file: | |||
|
264 | ui.warn(pf + '\n') | |||
|
265 | printed_file = True | |||
|
266 | ui.warn(line + '\n') | |||
|
267 | ||||
|
268 | code = fp.close() | |||
|
269 | if code: | |||
|
270 | raise util.Abort(_("patch command failed: %s") % | |||
|
271 | util.explain_exit(code)[0]) | |||
|
272 | ||||
|
273 | for gp in gitpatches: | |||
|
274 | files[gp.path] = (gp.op, gp) | |||
|
275 | ||||
|
276 | return (files, fuzz) | |||
|
277 | ||||
|
278 | def diffopts(ui, opts={}): | |||
|
279 | return mdiff.diffopts( | |||
|
280 | text=opts.get('text'), | |||
|
281 | git=(opts.get('git') or | |||
|
282 | ui.configbool('diff', 'git', None)), | |||
|
283 | showfunc=(opts.get('show_function') or | |||
|
284 | ui.configbool('diff', 'showfunc', None)), | |||
|
285 | ignorews=(opts.get('ignore_all_space') or | |||
|
286 | ui.configbool('diff', 'ignorews', None)), | |||
|
287 | ignorewsamount=(opts.get('ignore_space_change') or | |||
|
288 | ui.configbool('diff', 'ignorewsamount', None)), | |||
|
289 | ignoreblanklines=(opts.get('ignore_blank_lines') or | |||
|
290 | ui.configbool('diff', 'ignoreblanklines', None))) | |||
|
291 | ||||
|
292 | def updatedir(ui, repo, patches, wlock=None): | |||
|
293 | '''Update dirstate after patch application according to metadata''' | |||
|
294 | if not patches: | |||
|
295 | return | |||
|
296 | copies = [] | |||
|
297 | removes = [] | |||
|
298 | cfiles = patches.keys() | |||
|
299 | copts = {'after': False, 'force': False} | |||
|
300 | cwd = repo.getcwd() | |||
|
301 | if cwd: | |||
|
302 | cfiles = [util.pathto(cwd, f) for f in patches.keys()] | |||
|
303 | for f in patches: | |||
|
304 | ctype, gp = patches[f] | |||
|
305 | if ctype == 'RENAME': | |||
|
306 | copies.append((gp.oldpath, gp.path, gp.copymod)) | |||
|
307 | removes.append(gp.oldpath) | |||
|
308 | elif ctype == 'COPY': | |||
|
309 | copies.append((gp.oldpath, gp.path, gp.copymod)) | |||
|
310 | elif ctype == 'DELETE': | |||
|
311 | removes.append(gp.path) | |||
|
312 | for src, dst, after in copies: | |||
|
313 | if not after: | |||
|
314 | copyfile(src, dst, repo.root) | |||
|
315 | repo.copy(src, dst, wlock=wlock) | |||
|
316 | if removes: | |||
|
317 | repo.remove(removes, True, wlock=wlock) | |||
|
318 | for f in patches: | |||
|
319 | ctype, gp = patches[f] | |||
|
320 | if gp and gp.mode: | |||
|
321 | x = gp.mode & 0100 != 0 | |||
|
322 | dst = os.path.join(repo.root, gp.path) | |||
|
323 | util.set_exec(dst, x) | |||
|
324 | cmdutil.addremove(repo, cfiles, wlock=wlock) | |||
|
325 | files = patches.keys() | |||
|
326 | files.extend([r for r in removes if r not in files]) | |||
|
327 | files.sort() | |||
|
328 | ||||
|
329 | return files | |||
|
330 | ||||
|
331 | def diff(repo, node1=None, node2=None, files=None, match=util.always, | |||
|
332 | fp=None, changes=None, opts=None): | |||
|
333 | '''print diff of changes to files between two nodes, or node and | |||
|
334 | working directory. | |||
|
335 | ||||
|
336 | if node1 is None, use first dirstate parent instead. | |||
|
337 | if node2 is None, compare node1 with working directory.''' | |||
|
338 | ||||
|
339 | if opts is None: | |||
|
340 | opts = mdiff.defaultopts | |||
|
341 | if fp is None: | |||
|
342 | fp = repo.ui | |||
|
343 | ||||
|
344 | if not node1: | |||
|
345 | node1 = repo.dirstate.parents()[0] | |||
|
346 | ||||
|
347 | clcache = {} | |||
|
348 | def getchangelog(n): | |||
|
349 | if n not in clcache: | |||
|
350 | clcache[n] = repo.changelog.read(n) | |||
|
351 | return clcache[n] | |||
|
352 | mcache = {} | |||
|
353 | def getmanifest(n): | |||
|
354 | if n not in mcache: | |||
|
355 | mcache[n] = repo.manifest.read(n) | |||
|
356 | return mcache[n] | |||
|
357 | fcache = {} | |||
|
358 | def getfile(f): | |||
|
359 | if f not in fcache: | |||
|
360 | fcache[f] = repo.file(f) | |||
|
361 | return fcache[f] | |||
|
362 | ||||
|
363 | # reading the data for node1 early allows it to play nicely | |||
|
364 | # with repo.status and the revlog cache. | |||
|
365 | change = getchangelog(node1) | |||
|
366 | mmap = getmanifest(change[0]) | |||
|
367 | date1 = util.datestr(change[2]) | |||
|
368 | ||||
|
369 | if not changes: | |||
|
370 | changes = repo.status(node1, node2, files, match=match)[:5] | |||
|
371 | modified, added, removed, deleted, unknown = changes | |||
|
372 | if files: | |||
|
373 | def filterfiles(filters): | |||
|
374 | l = [x for x in filters if x in files] | |||
|
375 | ||||
|
376 | for t in files: | |||
|
377 | if not t.endswith("/"): | |||
|
378 | t += "/" | |||
|
379 | l += [x for x in filters if x.startswith(t)] | |||
|
380 | return l | |||
|
381 | ||||
|
382 | modified, added, removed = map(filterfiles, (modified, added, removed)) | |||
|
383 | ||||
|
384 | if not modified and not added and not removed: | |||
|
385 | return | |||
|
386 | ||||
|
387 | def renamedbetween(f, n1, n2): | |||
|
388 | r1, r2 = map(repo.changelog.rev, (n1, n2)) | |||
|
389 | src = None | |||
|
390 | while r2 > r1: | |||
|
391 | cl = getchangelog(n2)[0] | |||
|
392 | m = getmanifest(cl) | |||
|
393 | try: | |||
|
394 | src = getfile(f).renamed(m[f]) | |||
|
395 | except KeyError: | |||
|
396 | return None | |||
|
397 | if src: | |||
|
398 | f = src[0] | |||
|
399 | n2 = repo.changelog.parents(n2)[0] | |||
|
400 | r2 = repo.changelog.rev(n2) | |||
|
401 | return src | |||
|
402 | ||||
|
403 | if node2: | |||
|
404 | change = getchangelog(node2) | |||
|
405 | mmap2 = getmanifest(change[0]) | |||
|
406 | _date2 = util.datestr(change[2]) | |||
|
407 | def date2(f): | |||
|
408 | return _date2 | |||
|
409 | def read(f): | |||
|
410 | return getfile(f).read(mmap2[f]) | |||
|
411 | def renamed(f): | |||
|
412 | return renamedbetween(f, node1, node2) | |||
|
413 | else: | |||
|
414 | tz = util.makedate()[1] | |||
|
415 | _date2 = util.datestr() | |||
|
416 | def date2(f): | |||
|
417 | try: | |||
|
418 | return util.datestr((os.lstat(repo.wjoin(f)).st_mtime, tz)) | |||
|
419 | except OSError, err: | |||
|
420 | if err.errno != errno.ENOENT: raise | |||
|
421 | return _date2 | |||
|
422 | def read(f): | |||
|
423 | return repo.wread(f) | |||
|
424 | def renamed(f): | |||
|
425 | src = repo.dirstate.copies.get(f) | |||
|
426 | parent = repo.dirstate.parents()[0] | |||
|
427 | if src: | |||
|
428 | f = src[0] | |||
|
429 | of = renamedbetween(f, node1, parent) | |||
|
430 | if of: | |||
|
431 | return of | |||
|
432 | elif src: | |||
|
433 | cl = getchangelog(parent)[0] | |||
|
434 | return (src, getmanifest(cl)[src]) | |||
|
435 | else: | |||
|
436 | return None | |||
|
437 | ||||
|
438 | if repo.ui.quiet: | |||
|
439 | r = None | |||
|
440 | else: | |||
|
441 | hexfunc = repo.ui.verbose and hex or short | |||
|
442 | r = [hexfunc(node) for node in [node1, node2] if node] | |||
|
443 | ||||
|
444 | if opts.git: | |||
|
445 | copied = {} | |||
|
446 | for f in added: | |||
|
447 | src = renamed(f) | |||
|
448 | if src: | |||
|
449 | copied[f] = src | |||
|
450 | srcs = [x[1][0] for x in copied.items()] | |||
|
451 | ||||
|
452 | all = modified + added + removed | |||
|
453 | all.sort() | |||
|
454 | for f in all: | |||
|
455 | to = None | |||
|
456 | tn = None | |||
|
457 | dodiff = True | |||
|
458 | if f in mmap: | |||
|
459 | to = getfile(f).read(mmap[f]) | |||
|
460 | if f not in removed: | |||
|
461 | tn = read(f) | |||
|
462 | if opts.git: | |||
|
463 | def gitmode(x): | |||
|
464 | return x and '100755' or '100644' | |||
|
465 | def addmodehdr(header, omode, nmode): | |||
|
466 | if omode != nmode: | |||
|
467 | header.append('old mode %s\n' % omode) | |||
|
468 | header.append('new mode %s\n' % nmode) | |||
|
469 | ||||
|
470 | a, b = f, f | |||
|
471 | header = [] | |||
|
472 | if f in added: | |||
|
473 | if node2: | |||
|
474 | mode = gitmode(mmap2.execf(f)) | |||
|
475 | else: | |||
|
476 | mode = gitmode(util.is_exec(repo.wjoin(f), None)) | |||
|
477 | if f in copied: | |||
|
478 | a, arev = copied[f] | |||
|
479 | omode = gitmode(mmap.execf(a)) | |||
|
480 | addmodehdr(header, omode, mode) | |||
|
481 | op = a in removed and 'rename' or 'copy' | |||
|
482 | header.append('%s from %s\n' % (op, a)) | |||
|
483 | header.append('%s to %s\n' % (op, f)) | |||
|
484 | to = getfile(a).read(arev) | |||
|
485 | else: | |||
|
486 | header.append('new file mode %s\n' % mode) | |||
|
487 | elif f in removed: | |||
|
488 | if f in srcs: | |||
|
489 | dodiff = False | |||
|
490 | else: | |||
|
491 | mode = gitmode(mmap.execf(f)) | |||
|
492 | header.append('deleted file mode %s\n' % mode) | |||
|
493 | else: | |||
|
494 | omode = gitmode(mmap.execf(f)) | |||
|
495 | nmode = gitmode(util.is_exec(repo.wjoin(f), mmap.execf(f))) | |||
|
496 | addmodehdr(header, omode, nmode) | |||
|
497 | r = None | |||
|
498 | if dodiff: | |||
|
499 | header.insert(0, 'diff --git a/%s b/%s\n' % (a, b)) | |||
|
500 | fp.write(''.join(header)) | |||
|
501 | if dodiff: | |||
|
502 | fp.write(mdiff.unidiff(to, date1, tn, date2(f), f, r, opts=opts)) | |||
|
503 | ||||
|
504 | def export(repo, revs, template='hg-%h.patch', fp=None, switch_parent=False, | |||
|
505 | opts=None): | |||
|
506 | '''export changesets as hg patches.''' | |||
|
507 | ||||
|
508 | total = len(revs) | |||
|
509 | revwidth = max(map(len, revs)) | |||
|
510 | ||||
|
511 | def single(node, seqno, fp): | |||
|
512 | parents = [p for p in repo.changelog.parents(node) if p != nullid] | |||
|
513 | if switch_parent: | |||
|
514 | parents.reverse() | |||
|
515 | prev = (parents and parents[0]) or nullid | |||
|
516 | change = repo.changelog.read(node) | |||
|
517 | ||||
|
518 | if not fp: | |||
|
519 | fp = cmdutil.make_file(repo, template, node, total=total, | |||
|
520 | seqno=seqno, revwidth=revwidth) | |||
|
521 | if fp not in (sys.stdout, repo.ui): | |||
|
522 | repo.ui.note("%s\n" % fp.name) | |||
|
523 | ||||
|
524 | fp.write("# HG changeset patch\n") | |||
|
525 | fp.write("# User %s\n" % change[1]) | |||
|
526 | fp.write("# Date %d %d\n" % change[2]) | |||
|
527 | fp.write("# Node ID %s\n" % hex(node)) | |||
|
528 | fp.write("# Parent %s\n" % hex(prev)) | |||
|
529 | if len(parents) > 1: | |||
|
530 | fp.write("# Parent %s\n" % hex(parents[1])) | |||
|
531 | fp.write(change[4].rstrip()) | |||
|
532 | fp.write("\n\n") | |||
|
533 | ||||
|
534 | diff(repo, prev, node, fp=fp, opts=opts) | |||
|
535 | if fp not in (sys.stdout, repo.ui): | |||
|
536 | fp.close() | |||
|
537 | ||||
|
538 | for seqno, cset in enumerate(revs): | |||
|
539 | single(cset, seqno, fp) |
@@ -0,0 +1,34 b'' | |||||
|
1 | # strutil.py - string utilities for Mercurial | |||
|
2 | # | |||
|
3 | # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.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 | def findall(haystack, needle, start=0, end=None): | |||
|
9 | if end is None: | |||
|
10 | end = len(haystack) | |||
|
11 | if end < 0: | |||
|
12 | end += len(haystack) | |||
|
13 | if start < 0: | |||
|
14 | start += len(haystack) | |||
|
15 | while start < end: | |||
|
16 | c = haystack.find(needle, start, end) | |||
|
17 | if c == -1: | |||
|
18 | break | |||
|
19 | yield c | |||
|
20 | start = c + 1 | |||
|
21 | ||||
|
22 | def rfindall(haystack, needle, start=0, end=None): | |||
|
23 | if end is None: | |||
|
24 | end = len(haystack) | |||
|
25 | if end < 0: | |||
|
26 | end += len(haystack) | |||
|
27 | if start < 0: | |||
|
28 | start += len(haystack) | |||
|
29 | while end >= 0: | |||
|
30 | c = haystack.rfind(needle, start, end) | |||
|
31 | if c == -1: | |||
|
32 | break | |||
|
33 | yield c | |||
|
34 | end = c - 1 |
@@ -0,0 +1,23 b'' | |||||
|
1 | #!/bin/sh | |||
|
2 | ||||
|
3 | echo % init | |||
|
4 | hg init | |||
|
5 | ||||
|
6 | echo % commit | |||
|
7 | echo 'a' > a | |||
|
8 | hg ci -A -m test -u nobody -d '1 0' | |||
|
9 | ||||
|
10 | echo % annotate -c | |||
|
11 | hg annotate -c a | |||
|
12 | ||||
|
13 | echo % annotate -d | |||
|
14 | hg annotate -d a | |||
|
15 | ||||
|
16 | echo % annotate -n | |||
|
17 | hg annotate -n a | |||
|
18 | ||||
|
19 | echo % annotate -u | |||
|
20 | hg annotate -u a | |||
|
21 | ||||
|
22 | echo % annotate -cdnu | |||
|
23 | hg annotate -cdnu a |
@@ -0,0 +1,13 b'' | |||||
|
1 | % init | |||
|
2 | % commit | |||
|
3 | adding a | |||
|
4 | % annotate -c | |||
|
5 | 8435f90966e4: a | |||
|
6 | % annotate -d | |||
|
7 | Thu Jan 01 00:00:01 1970 +0000: a | |||
|
8 | % annotate -n | |||
|
9 | 0: a | |||
|
10 | % annotate -u | |||
|
11 | nobody: a | |||
|
12 | % annotate -cdnu | |||
|
13 | nobody 0 8435f90966e4 Thu Jan 01 00:00:01 1970 +0000: a |
@@ -0,0 +1,36 b'' | |||||
|
1 | #!/bin/sh | |||
|
2 | ||||
|
3 | set -e | |||
|
4 | ||||
|
5 | echo "[extensions]" >> $HGRCPATH | |||
|
6 | echo "hbisect=" >> $HGRCPATH | |||
|
7 | ||||
|
8 | echo % init | |||
|
9 | hg init | |||
|
10 | ||||
|
11 | echo % committing changes | |||
|
12 | count=0 | |||
|
13 | echo > a | |||
|
14 | while test $count -lt 32 ; do | |||
|
15 | echo 'a' >> a | |||
|
16 | test $count -eq 0 && hg add | |||
|
17 | hg ci -m "msg $count" -d "$count 0" | |||
|
18 | echo % committed changeset $count | |||
|
19 | count=`expr $count + 1` | |||
|
20 | done | |||
|
21 | ||||
|
22 | echo % log | |||
|
23 | hg log | |||
|
24 | ||||
|
25 | echo % hg up -C | |||
|
26 | hg up -C | |||
|
27 | ||||
|
28 | echo % bisect test | |||
|
29 | hg bisect init | |||
|
30 | hg bisect bad | |||
|
31 | hg bisect good 1 | |||
|
32 | hg bisect good | |||
|
33 | hg bisect good | |||
|
34 | hg bisect good | |||
|
35 | hg bisect bad | |||
|
36 | hg bisect good |
@@ -0,0 +1,216 b'' | |||||
|
1 | % init | |||
|
2 | % committing changes | |||
|
3 | adding a | |||
|
4 | % committed changeset 0 | |||
|
5 | % committed changeset 1 | |||
|
6 | % committed changeset 2 | |||
|
7 | % committed changeset 3 | |||
|
8 | % committed changeset 4 | |||
|
9 | % committed changeset 5 | |||
|
10 | % committed changeset 6 | |||
|
11 | % committed changeset 7 | |||
|
12 | % committed changeset 8 | |||
|
13 | % committed changeset 9 | |||
|
14 | % committed changeset 10 | |||
|
15 | % committed changeset 11 | |||
|
16 | % committed changeset 12 | |||
|
17 | % committed changeset 13 | |||
|
18 | % committed changeset 14 | |||
|
19 | % committed changeset 15 | |||
|
20 | % committed changeset 16 | |||
|
21 | % committed changeset 17 | |||
|
22 | % committed changeset 18 | |||
|
23 | % committed changeset 19 | |||
|
24 | % committed changeset 20 | |||
|
25 | % committed changeset 21 | |||
|
26 | % committed changeset 22 | |||
|
27 | % committed changeset 23 | |||
|
28 | % committed changeset 24 | |||
|
29 | % committed changeset 25 | |||
|
30 | % committed changeset 26 | |||
|
31 | % committed changeset 27 | |||
|
32 | % committed changeset 28 | |||
|
33 | % committed changeset 29 | |||
|
34 | % committed changeset 30 | |||
|
35 | % committed changeset 31 | |||
|
36 | % log | |||
|
37 | changeset: 31:58c80a7c8a40 | |||
|
38 | tag: tip | |||
|
39 | user: test | |||
|
40 | date: Thu Jan 01 00:00:31 1970 +0000 | |||
|
41 | summary: msg 31 | |||
|
42 | ||||
|
43 | changeset: 30:ed2d2f24b11c | |||
|
44 | user: test | |||
|
45 | date: Thu Jan 01 00:00:30 1970 +0000 | |||
|
46 | summary: msg 30 | |||
|
47 | ||||
|
48 | changeset: 29:b5bd63375ab9 | |||
|
49 | user: test | |||
|
50 | date: Thu Jan 01 00:00:29 1970 +0000 | |||
|
51 | summary: msg 29 | |||
|
52 | ||||
|
53 | changeset: 28:8e0c2264c8af | |||
|
54 | user: test | |||
|
55 | date: Thu Jan 01 00:00:28 1970 +0000 | |||
|
56 | summary: msg 28 | |||
|
57 | ||||
|
58 | changeset: 27:288867a866e9 | |||
|
59 | user: test | |||
|
60 | date: Thu Jan 01 00:00:27 1970 +0000 | |||
|
61 | summary: msg 27 | |||
|
62 | ||||
|
63 | changeset: 26:3efc6fd51aeb | |||
|
64 | user: test | |||
|
65 | date: Thu Jan 01 00:00:26 1970 +0000 | |||
|
66 | summary: msg 26 | |||
|
67 | ||||
|
68 | changeset: 25:02a84173a97a | |||
|
69 | user: test | |||
|
70 | date: Thu Jan 01 00:00:25 1970 +0000 | |||
|
71 | summary: msg 25 | |||
|
72 | ||||
|
73 | changeset: 24:10e0acd3809e | |||
|
74 | user: test | |||
|
75 | date: Thu Jan 01 00:00:24 1970 +0000 | |||
|
76 | summary: msg 24 | |||
|
77 | ||||
|
78 | changeset: 23:5ec79163bff4 | |||
|
79 | user: test | |||
|
80 | date: Thu Jan 01 00:00:23 1970 +0000 | |||
|
81 | summary: msg 23 | |||
|
82 | ||||
|
83 | changeset: 22:06c7993750ce | |||
|
84 | user: test | |||
|
85 | date: Thu Jan 01 00:00:22 1970 +0000 | |||
|
86 | summary: msg 22 | |||
|
87 | ||||
|
88 | changeset: 21:e5db6aa3fe2a | |||
|
89 | user: test | |||
|
90 | date: Thu Jan 01 00:00:21 1970 +0000 | |||
|
91 | summary: msg 21 | |||
|
92 | ||||
|
93 | changeset: 20:7128fb4fdbc9 | |||
|
94 | user: test | |||
|
95 | date: Thu Jan 01 00:00:20 1970 +0000 | |||
|
96 | summary: msg 20 | |||
|
97 | ||||
|
98 | changeset: 19:52798545b482 | |||
|
99 | user: test | |||
|
100 | date: Thu Jan 01 00:00:19 1970 +0000 | |||
|
101 | summary: msg 19 | |||
|
102 | ||||
|
103 | changeset: 18:86977a90077e | |||
|
104 | user: test | |||
|
105 | date: Thu Jan 01 00:00:18 1970 +0000 | |||
|
106 | summary: msg 18 | |||
|
107 | ||||
|
108 | changeset: 17:03515f4a9080 | |||
|
109 | user: test | |||
|
110 | date: Thu Jan 01 00:00:17 1970 +0000 | |||
|
111 | summary: msg 17 | |||
|
112 | ||||
|
113 | changeset: 16:a2e6ea4973e9 | |||
|
114 | user: test | |||
|
115 | date: Thu Jan 01 00:00:16 1970 +0000 | |||
|
116 | summary: msg 16 | |||
|
117 | ||||
|
118 | changeset: 15:e7fa0811edb0 | |||
|
119 | user: test | |||
|
120 | date: Thu Jan 01 00:00:15 1970 +0000 | |||
|
121 | summary: msg 15 | |||
|
122 | ||||
|
123 | changeset: 14:ce8f0998e922 | |||
|
124 | user: test | |||
|
125 | date: Thu Jan 01 00:00:14 1970 +0000 | |||
|
126 | summary: msg 14 | |||
|
127 | ||||
|
128 | changeset: 13:9d7d07bc967c | |||
|
129 | user: test | |||
|
130 | date: Thu Jan 01 00:00:13 1970 +0000 | |||
|
131 | summary: msg 13 | |||
|
132 | ||||
|
133 | changeset: 12:1941b52820a5 | |||
|
134 | user: test | |||
|
135 | date: Thu Jan 01 00:00:12 1970 +0000 | |||
|
136 | summary: msg 12 | |||
|
137 | ||||
|
138 | changeset: 11:7b4cd9578619 | |||
|
139 | user: test | |||
|
140 | date: Thu Jan 01 00:00:11 1970 +0000 | |||
|
141 | summary: msg 11 | |||
|
142 | ||||
|
143 | changeset: 10:7c5eff49a6b6 | |||
|
144 | user: test | |||
|
145 | date: Thu Jan 01 00:00:10 1970 +0000 | |||
|
146 | summary: msg 10 | |||
|
147 | ||||
|
148 | changeset: 9:eb44510ef29a | |||
|
149 | user: test | |||
|
150 | date: Thu Jan 01 00:00:09 1970 +0000 | |||
|
151 | summary: msg 9 | |||
|
152 | ||||
|
153 | changeset: 8:453eb4dba229 | |||
|
154 | user: test | |||
|
155 | date: Thu Jan 01 00:00:08 1970 +0000 | |||
|
156 | summary: msg 8 | |||
|
157 | ||||
|
158 | changeset: 7:03750880c6b5 | |||
|
159 | user: test | |||
|
160 | date: Thu Jan 01 00:00:07 1970 +0000 | |||
|
161 | summary: msg 7 | |||
|
162 | ||||
|
163 | changeset: 6:a3d5c6fdf0d3 | |||
|
164 | user: test | |||
|
165 | date: Thu Jan 01 00:00:06 1970 +0000 | |||
|
166 | summary: msg 6 | |||
|
167 | ||||
|
168 | changeset: 5:7874a09ea728 | |||
|
169 | user: test | |||
|
170 | date: Thu Jan 01 00:00:05 1970 +0000 | |||
|
171 | summary: msg 5 | |||
|
172 | ||||
|
173 | changeset: 4:9b2ba8336a65 | |||
|
174 | user: test | |||
|
175 | date: Thu Jan 01 00:00:04 1970 +0000 | |||
|
176 | summary: msg 4 | |||
|
177 | ||||
|
178 | changeset: 3:b53bea5e2fcb | |||
|
179 | user: test | |||
|
180 | date: Thu Jan 01 00:00:03 1970 +0000 | |||
|
181 | summary: msg 3 | |||
|
182 | ||||
|
183 | changeset: 2:db07c04beaca | |||
|
184 | user: test | |||
|
185 | date: Thu Jan 01 00:00:02 1970 +0000 | |||
|
186 | summary: msg 2 | |||
|
187 | ||||
|
188 | changeset: 1:5cd978ea5149 | |||
|
189 | user: test | |||
|
190 | date: Thu Jan 01 00:00:01 1970 +0000 | |||
|
191 | summary: msg 1 | |||
|
192 | ||||
|
193 | changeset: 0:b99c7b9c8e11 | |||
|
194 | user: test | |||
|
195 | date: Thu Jan 01 00:00:00 1970 +0000 | |||
|
196 | summary: msg 0 | |||
|
197 | ||||
|
198 | % hg up -C | |||
|
199 | 0 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
|
200 | % bisect test | |||
|
201 | Testing changeset 16:a2e6ea4973e9 (30 changesets remaining, ~4 tests) | |||
|
202 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
|
203 | Testing changeset 23:5ec79163bff4 (15 changesets remaining, ~3 tests) | |||
|
204 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
|
205 | Testing changeset 27:288867a866e9 (8 changesets remaining, ~3 tests) | |||
|
206 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
|
207 | Testing changeset 29:b5bd63375ab9 (4 changesets remaining, ~2 tests) | |||
|
208 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
|
209 | Testing changeset 28:8e0c2264c8af (2 changesets remaining, ~1 tests) | |||
|
210 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
|
211 | The first bad revision is: | |||
|
212 | changeset: 29:b5bd63375ab9 | |||
|
213 | user: test | |||
|
214 | date: Thu Jan 01 00:00:29 1970 +0000 | |||
|
215 | summary: msg 29 | |||
|
216 |
@@ -0,0 +1,27 b'' | |||||
|
1 | #!/bin/sh | |||
|
2 | ||||
|
3 | hg init | |||
|
4 | ||||
|
5 | mkdir alpha | |||
|
6 | touch alpha/one | |||
|
7 | mkdir beta | |||
|
8 | touch beta/two | |||
|
9 | ||||
|
10 | hg add alpha/one beta/two | |||
|
11 | hg ci -m "start" -d "1000000 0" | |||
|
12 | ||||
|
13 | echo 1 > alpha/one | |||
|
14 | echo 2 > beta/two | |||
|
15 | ||||
|
16 | echo EVERYTHING | |||
|
17 | hg diff | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ | |||
|
18 | -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" | |||
|
19 | ||||
|
20 | echo BETA ONLY | |||
|
21 | hg diff beta | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ | |||
|
22 | -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" | |||
|
23 | ||||
|
24 | echo INSIDE BETA | |||
|
25 | cd beta | |||
|
26 | hg diff . | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ | |||
|
27 | -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" |
@@ -0,0 +1,23 b'' | |||||
|
1 | EVERYTHING | |||
|
2 | diff -r ec612a6291f1 alpha/one | |||
|
3 | --- a/alpha/one | |||
|
4 | +++ b/alpha/one | |||
|
5 | @@ -0,0 +1,1 @@ | |||
|
6 | +1 | |||
|
7 | diff -r ec612a6291f1 beta/two | |||
|
8 | --- a/beta/two | |||
|
9 | +++ b/beta/two | |||
|
10 | @@ -0,0 +1,1 @@ | |||
|
11 | +2 | |||
|
12 | BETA ONLY | |||
|
13 | diff -r ec612a6291f1 beta/two | |||
|
14 | --- a/beta/two | |||
|
15 | +++ b/beta/two | |||
|
16 | @@ -0,0 +1,1 @@ | |||
|
17 | +2 | |||
|
18 | INSIDE BETA | |||
|
19 | diff -r ec612a6291f1 beta/two | |||
|
20 | --- a/beta/two | |||
|
21 | +++ b/beta/two | |||
|
22 | @@ -0,0 +1,1 @@ | |||
|
23 | +2 |
@@ -0,0 +1,29 b'' | |||||
|
1 | #!/bin/sh | |||
|
2 | ||||
|
3 | echo "[extensions]" >> $HGRCPATH | |||
|
4 | echo "extdiff=" >> $HGRCPATH | |||
|
5 | ||||
|
6 | hg init a | |||
|
7 | cd a | |||
|
8 | echo a > a | |||
|
9 | hg add | |||
|
10 | diff -N /dev/null /dev/null 2> /dev/null | |||
|
11 | if [ $? -ne 0 ]; then | |||
|
12 | opt="-p gdiff" | |||
|
13 | fi | |||
|
14 | hg extdiff -o -Nr $opt | |||
|
15 | ||||
|
16 | echo "[extdiff]" >> $HGRCPATH | |||
|
17 | echo "cmd.falabala=echo" >> $HGRCPATH | |||
|
18 | echo "opts.falabala=diffing" >> $HGRCPATH | |||
|
19 | ||||
|
20 | hg falabala | |||
|
21 | ||||
|
22 | hg help falabala | |||
|
23 | ||||
|
24 | hg ci -d '0 0' -mtest1 | |||
|
25 | ||||
|
26 | echo b >> a | |||
|
27 | hg ci -d '1 0' -mtest2 | |||
|
28 | ||||
|
29 | hg falabala -r 0:1 || echo "diff-like tools yield a non-zero exit code" |
@@ -0,0 +1,32 b'' | |||||
|
1 | adding a | |||
|
2 | making snapshot of 0 files from rev 000000000000 | |||
|
3 | making snapshot of 1 files from working dir | |||
|
4 | diff -Nr a.000000000000/a a/a | |||
|
5 | 0a1 | |||
|
6 | > a | |||
|
7 | making snapshot of 0 files from rev 000000000000 | |||
|
8 | making snapshot of 1 files from working dir | |||
|
9 | diffing a.000000000000 a | |||
|
10 | hg falabala [OPT]... [FILE]... | |||
|
11 | ||||
|
12 | use 'echo' to diff repository (or selected files) | |||
|
13 | ||||
|
14 | Show differences between revisions for the specified | |||
|
15 | files, using the 'echo' program. | |||
|
16 | ||||
|
17 | When two revision arguments are given, then changes are | |||
|
18 | shown between those revisions. If only one revision is | |||
|
19 | specified then that revision is compared to the working | |||
|
20 | directory, and, when no revisions are specified, the | |||
|
21 | working directory files are compared to its parent. | |||
|
22 | ||||
|
23 | options: | |||
|
24 | ||||
|
25 | -o --option pass option to comparison program | |||
|
26 | -r --rev revision | |||
|
27 | -I --include include names matching the given patterns | |||
|
28 | -X --exclude exclude names matching the given patterns | |||
|
29 | making snapshot of 1 files from rev e27a2475d60a | |||
|
30 | making snapshot of 1 files from rev 5e49ec8d3f05 | |||
|
31 | diffing a.e27a2475d60a a.5e49ec8d3f05 | |||
|
32 | diff-like tools yield a non-zero exit code |
@@ -0,0 +1,52 b'' | |||||
|
1 | #!/bin/sh | |||
|
2 | ||||
|
3 | hg init a | |||
|
4 | cd a | |||
|
5 | ||||
|
6 | echo start > start | |||
|
7 | hg ci -Amstart -d '0 0' | |||
|
8 | echo new > new | |||
|
9 | hg ci -Amnew -d '0 0' | |||
|
10 | echo '% new file' | |||
|
11 | hg diff --git -r 0 | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ | |||
|
12 | -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" | |||
|
13 | ||||
|
14 | hg cp new copy | |||
|
15 | hg ci -mcopy -d '0 0' | |||
|
16 | echo '% copy' | |||
|
17 | hg diff --git -r 1:tip | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ | |||
|
18 | -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" | |||
|
19 | ||||
|
20 | hg mv copy rename | |||
|
21 | hg ci -mrename -d '0 0' | |||
|
22 | echo '% rename' | |||
|
23 | hg diff --git -r 2:tip | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ | |||
|
24 | -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" | |||
|
25 | ||||
|
26 | hg rm rename | |||
|
27 | hg ci -mdelete -d '0 0' | |||
|
28 | echo '% delete' | |||
|
29 | hg diff --git -r 3:tip | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ | |||
|
30 | -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" | |||
|
31 | ||||
|
32 | cat > src <<EOF | |||
|
33 | 1 | |||
|
34 | 2 | |||
|
35 | 3 | |||
|
36 | 4 | |||
|
37 | 5 | |||
|
38 | EOF | |||
|
39 | hg ci -Amsrc -d '0 0' | |||
|
40 | chmod +x src | |||
|
41 | hg ci -munexec -d '0 0' | |||
|
42 | echo '% chmod 644' | |||
|
43 | hg diff --git -r 5:tip | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ | |||
|
44 | -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" | |||
|
45 | ||||
|
46 | hg mv src dst | |||
|
47 | chmod -x dst | |||
|
48 | echo a >> dst | |||
|
49 | hg ci -mrenamemod -d '0 0' | |||
|
50 | echo '% rename+mod+chmod' | |||
|
51 | hg diff --git -r 6:tip | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ | |||
|
52 | -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" |
@@ -0,0 +1,42 b'' | |||||
|
1 | adding start | |||
|
2 | adding new | |||
|
3 | % new file | |||
|
4 | diff --git a/new b/new | |||
|
5 | new file mode 100644 | |||
|
6 | --- /dev/null | |||
|
7 | +++ b/new | |||
|
8 | @@ -0,0 +1,1 @@ | |||
|
9 | +new | |||
|
10 | % copy | |||
|
11 | diff --git a/new b/copy | |||
|
12 | copy from new | |||
|
13 | copy to copy | |||
|
14 | % rename | |||
|
15 | diff --git a/copy b/rename | |||
|
16 | rename from copy | |||
|
17 | rename to rename | |||
|
18 | % delete | |||
|
19 | diff --git a/rename b/rename | |||
|
20 | deleted file mode 100644 | |||
|
21 | --- a/rename | |||
|
22 | +++ /dev/null | |||
|
23 | @@ -1,1 +0,0 @@ | |||
|
24 | -new | |||
|
25 | adding src | |||
|
26 | % chmod 644 | |||
|
27 | diff --git a/src b/src | |||
|
28 | old mode 100644 | |||
|
29 | new mode 100755 | |||
|
30 | % rename+mod+chmod | |||
|
31 | diff --git a/src b/dst | |||
|
32 | old mode 100755 | |||
|
33 | new mode 100644 | |||
|
34 | rename from src | |||
|
35 | rename to dst | |||
|
36 | --- a/dst | |||
|
37 | +++ b/dst | |||
|
38 | @@ -3,3 +3,4 @@ 3 | |||
|
39 | 3 | |||
|
40 | 4 | |||
|
41 | 5 | |||
|
42 | +a |
@@ -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,34 b'' | |||||
|
1 | % new file | |||
|
2 | applying patch from stdin | |||
|
3 | % chmod +x | |||
|
4 | applying patch from stdin | |||
|
5 | % copy | |||
|
6 | applying patch from stdin | |||
|
7 | a | |||
|
8 | a | |||
|
9 | % rename | |||
|
10 | applying patch from stdin | |||
|
11 | copyx | |||
|
12 | new | |||
|
13 | rename | |||
|
14 | % delete | |||
|
15 | applying patch from stdin | |||
|
16 | new | |||
|
17 | rename | |||
|
18 | % regular diff | |||
|
19 | applying patch from stdin | |||
|
20 | % copy and modify | |||
|
21 | applying patch from stdin | |||
|
22 | a | |||
|
23 | a | |||
|
24 | b | |||
|
25 | a | |||
|
26 | a | |||
|
27 | % rename and modify | |||
|
28 | applying patch from stdin | |||
|
29 | copy2: No such file or directory | |||
|
30 | a | |||
|
31 | a | |||
|
32 | b | |||
|
33 | c | |||
|
34 | a |
@@ -0,0 +1,49 b'' | |||||
|
1 | #!/bin/sh | |||
|
2 | # http://www.selenic.com/mercurial/bts/issue322 | |||
|
3 | ||||
|
4 | echo % file replaced with directory | |||
|
5 | ||||
|
6 | hg init a | |||
|
7 | cd a | |||
|
8 | echo a > a | |||
|
9 | hg commit -Ama | |||
|
10 | rm a | |||
|
11 | mkdir a | |||
|
12 | echo a > a/a | |||
|
13 | ||||
|
14 | echo % should fail - would corrupt dirstate | |||
|
15 | hg add a/a | |||
|
16 | ||||
|
17 | cd .. | |||
|
18 | ||||
|
19 | echo % directory replaced with file | |||
|
20 | ||||
|
21 | hg init c | |||
|
22 | cd c | |||
|
23 | mkdir a | |||
|
24 | echo a > a/a | |||
|
25 | hg commit -Ama | |||
|
26 | ||||
|
27 | rm -rf a | |||
|
28 | echo a > a | |||
|
29 | ||||
|
30 | echo % should fail - would corrupt dirstate | |||
|
31 | hg add a | |||
|
32 | ||||
|
33 | cd .. | |||
|
34 | ||||
|
35 | echo % directory replaced with file | |||
|
36 | ||||
|
37 | hg init d | |||
|
38 | cd d | |||
|
39 | mkdir b | |||
|
40 | mkdir b/c | |||
|
41 | echo a > b/c/d | |||
|
42 | hg commit -Ama | |||
|
43 | rm -rf b | |||
|
44 | echo a > b | |||
|
45 | ||||
|
46 | echo % should fail - would corrupt dirstate | |||
|
47 | hg add b | |||
|
48 | ||||
|
49 | exit 0 |
@@ -0,0 +1,12 b'' | |||||
|
1 | % file replaced with directory | |||
|
2 | adding a | |||
|
3 | % should fail - would corrupt dirstate | |||
|
4 | abort: file named 'a' already in dirstate | |||
|
5 | % directory replaced with file | |||
|
6 | adding a/a | |||
|
7 | % should fail - would corrupt dirstate | |||
|
8 | abort: directory named 'a' already in dirstate | |||
|
9 | % directory replaced with file | |||
|
10 | adding b/c/d | |||
|
11 | % should fail - would corrupt dirstate | |||
|
12 | abort: directory named 'b' already in dirstate |
@@ -0,0 +1,40 b'' | |||||
|
1 | #!/bin/sh | |||
|
2 | ||||
|
3 | hg init | |||
|
4 | echo a > a | |||
|
5 | hg commit -A -ma | |||
|
6 | ||||
|
7 | echo a >> a | |||
|
8 | hg commit -mb | |||
|
9 | ||||
|
10 | echo a >> a | |||
|
11 | hg commit -mc | |||
|
12 | ||||
|
13 | hg up 1 | |||
|
14 | echo a >> a | |||
|
15 | hg commit -md | |||
|
16 | ||||
|
17 | hg up 1 | |||
|
18 | echo a >> a | |||
|
19 | hg commit -me | |||
|
20 | ||||
|
21 | hg up 1 | |||
|
22 | echo % should fail because not at a head | |||
|
23 | hg merge | |||
|
24 | ||||
|
25 | hg up | |||
|
26 | echo % should fail because \> 2 heads | |||
|
27 | hg merge | |||
|
28 | ||||
|
29 | echo % should succeed | |||
|
30 | hg merge 2 | |||
|
31 | hg commit -mm1 | |||
|
32 | ||||
|
33 | echo % should succeed - 2 heads | |||
|
34 | hg merge | |||
|
35 | hg commit -mm2 | |||
|
36 | ||||
|
37 | echo % should fail because 1 head | |||
|
38 | hg merge | |||
|
39 | ||||
|
40 | true |
@@ -0,0 +1,17 b'' | |||||
|
1 | adding a | |||
|
2 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
|
3 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
|
4 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
|
5 | % should fail because not at a head | |||
|
6 | abort: repo has 3 heads - please merge with an explicit rev | |||
|
7 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
|
8 | % should fail because > 2 heads | |||
|
9 | abort: repo has 3 heads - please merge with an explicit rev | |||
|
10 | % should succeed | |||
|
11 | 0 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
|
12 | (branch merge, don't forget to commit) | |||
|
13 | % should succeed - 2 heads | |||
|
14 | 0 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
|
15 | (branch merge, don't forget to commit) | |||
|
16 | % should fail because 1 head | |||
|
17 | abort: there is nothing to merge - use "hg update" instead |
@@ -0,0 +1,27 b'' | |||||
|
1 | #!/bin/sh | |||
|
2 | ||||
|
3 | echo "[extensions]" >> $HGRCPATH | |||
|
4 | echo "mq=" >> $HGRCPATH | |||
|
5 | ||||
|
6 | echo % init | |||
|
7 | hg init a | |||
|
8 | cd a | |||
|
9 | ||||
|
10 | echo % commit | |||
|
11 | echo 'base' > base | |||
|
12 | hg ci -Ambase -d '1 0' | |||
|
13 | ||||
|
14 | echo % qnew mqbase | |||
|
15 | hg qnew -mmqbase mqbase | |||
|
16 | ||||
|
17 | echo % qrefresh | |||
|
18 | echo 'patched' > base | |||
|
19 | hg qrefresh | |||
|
20 | ||||
|
21 | echo % qdiff | |||
|
22 | hg qdiff | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ | |||
|
23 | -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" | |||
|
24 | ||||
|
25 | echo % qdiff dirname | |||
|
26 | hg qdiff . | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ | |||
|
27 | -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" |
@@ -0,0 +1,19 b'' | |||||
|
1 | % init | |||
|
2 | % commit | |||
|
3 | adding base | |||
|
4 | % qnew mqbase | |||
|
5 | % qrefresh | |||
|
6 | % qdiff | |||
|
7 | diff -r 67e992f2c4f3 base | |||
|
8 | --- a/base | |||
|
9 | +++ b/base | |||
|
10 | @@ -1,1 +1,1 @@ base | |||
|
11 | -base | |||
|
12 | +patched | |||
|
13 | % qdiff dirname | |||
|
14 | diff -r 67e992f2c4f3 base | |||
|
15 | --- a/base | |||
|
16 | +++ b/base | |||
|
17 | @@ -1,1 +1,1 @@ base | |||
|
18 | -base | |||
|
19 | +patched |
@@ -0,0 +1,18 b'' | |||||
|
1 | #!/bin/sh | |||
|
2 | ||||
|
3 | hg init | |||
|
4 | ||||
|
5 | echo a > a | |||
|
6 | hg ci -d '0 0' -Ama | |||
|
7 | ||||
|
8 | hg an a | |||
|
9 | ||||
|
10 | echo "[ui]" >> $HGRCPATH | |||
|
11 | echo "strict=True" >> $HGRCPATH | |||
|
12 | ||||
|
13 | hg an a | |||
|
14 | hg annotate a | |||
|
15 | ||||
|
16 | echo % should succeed - up is an alias, not an abbreviation | |||
|
17 | ||||
|
18 | hg up |
@@ -0,0 +1,26 b'' | |||||
|
1 | adding a | |||
|
2 | 0: a | |||
|
3 | hg: unknown command 'an' | |||
|
4 | Mercurial Distributed SCM | |||
|
5 | ||||
|
6 | basic commands (use "hg help" for the full list or option "-v" for details): | |||
|
7 | ||||
|
8 | add add the specified files on the next commit | |||
|
9 | annotate show changeset information per file line | |||
|
10 | clone make a copy of an existing repository | |||
|
11 | commit commit the specified files or all outstanding changes | |||
|
12 | diff diff repository (or selected files) | |||
|
13 | export dump the header and diffs for one or more changesets | |||
|
14 | init create a new repository in the given directory | |||
|
15 | log show revision history of entire repository or files | |||
|
16 | parents show the parents of the working dir or revision | |||
|
17 | pull pull changes from the specified source | |||
|
18 | push push changes to the specified destination | |||
|
19 | remove remove the specified files on the next commit | |||
|
20 | revert revert files or dirs to their states as of some revision | |||
|
21 | serve export the repository via HTTP | |||
|
22 | status show changed files in the working directory | |||
|
23 | update update or merge working directory | |||
|
24 | 0: a | |||
|
25 | % should succeed - up is an alias, not an abbreviation | |||
|
26 | 0 files updated, 0 files merged, 0 files removed, 0 files unresolved |
@@ -21,6 +21,7 b' doc/*.[0-9].{x,ht}ml' | |||||
21 | MANIFEST |
|
21 | MANIFEST | |
22 | patches |
|
22 | patches | |
23 | mercurial/__version__.py |
|
23 | mercurial/__version__.py | |
|
24 | .DS_Store | |||
24 |
|
25 | |||
25 | syntax: regexp |
|
26 | syntax: regexp | |
26 | ^\.pc/ |
|
27 | ^\.pc/ |
@@ -4,6 +4,7 b' Goffredo Baroncelli <kreijack at libero.' | |||||
4 | Muli Ben-Yehuda <mulix at mulix.org> |
|
4 | Muli Ben-Yehuda <mulix at mulix.org> | |
5 | Mikael Berthe <mikael at lilotux.net> |
|
5 | Mikael Berthe <mikael at lilotux.net> | |
6 | Benoit Boissinot <bboissin at gmail.com> |
|
6 | Benoit Boissinot <bboissin at gmail.com> | |
|
7 | Brendan Cully <brendan at kublai.com> | |||
7 | Vincent Danjean <vdanjean.ml at free.fr> |
|
8 | Vincent Danjean <vdanjean.ml at free.fr> | |
8 | Jake Edge <jake at edge2.net> |
|
9 | Jake Edge <jake at edge2.net> | |
9 | Michael Fetterman <michael.fetterman at intel.com> |
|
10 | Michael Fetterman <michael.fetterman at intel.com> |
@@ -722,7 +722,7 b' code by typing `M-x find-library mercuri' | |||||
722 | (if (not hg-root-dir) |
|
722 | (if (not hg-root-dir) | |
723 | (error "error: %s: directory is not part of a Mercurial repository." |
|
723 | (error "error: %s: directory is not part of a Mercurial repository." | |
724 | default-directory) |
|
724 | default-directory) | |
725 |
(cd |
|
725 | (cd hg-root-dir))))) | |
726 |
|
726 | |||
727 | (defun hg-add (path) |
|
727 | (defun hg-add (path) | |
728 | "Add PATH to the Mercurial repository on the next commit. |
|
728 | "Add PATH to the Mercurial repository on the next commit. |
@@ -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). |
@@ -306,7 +306,7 b' http_proxy::' | |||||
306 | smtp:: |
|
306 | smtp:: | |
307 | Configuration for extensions that need to send email messages. |
|
307 | Configuration for extensions that need to send email messages. | |
308 | host;; |
|
308 | host;; | |
309 |
|
|
309 | Host name of mail server, e.g. "mail.example.com". | |
310 | port;; |
|
310 | port;; | |
311 | Optional. Port to connect to on mail server. Default: 25. |
|
311 | Optional. Port to connect to on mail server. Default: 25. | |
312 | tls;; |
|
312 | tls;; | |
@@ -377,6 +377,9 b' ui::' | |||||
377 | remote command to use for clone/push/pull operations. Default is 'hg'. |
|
377 | remote command to use for clone/push/pull operations. Default is 'hg'. | |
378 | ssh;; |
|
378 | ssh;; | |
379 | command to use for SSH connections. Default is 'ssh'. |
|
379 | command to use for SSH connections. Default is 'ssh'. | |
|
380 | strict;; | |||
|
381 | Require exact command names, instead of allowing unambiguous | |||
|
382 | abbreviations. True or False. Default is False. | |||
380 | timeout;; |
|
383 | timeout;; | |
381 | The timeout used when a lock is held (in seconds), a negative value |
|
384 | The timeout used when a lock is held (in seconds), a negative value | |
382 | means no timeout. Default is 600. |
|
385 | means no timeout. Default is 600. |
@@ -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 | 認められます。 |
@@ -5,19 +5,24 b'' | |||||
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. | |
7 | # |
|
7 | # | |
8 | # allow to use external programs to compare revisions, or revision |
|
8 | # The `extdiff' Mercurial extension allows you to use external programs | |
9 | # with working dir. program is called with two arguments: paths to |
|
9 | # to compare revisions, or revision with working dir. The external diff | |
10 | # directories containing snapshots of files to compare. |
|
10 | # programs are called with a configurable set of options and two | |
|
11 | # non-option arguments: paths to directories containing snapshots of | |||
|
12 | # files to compare. | |||
11 | # |
|
13 | # | |
12 | # to enable: |
|
14 | # To enable this extension: | |
13 | # |
|
15 | # | |
14 | # [extensions] |
|
16 | # [extensions] | |
15 | # hgext.extdiff = |
|
17 | # hgext.extdiff = | |
16 | # |
|
18 | # | |
17 |
# also allows to configure new diff commands, so |
|
19 | # The `extdiff' extension also allows to configure new diff commands, so | |
18 | # type "hg extdiff -p kdiff3" always. |
|
20 | # you do not need to type "hg extdiff -p kdiff3" always. | |
19 | # |
|
21 | # | |
20 | # [extdiff] |
|
22 | # [extdiff] | |
|
23 | # # add new command that runs GNU diff(1) in 'context diff' mode | |||
|
24 | # cmd.cdiff = gdiff | |||
|
25 | # opts.cdiff = -Nprc5 | |||
21 | # # add new command called vdiff, runs kdiff3 |
|
26 | # # add new command called vdiff, runs kdiff3 | |
22 | # cmd.vdiff = kdiff3 |
|
27 | # cmd.vdiff = kdiff3 | |
23 | # # add new command called meld, runs meld (no need to name twice) |
|
28 | # # add new command called meld, runs meld (no need to name twice) | |
@@ -26,16 +31,23 b'' | |||||
26 | # #(see http://www.vim.org/scripts/script.php?script_id=102) |
|
31 | # #(see http://www.vim.org/scripts/script.php?script_id=102) | |
27 | # cmd.vimdiff = LC_ALL=C gvim -f '+bdel 1 2' '+ execute "DirDiff ".argv(0)." ".argv(1)' |
|
32 | # cmd.vimdiff = LC_ALL=C gvim -f '+bdel 1 2' '+ execute "DirDiff ".argv(0)." ".argv(1)' | |
28 | # |
|
33 | # | |
29 | # you can use -I/-X and list of file or directory names like normal |
|
34 | # Each custom diff commands can have two parts: a `cmd' and an `opts' | |
30 | # "hg diff" command. extdiff makes snapshots of only needed files, so |
|
35 | # part. The cmd.xxx option defines the name of an executable program | |
31 | # compare program will be fast. |
|
36 | # that will be run, and opts.xxx defines a set of command-line options | |
|
37 | # which will be inserted to the command between the program name and | |||
|
38 | # the files/directories to diff (i.e. the cdiff example above). | |||
|
39 | # | |||
|
40 | # You can use -I/-X and list of file or directory names like normal | |||
|
41 | # "hg diff" command. The `extdiff' extension makes snapshots of only | |||
|
42 | # needed files, so running the external diff program will actually be | |||
|
43 | # pretty fast (at least faster than having to compare the entire tree). | |||
32 |
|
44 | |||
33 | from mercurial.demandload import demandload |
|
45 | from mercurial.demandload import demandload | |
34 | from mercurial.i18n import gettext as _ |
|
46 | from mercurial.i18n import gettext as _ | |
35 | from mercurial.node import * |
|
47 | from mercurial.node import * | |
36 | demandload(globals(), 'mercurial:commands,util os shutil tempfile') |
|
48 | demandload(globals(), 'mercurial:commands,cmdutil,util os shutil tempfile') | |
37 |
|
49 | |||
38 | def dodiff(ui, repo, diffcmd, pats, opts): |
|
50 | def dodiff(ui, repo, diffcmd, diffopts, pats, opts): | |
39 | def snapshot_node(files, node): |
|
51 | def snapshot_node(files, node): | |
40 | '''snapshot files as of some revision''' |
|
52 | '''snapshot files as of some revision''' | |
41 | changes = repo.changelog.read(node) |
|
53 | changes = repo.changelog.read(node) | |
@@ -79,9 +91,9 b' def dodiff(ui, repo, diffcmd, pats, opts' | |||||
79 | return dirname |
|
91 | return dirname | |
80 |
|
92 | |||
81 | node1, node2 = commands.revpair(ui, repo, opts['rev']) |
|
93 | node1, node2 = commands.revpair(ui, repo, opts['rev']) | |
82 |
files, matchfn, anypats = c |
|
94 | files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts) | |
83 |
modified, added, removed, deleted, unknown = repo. |
|
95 | modified, added, removed, deleted, unknown = repo.status( | |
84 | node1, node2, files, match=matchfn) |
|
96 | node1, node2, files, match=matchfn)[:5] | |
85 | if not (modified or added or removed): |
|
97 | if not (modified or added or removed): | |
86 | return 0 |
|
98 | return 0 | |
87 |
|
99 | |||
@@ -92,9 +104,12 b' def dodiff(ui, repo, diffcmd, pats, opts' | |||||
92 | dir2 = snapshot_node(modified + added, node2) |
|
104 | dir2 = snapshot_node(modified + added, node2) | |
93 | else: |
|
105 | else: | |
94 | dir2 = snapshot_wdir(modified + added) |
|
106 | dir2 = snapshot_wdir(modified + added) | |
95 |
|
|
107 | cmdline = ('%s %s %s %s' % | |
96 | (diffcmd, ' '.join(opts['option']), dir1, dir2), |
|
108 | (util.shellquote(diffcmd), | |
97 | cwd=tmproot) |
|
109 | ' '.join(map(util.shellquote, diffopts)), | |
|
110 | util.shellquote(dir1), util.shellquote(dir2))) | |||
|
111 | ui.debug('running %r in %s\n' % (cmdline, tmproot)) | |||
|
112 | util.system(cmdline, cwd=tmproot) | |||
98 | return 1 |
|
113 | return 1 | |
99 | finally: |
|
114 | finally: | |
100 | ui.note(_('cleaning up temp directory\n')) |
|
115 | ui.note(_('cleaning up temp directory\n')) | |
@@ -104,7 +119,9 b' def extdiff(ui, repo, *pats, **opts):' | |||||
104 | '''use external program to diff repository (or selected files) |
|
119 | '''use external program to diff repository (or selected files) | |
105 |
|
120 | |||
106 | Show differences between revisions for the specified files, using |
|
121 | Show differences between revisions for the specified files, using | |
107 |
an external program. The default program used is |
|
122 | an external program. The default program used is diff, with | |
|
123 | default options "-Npru". | |||
|
124 | ||||
108 | To select a different program, use the -p option. The program |
|
125 | To select a different program, use the -p option. The program | |
109 | will be passed the names of two directories to compare. To pass |
|
126 | will be passed the names of two directories to compare. To pass | |
110 | additional options to the program, use the -o option. These will |
|
127 | additional options to the program, use the -o option. These will | |
@@ -115,7 +132,8 b' def extdiff(ui, repo, *pats, **opts):' | |||||
115 | specified then that revision is compared to the working |
|
132 | specified then that revision is compared to the working | |
116 | directory, and, when no revisions are specified, the |
|
133 | directory, and, when no revisions are specified, the | |
117 | working directory files are compared to its parent.''' |
|
134 | working directory files are compared to its parent.''' | |
118 |
return dodiff(ui, repo, opts['program'] or 'diff |
|
135 | return dodiff(ui, repo, opts['program'] or 'diff', | |
|
136 | opts['option'] or ['-Npru'], pats, opts) | |||
119 |
|
137 | |||
120 | cmdtable = { |
|
138 | cmdtable = { | |
121 | "extdiff": |
|
139 | "extdiff": | |
@@ -133,21 +151,25 b' def uisetup(ui):' | |||||
133 | if not cmd.startswith('cmd.'): continue |
|
151 | if not cmd.startswith('cmd.'): continue | |
134 | cmd = cmd[4:] |
|
152 | cmd = cmd[4:] | |
135 | if not path: path = cmd |
|
153 | if not path: path = cmd | |
136 | def save(cmd, path): |
|
154 | diffopts = ui.config('extdiff', 'opts.' + cmd, '') | |
|
155 | diffopts = diffopts and [diffopts] or [] | |||
|
156 | def save(cmd, path, diffopts): | |||
137 | '''use closure to save diff command to use''' |
|
157 | '''use closure to save diff command to use''' | |
138 | def mydiff(ui, repo, *pats, **opts): |
|
158 | def mydiff(ui, repo, *pats, **opts): | |
139 | return dodiff(ui, repo, path, pats, opts) |
|
159 | return dodiff(ui, repo, path, diffopts, pats, opts) | |
140 |
mydiff.__doc__ = '''use % |
|
160 | mydiff.__doc__ = '''use %(path)r to diff repository (or selected files) | |
141 |
|
161 | |||
142 | Show differences between revisions for the specified |
|
162 | Show differences between revisions for the specified | |
143 |
files, using the % |
|
163 | files, using the %(path)r program. | |
144 |
|
164 | |||
145 | When two revision arguments are given, then changes are |
|
165 | When two revision arguments are given, then changes are | |
146 | shown between those revisions. If only one revision is |
|
166 | shown between those revisions. If only one revision is | |
147 | specified then that revision is compared to the working |
|
167 | specified then that revision is compared to the working | |
148 | directory, and, when no revisions are specified, the |
|
168 | directory, and, when no revisions are specified, the | |
149 |
working directory files are compared to its parent.''' % |
|
169 | working directory files are compared to its parent.''' % { | |
|
170 | 'path': path, | |||
|
171 | } | |||
150 | return mydiff |
|
172 | return mydiff | |
151 | cmdtable[cmd] = (save(cmd, path), |
|
173 | cmdtable[cmd] = (save(cmd, path, diffopts), | |
152 | cmdtable['extdiff'][1][1:], |
|
174 | cmdtable['extdiff'][1][1:], | |
153 | _('hg %s [OPT]... [FILE]...') % cmd) |
|
175 | _('hg %s [OPT]... [FILE]...') % cmd) |
@@ -24,13 +24,13 b" def fetch(ui, repo, source='default', **" | |||||
24 | if modheads == 0: |
|
24 | if modheads == 0: | |
25 | return 0 |
|
25 | return 0 | |
26 | if modheads == 1: |
|
26 | if modheads == 1: | |
27 |
return hg. |
|
27 | return hg.clean(repo, repo.changelog.tip(), wlock=wlock) | |
28 | newheads = repo.heads(parent) |
|
28 | newheads = repo.heads(parent) | |
29 | newchildren = [n for n in repo.heads(parent) if n != parent] |
|
29 | newchildren = [n for n in repo.heads(parent) if n != parent] | |
30 | newparent = parent |
|
30 | newparent = parent | |
31 | if newchildren: |
|
31 | if newchildren: | |
32 | newparent = newchildren[0] |
|
32 | newparent = newchildren[0] | |
33 |
hg. |
|
33 | hg.clean(repo, newparent, wlock=wlock) | |
34 | newheads = [n for n in repo.heads() if n != newparent] |
|
34 | newheads = [n for n in repo.heads() if n != newparent] | |
35 | err = False |
|
35 | err = False | |
36 | if newheads: |
|
36 | if newheads: |
@@ -221,7 +221,7 b' def sign(ui, repo, *revs, **opts):' | |||||
221 | repo.opener("localsigs", "ab").write(sigmessage) |
|
221 | repo.opener("localsigs", "ab").write(sigmessage) | |
222 | return |
|
222 | return | |
223 |
|
223 | |||
224 |
for x in repo. |
|
224 | for x in repo.status()[:5]: | |
225 | if ".hgsigs" in x and not opts["force"]: |
|
225 | if ".hgsigs" in x and not opts["force"]: | |
226 | raise util.Abort(_("working copy of .hgsigs is changed " |
|
226 | raise util.Abort(_("working copy of .hgsigs is changed " | |
227 | "(please commit .hgsigs manually " |
|
227 | "(please commit .hgsigs manually " |
@@ -23,10 +23,10 b' def lookup_rev(ui, repo, rev=None):' | |||||
23 | return parents.pop() |
|
23 | return parents.pop() | |
24 |
|
24 | |||
25 | def check_clean(ui, repo): |
|
25 | def check_clean(ui, repo): | |
26 |
|
|
26 | modified, added, removed, deleted, unknown = repo.status()[:5] | |
27 |
|
|
27 | if modified or added or removed: | |
28 |
|
|
28 | ui.warn("Repository is not clean, please commit or revert\n") | |
29 |
|
|
29 | sys.exit(1) | |
30 |
|
30 | |||
31 | class bisect(object): |
|
31 | class bisect(object): | |
32 | """dichotomic search in the DAG of changesets""" |
|
32 | """dichotomic search in the DAG of changesets""" |
@@ -1,12 +1,13 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. | |
7 |
|
7 | |||
8 | import time, sys, signal, os |
|
8 | from mercurial.demandload import * | |
9 | from mercurial import hg, mdiff, fancyopts, commands, ui, util |
|
9 | demandload(globals(), 'time sys signal os') | |
|
10 | demandload(globals(), 'mercurial:hg,mdiff,fancyopts,commands,ui,util') | |||
10 |
|
11 | |||
11 | def dodiff(fp, ui, repo, node1, node2, files=None, match=util.always, |
|
12 | def dodiff(fp, ui, repo, node1, node2, files=None, match=util.always, | |
12 | changes=None, text=False): |
|
13 | changes=None, text=False): | |
@@ -14,7 +15,7 b' def dodiff(fp, ui, repo, node1, node2, f' | |||||
14 | return time.asctime(time.gmtime(c[2][0])) |
|
15 | return time.asctime(time.gmtime(c[2][0])) | |
15 |
|
16 | |||
16 | if not changes: |
|
17 | if not changes: | |
17 |
changes = repo. |
|
18 | changes = repo.status(node1, node2, files, match=match)[:5] | |
18 | modified, added, removed, deleted, unknown = changes |
|
19 | modified, added, removed, deleted, unknown = changes | |
19 | if files: |
|
20 | if files: | |
20 | modified, added, removed = map(lambda x: filterfiles(files, x), |
|
21 | modified, added, removed = map(lambda x: filterfiles(files, x), | |
@@ -67,12 +68,12 b' def difftree(ui, repo, node1=None, node2' | |||||
67 | if node2: |
|
68 | if node2: | |
68 | change = repo.changelog.read(node2) |
|
69 | change = repo.changelog.read(node2) | |
69 | mmap2 = repo.manifest.read(change[0]) |
|
70 | mmap2 = repo.manifest.read(change[0]) | |
70 |
modified, added, removed, deleted, unknown = repo. |
|
71 | modified, added, removed, deleted, unknown = repo.status(node1, node2)[:5] | |
71 | def read(f): return repo.file(f).read(mmap2[f]) |
|
72 | def read(f): return repo.file(f).read(mmap2[f]) | |
72 | date2 = date(change) |
|
73 | date2 = date(change) | |
73 | else: |
|
74 | else: | |
74 | date2 = time.asctime() |
|
75 | date2 = time.asctime() | |
75 |
modified, added, removed, deleted, unknown = repo. |
|
76 | modified, added, removed, deleted, unknown = repo.status(node1)[:5] | |
76 | if not node1: |
|
77 | if not node1: | |
77 | node1 = repo.dirstate.parents()[0] |
|
78 | node1 = repo.dirstate.parents()[0] | |
78 | def read(f): return file(os.path.join(repo.root, f)).read() |
|
79 | def read(f): return file(os.path.join(repo.root, f)).read() |
@@ -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,10 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 | from mercurial import commands | |||
34 | demandload(globals(), "os sys re struct traceback errno bz2") |
|
35 | demandload(globals(), "os sys re struct traceback errno bz2") | |
35 | from mercurial.i18n import gettext as _ |
|
36 | demandload(globals(), "mercurial:cmdutil,hg,patch,revlog,ui,util") | |
36 | from mercurial import ui, hg, revlog, commands, util |
|
|||
37 |
|
37 | |||
38 | commands.norepo += " qclone qversion" |
|
38 | commands.norepo += " qclone qversion" | |
39 |
|
39 | |||
@@ -66,6 +66,7 b' class queue:' | |||||
66 | self.guards_path = "guards" |
|
66 | self.guards_path = "guards" | |
67 | self.active_guards = None |
|
67 | self.active_guards = None | |
68 | self.guards_dirty = False |
|
68 | self.guards_dirty = False | |
|
69 | self._diffopts = None | |||
69 |
|
70 | |||
70 | if os.path.exists(self.join(self.series_path)): |
|
71 | if os.path.exists(self.join(self.series_path)): | |
71 | self.full_series = self.opener(self.series_path).read().splitlines() |
|
72 | self.full_series = self.opener(self.series_path).read().splitlines() | |
@@ -75,6 +76,11 b' class queue:' | |||||
75 | lines = self.opener(self.status_path).read().splitlines() |
|
76 | lines = self.opener(self.status_path).read().splitlines() | |
76 | self.applied = [statusentry(l) for l in lines] |
|
77 | self.applied = [statusentry(l) for l in lines] | |
77 |
|
78 | |||
|
79 | def diffopts(self): | |||
|
80 | if self._diffopts is None: | |||
|
81 | self._diffopts = patch.diffopts(self.ui) | |||
|
82 | return self._diffopts | |||
|
83 | ||||
78 | def join(self, *p): |
|
84 | def join(self, *p): | |
79 | return os.path.join(self.path, *p) |
|
85 | return os.path.join(self.path, *p) | |
80 |
|
86 | |||
@@ -176,11 +182,11 b' class queue:' | |||||
176 | if exactneg: |
|
182 | if exactneg: | |
177 | return False, exactneg[0] |
|
183 | return False, exactneg[0] | |
178 | pos = [g for g in patchguards if g[0] == '+'] |
|
184 | pos = [g for g in patchguards if g[0] == '+'] | |
179 |
|
|
185 | exactpos = [g for g in pos if g[1:] in guards] | |
180 | if pos: |
|
186 | if pos: | |
181 |
if |
|
187 | if exactpos: | |
182 |
return True, |
|
188 | return True, exactpos[0] | |
183 |
return False, |
|
189 | return False, pos | |
184 | return True, '' |
|
190 | return True, '' | |
185 |
|
191 | |||
186 | def explain_pushable(self, idx, all_patches=False): |
|
192 | def explain_pushable(self, idx, all_patches=False): | |
@@ -247,6 +253,9 b' class queue:' | |||||
247 |
|
253 | |||
248 | for line in file(pf): |
|
254 | for line in file(pf): | |
249 | line = line.rstrip() |
|
255 | line = line.rstrip() | |
|
256 | if line.startswith('diff --git'): | |||
|
257 | diffstart = 2 | |||
|
258 | break | |||
250 | if diffstart: |
|
259 | if diffstart: | |
251 | if line.startswith('+++ '): |
|
260 | if line.startswith('+++ '): | |
252 | diffstart = 2 |
|
261 | diffstart = 2 | |
@@ -292,6 +301,13 b' class queue:' | |||||
292 | message.insert(0, subject) |
|
301 | message.insert(0, subject) | |
293 | return (message, comments, user, date, diffstart > 1) |
|
302 | return (message, comments, user, date, diffstart > 1) | |
294 |
|
303 | |||
|
304 | def printdiff(self, repo, node1, node2=None, files=None, | |||
|
305 | fp=None, changes=None, opts={}): | |||
|
306 | fns, matchfn, anypats = cmdutil.matchpats(repo, files, opts) | |||
|
307 | ||||
|
308 | patch.diff(repo, node1, node2, fns, match=matchfn, | |||
|
309 | fp=fp, changes=changes, opts=self.diffopts()) | |||
|
310 | ||||
295 | def mergeone(self, repo, mergeq, head, patch, rev, wlock): |
|
311 | def mergeone(self, repo, mergeq, head, patch, rev, wlock): | |
296 | # first try just applying the patch |
|
312 | # first try just applying the patch | |
297 | (err, n) = self.apply(repo, [ patch ], update_status=False, |
|
313 | (err, n) = self.apply(repo, [ patch ], update_status=False, | |
@@ -325,7 +341,7 b' class queue:' | |||||
325 | if comments: |
|
341 | if comments: | |
326 | comments = "\n".join(comments) + '\n\n' |
|
342 | comments = "\n".join(comments) + '\n\n' | |
327 | patchf.write(comments) |
|
343 | patchf.write(comments) | |
328 | commands.dodiff(patchf, self.ui, repo, head, n) |
|
344 | self.printdiff(repo, head, n, fp=patchf) | |
329 | patchf.close() |
|
345 | patchf.close() | |
330 | return (0, n) |
|
346 | return (0, n) | |
331 |
|
347 | |||
@@ -390,39 +406,15 b' class queue:' | |||||
390 | '''Apply patchfile to the working directory. |
|
406 | '''Apply patchfile to the working directory. | |
391 | patchfile: file name of patch''' |
|
407 | patchfile: file name of patch''' | |
392 | try: |
|
408 | try: | |
393 | pp = util.find_in_path('gpatch', os.environ.get('PATH', ''), 'patch') |
|
409 | (files, fuzz) = patch.patch(patchfile, self.ui, strip=1, | |
394 | f = os.popen("%s -d %s -p1 --no-backup-if-mismatch < %s" % |
|
410 | cwd=repo.root) | |
395 | (pp, util.shellquote(repo.root), util.shellquote(patchfile))) |
|
411 | except Exception, inst: | |
396 | except: |
|
412 | self.ui.note(str(inst) + '\n') | |
397 | self.ui.warn("patch failed, unable to continue (try -v)\n") |
|
413 | if not self.ui.verbose: | |
398 | return (None, [], False) |
|
414 | self.ui.warn("patch failed, unable to continue (try -v)\n") | |
399 | files = [] |
|
415 | return (False, [], False) | |
400 | fuzz = False |
|
|||
401 | for l in f: |
|
|||
402 | l = l.rstrip('\r\n'); |
|
|||
403 | if self.ui.verbose: |
|
|||
404 | self.ui.warn(l + "\n") |
|
|||
405 | if l[:14] == 'patching file ': |
|
|||
406 | pf = os.path.normpath(util.parse_patch_output(l)) |
|
|||
407 | if pf not in files: |
|
|||
408 | files.append(pf) |
|
|||
409 | printed_file = False |
|
|||
410 | file_str = l |
|
|||
411 | elif l.find('with fuzz') >= 0: |
|
|||
412 | if not printed_file: |
|
|||
413 | self.ui.warn(file_str + '\n') |
|
|||
414 | printed_file = True |
|
|||
415 | self.ui.warn(l + '\n') |
|
|||
416 | fuzz = True |
|
|||
417 | elif l.find('saving rejects to file') >= 0: |
|
|||
418 | self.ui.warn(l + '\n') |
|
|||
419 | elif l.find('FAILED') >= 0: |
|
|||
420 | if not printed_file: |
|
|||
421 | self.ui.warn(file_str + '\n') |
|
|||
422 | printed_file = True |
|
|||
423 | self.ui.warn(l + '\n') |
|
|||
424 |
|
416 | |||
425 |
return ( |
|
417 | return (True, files, fuzz) | |
426 |
|
418 | |||
427 | def apply(self, repo, series, list=False, update_status=True, |
|
419 | def apply(self, repo, series, list=False, update_status=True, | |
428 | strict=False, patchdir=None, merge=None, wlock=None): |
|
420 | strict=False, patchdir=None, merge=None, wlock=None): | |
@@ -435,43 +427,37 b' class queue:' | |||||
435 | lock = repo.lock() |
|
427 | lock = repo.lock() | |
436 | tr = repo.transaction() |
|
428 | tr = repo.transaction() | |
437 | n = None |
|
429 | n = None | |
438 | for patch in series: |
|
430 | for patchname in series: | |
439 | pushable, reason = self.pushable(patch) |
|
431 | pushable, reason = self.pushable(patchname) | |
440 | if not pushable: |
|
432 | if not pushable: | |
441 | self.explain_pushable(patch, all_patches=True) |
|
433 | self.explain_pushable(patchname, all_patches=True) | |
442 | continue |
|
434 | continue | |
443 | self.ui.warn("applying %s\n" % patch) |
|
435 | self.ui.warn("applying %s\n" % patchname) | |
444 | pf = os.path.join(patchdir, patch) |
|
436 | pf = os.path.join(patchdir, patchname) | |
445 |
|
437 | |||
446 | try: |
|
438 | try: | |
447 | message, comments, user, date, patchfound = self.readheaders(patch) |
|
439 | message, comments, user, date, patchfound = self.readheaders(patchname) | |
448 | except: |
|
440 | except: | |
449 |
self.ui.warn("Unable to read %s\n" % p |
|
441 | self.ui.warn("Unable to read %s\n" % patchname) | |
450 | err = 1 |
|
442 | err = 1 | |
451 | break |
|
443 | break | |
452 |
|
444 | |||
453 | if not message: |
|
445 | if not message: | |
454 | message = "imported patch %s\n" % patch |
|
446 | message = "imported patch %s\n" % patchname | |
455 | else: |
|
447 | else: | |
456 | if list: |
|
448 | if list: | |
457 | message.append("\nimported patch %s" % patch) |
|
449 | message.append("\nimported patch %s" % patchname) | |
458 | message = '\n'.join(message) |
|
450 | message = '\n'.join(message) | |
459 |
|
451 | |||
460 | (patcherr, files, fuzz) = self.patch(repo, pf) |
|
452 | (patcherr, files, fuzz) = self.patch(repo, pf) | |
461 | patcherr = not patcherr |
|
453 | patcherr = not patcherr | |
462 |
|
454 | |||
463 |
if merge and |
|
455 | if merge and files: | |
464 | # Mark as merged and update dirstate parent info |
|
456 | # Mark as merged and update dirstate parent info | |
465 | repo.dirstate.update(repo.dirstate.filterfiles(files), 'm') |
|
457 | repo.dirstate.update(repo.dirstate.filterfiles(files.keys()), 'm') | |
466 | p1, p2 = repo.dirstate.parents() |
|
458 | p1, p2 = repo.dirstate.parents() | |
467 | repo.dirstate.setparents(p1, merge) |
|
459 | repo.dirstate.setparents(p1, merge) | |
468 | if len(files) > 0: |
|
460 | files = patch.updatedir(self.ui, repo, files, wlock=wlock) | |
469 | cwd = repo.getcwd() |
|
|||
470 | cfiles = files |
|
|||
471 | if cwd: |
|
|||
472 | cfiles = [util.pathto(cwd, f) for f in files] |
|
|||
473 | commands.addremove_lock(self.ui, repo, cfiles, |
|
|||
474 | opts={}, wlock=wlock) |
|
|||
475 | n = repo.commit(files, message, user, date, force=1, lock=lock, |
|
461 | n = repo.commit(files, message, user, date, force=1, lock=lock, | |
476 | wlock=wlock) |
|
462 | wlock=wlock) | |
477 |
|
463 | |||
@@ -479,11 +465,11 b' class queue:' | |||||
479 | raise util.Abort(_("repo commit failed")) |
|
465 | raise util.Abort(_("repo commit failed")) | |
480 |
|
466 | |||
481 | if update_status: |
|
467 | if update_status: | |
482 | self.applied.append(statusentry(revlog.hex(n), patch)) |
|
468 | self.applied.append(statusentry(revlog.hex(n), patchname)) | |
483 |
|
469 | |||
484 | if patcherr: |
|
470 | if patcherr: | |
485 | if not patchfound: |
|
471 | if not patchfound: | |
486 | self.ui.warn("patch %s is empty\n" % patch) |
|
472 | self.ui.warn("patch %s is empty\n" % patchname) | |
487 | err = 0 |
|
473 | err = 0 | |
488 | else: |
|
474 | else: | |
489 | self.ui.warn("patch failed, rejects left in working dir\n") |
|
475 | self.ui.warn("patch failed, rejects left in working dir\n") | |
@@ -497,21 +483,28 b' class queue:' | |||||
497 | tr.close() |
|
483 | tr.close() | |
498 | return (err, n) |
|
484 | return (err, n) | |
499 |
|
485 | |||
500 |
def delete(self, repo, patch, |
|
486 | def delete(self, repo, patches, keep=False): | |
501 | patch = self.lookup(patch, strict=True) |
|
487 | realpatches = [] | |
502 | info = self.isapplied(patch) |
|
488 | for patch in patches: | |
503 | if info: |
|
489 | patch = self.lookup(patch, strict=True) | |
504 | raise util.Abort(_("cannot delete applied patch %s") % patch) |
|
490 | info = self.isapplied(patch) | |
505 | if patch not in self.series: |
|
491 | if info: | |
506 |
raise util.Abort(_("patch %s |
|
492 | raise util.Abort(_("cannot delete applied patch %s") % patch) | |
507 | if force: |
|
493 | if patch not in self.series: | |
|
494 | raise util.Abort(_("patch %s not in series file") % patch) | |||
|
495 | realpatches.append(patch) | |||
|
496 | ||||
|
497 | if not keep: | |||
508 | r = self.qrepo() |
|
498 | r = self.qrepo() | |
509 | if r: |
|
499 | if r: | |
510 |
r.remove( |
|
500 | r.remove(realpatches, True) | |
511 | else: |
|
501 | else: | |
512 | os.unlink(self.join(patch)) |
|
502 | os.unlink(self.join(patch)) | |
513 | i = self.find_series(patch) |
|
503 | ||
514 | del self.full_series[i] |
|
504 | indices = [self.find_series(p) for p in realpatches] | |
|
505 | indices.sort() | |||
|
506 | for i in indices[-1::-1]: | |||
|
507 | del self.full_series[i] | |||
515 | self.parse_series() |
|
508 | self.parse_series() | |
516 | self.series_dirty = 1 |
|
509 | self.series_dirty = 1 | |
517 |
|
510 | |||
@@ -523,19 +516,20 b' class queue:' | |||||
523 | raise util.Abort(_("queue top not at same revision as working directory")) |
|
516 | raise util.Abort(_("queue top not at same revision as working directory")) | |
524 | return top |
|
517 | return top | |
525 | return None |
|
518 | return None | |
526 | def check_localchanges(self, repo): |
|
519 | def check_localchanges(self, repo, force=False, refresh=True): | |
527 |
|
|
520 | m, a, r, d = repo.status()[:4] | |
528 |
if |
|
521 | if m or a or r or d: | |
529 | raise util.Abort(_("local changes found, refresh first")) |
|
522 | if not force: | |
|
523 | if refresh: | |||
|
524 | raise util.Abort(_("local changes found, refresh first")) | |||
|
525 | else: | |||
|
526 | raise util.Abort(_("local changes found")) | |||
|
527 | return m, a, r, d | |||
530 | def new(self, repo, patch, msg=None, force=None): |
|
528 | def new(self, repo, patch, msg=None, force=None): | |
531 | if os.path.exists(self.join(patch)): |
|
529 | if os.path.exists(self.join(patch)): | |
532 | raise util.Abort(_('patch "%s" already exists') % patch) |
|
530 | raise util.Abort(_('patch "%s" already exists') % patch) | |
533 | commitfiles = [] |
|
531 | m, a, r, d = self.check_localchanges(repo, force) | |
534 | (c, a, r, d, u) = repo.changes(None, None) |
|
532 | commitfiles = m + a + r | |
535 | if c or a or d or r: |
|
|||
536 | if not force: |
|
|||
537 | raise util.Abort(_("local changes found, refresh first")) |
|
|||
538 | commitfiles = c + a + r |
|
|||
539 | self.check_toppatch(repo) |
|
533 | self.check_toppatch(repo) | |
540 | wlock = repo.wlock() |
|
534 | wlock = repo.wlock() | |
541 | insert = self.full_series_end() |
|
535 | insert = self.full_series_end() | |
@@ -561,7 +555,7 b' class queue:' | |||||
561 | r = self.qrepo() |
|
555 | r = self.qrepo() | |
562 | if r: r.add([patch]) |
|
556 | if r: r.add([patch]) | |
563 | if commitfiles: |
|
557 | if commitfiles: | |
564 |
self.refresh(repo, |
|
558 | self.refresh(repo, short=True) | |
565 |
|
559 | |||
566 | def strip(self, repo, rev, update=True, backup="all", wlock=None): |
|
560 | def strip(self, repo, rev, update=True, backup="all", wlock=None): | |
567 | def limitheads(chlog, stop): |
|
561 | def limitheads(chlog, stop): | |
@@ -649,9 +643,7 b' class queue:' | |||||
649 | revnum = chlog.rev(rev) |
|
643 | revnum = chlog.rev(rev) | |
650 |
|
644 | |||
651 | if update: |
|
645 | if update: | |
652 | (c, a, r, d, u) = repo.changes(None, None) |
|
646 | self.check_localchanges(repo, refresh=False) | |
653 | if c or a or d or r: |
|
|||
654 | raise util.Abort(_("local changes found")) |
|
|||
655 | urev = self.qparents(repo, rev) |
|
647 | urev = self.qparents(repo, rev) | |
656 | hg.clean(repo, urev, wlock=wlock) |
|
648 | hg.clean(repo, urev, wlock=wlock) | |
657 | repo.dirstate.write() |
|
649 | repo.dirstate.write() | |
@@ -725,6 +717,8 b' class queue:' | |||||
725 | # 2) a unique substring of the patch name was given |
|
717 | # 2) a unique substring of the patch name was given | |
726 | # 3) patchname[-+]num to indicate an offset in the series file |
|
718 | # 3) patchname[-+]num to indicate an offset in the series file | |
727 | def lookup(self, patch, strict=False): |
|
719 | def lookup(self, patch, strict=False): | |
|
720 | patch = patch and str(patch) | |||
|
721 | ||||
728 | def partial_name(s): |
|
722 | def partial_name(s): | |
729 | if s in self.series: |
|
723 | if s in self.series: | |
730 | return s |
|
724 | return s | |
@@ -886,17 +880,16 b' class queue:' | |||||
886 | top = self.check_toppatch(repo) |
|
880 | top = self.check_toppatch(repo) | |
887 | qp = self.qparents(repo, rev) |
|
881 | qp = self.qparents(repo, rev) | |
888 | changes = repo.changelog.read(qp) |
|
882 | changes = repo.changelog.read(qp) | |
889 | mf1 = repo.manifest.readflags(changes[0]) |
|
|||
890 | mmap = repo.manifest.read(changes[0]) |
|
883 | mmap = repo.manifest.read(changes[0]) | |
891 |
|
|
884 | m, a, r, d, u = repo.status(qp, top)[:5] | |
892 | if d: |
|
885 | if d: | |
893 | raise util.Abort("deletions found between repo revs") |
|
886 | raise util.Abort("deletions found between repo revs") | |
894 |
for f in |
|
887 | for f in m: | |
895 | getfile(f, mmap[f]) |
|
888 | getfile(f, mmap[f]) | |
896 | for f in r: |
|
889 | for f in r: | |
897 | getfile(f, mmap[f]) |
|
890 | getfile(f, mmap[f]) | |
898 |
util.set_exec(repo.wjoin(f), m |
|
891 | util.set_exec(repo.wjoin(f), mmap.execf(f)) | |
899 |
repo.dirstate.update( |
|
892 | repo.dirstate.update(m + r, 'n') | |
900 | for f in a: |
|
893 | for f in a: | |
901 | try: os.unlink(repo.wjoin(f)) |
|
894 | try: os.unlink(repo.wjoin(f)) | |
902 | except: raise |
|
895 | except: raise | |
@@ -912,15 +905,15 b' class queue:' | |||||
912 | else: |
|
905 | else: | |
913 | self.ui.write("Patch queue now empty\n") |
|
906 | self.ui.write("Patch queue now empty\n") | |
914 |
|
907 | |||
915 |
def diff(self, repo, |
|
908 | def diff(self, repo, pats, opts): | |
916 | top = self.check_toppatch(repo) |
|
909 | top = self.check_toppatch(repo) | |
917 | if not top: |
|
910 | if not top: | |
918 | self.ui.write("No patches applied\n") |
|
911 | self.ui.write("No patches applied\n") | |
919 | return |
|
912 | return | |
920 | qp = self.qparents(repo, top) |
|
913 | qp = self.qparents(repo, top) | |
921 | commands.dodiff(sys.stdout, self.ui, repo, qp, None, files) |
|
914 | self.printdiff(repo, qp, files=pats, opts=opts) | |
922 |
|
915 | |||
923 |
def refresh(self, repo, |
|
916 | def refresh(self, repo, pats=None, **opts): | |
924 | if len(self.applied) == 0: |
|
917 | if len(self.applied) == 0: | |
925 | self.ui.write("No patches applied\n") |
|
918 | self.ui.write("No patches applied\n") | |
926 | return |
|
919 | return | |
@@ -933,7 +926,7 b' class queue:' | |||||
933 | message, comments, user, date, patchfound = self.readheaders(patch) |
|
926 | message, comments, user, date, patchfound = self.readheaders(patch) | |
934 |
|
927 | |||
935 | patchf = self.opener(patch, "w") |
|
928 | patchf = self.opener(patch, "w") | |
936 | msg = msg.rstrip() |
|
929 | msg = opts.get('msg', '').rstrip() | |
937 | if msg: |
|
930 | if msg: | |
938 | if comments: |
|
931 | if comments: | |
939 | # Remove existing message. |
|
932 | # Remove existing message. | |
@@ -947,6 +940,7 b' class queue:' | |||||
947 | comments = "\n".join(comments) + '\n\n' |
|
940 | comments = "\n".join(comments) + '\n\n' | |
948 | patchf.write(comments) |
|
941 | patchf.write(comments) | |
949 |
|
942 | |||
|
943 | fns, matchfn, anypats = cmdutil.matchpats(repo, pats, opts) | |||
950 | tip = repo.changelog.tip() |
|
944 | tip = repo.changelog.tip() | |
951 | if top == tip: |
|
945 | if top == tip: | |
952 | # if the top of our patch queue is also the tip, there is an |
|
946 | # if the top of our patch queue is also the tip, there is an | |
@@ -959,30 +953,30 b' class queue:' | |||||
959 | # patch already |
|
953 | # patch already | |
960 | # |
|
954 | # | |
961 | # this should really read: |
|
955 | # this should really read: | |
962 |
# |
|
956 | # mm, dd, aa, aa2, uu = repo.status(tip, patchparent)[:5] | |
963 | # but we do it backwards to take advantage of manifest/chlog |
|
957 | # but we do it backwards to take advantage of manifest/chlog | |
964 |
# caching against the next repo. |
|
958 | # caching against the next repo.status call | |
965 | # |
|
959 | # | |
966 |
|
|
960 | mm, aa, dd, aa2, uu = repo.status(patchparent, tip)[:5] | |
967 | if short: |
|
961 | if opts.get('short'): | |
968 |
filelist = |
|
962 | filelist = mm + aa + dd | |
969 | else: |
|
963 | else: | |
970 | filelist = None |
|
964 | filelist = None | |
971 |
|
|
965 | m, a, r, d, u = repo.status(files=filelist)[:5] | |
972 |
|
966 | |||
973 | # we might end up with files that were added between tip and |
|
967 | # we might end up with files that were added between tip and | |
974 | # the dirstate parent, but then changed in the local dirstate. |
|
968 | # the dirstate parent, but then changed in the local dirstate. | |
975 | # in this case, we want them to only show up in the added section |
|
969 | # in this case, we want them to only show up in the added section | |
976 |
for x in |
|
970 | for x in m: | |
977 | if x not in aa: |
|
971 | if x not in aa: | |
978 |
|
|
972 | mm.append(x) | |
979 | # we might end up with files added by the local dirstate that |
|
973 | # we might end up with files added by the local dirstate that | |
980 | # were deleted by the patch. In this case, they should only |
|
974 | # were deleted by the patch. In this case, they should only | |
981 | # show up in the changed section. |
|
975 | # show up in the changed section. | |
982 | for x in a: |
|
976 | for x in a: | |
983 | if x in dd: |
|
977 | if x in dd: | |
984 | del dd[dd.index(x)] |
|
978 | del dd[dd.index(x)] | |
985 |
|
|
979 | mm.append(x) | |
986 | else: |
|
980 | else: | |
987 | aa.append(x) |
|
981 | aa.append(x) | |
988 | # make sure any files deleted in the local dirstate |
|
982 | # make sure any files deleted in the local dirstate | |
@@ -993,23 +987,34 b' class queue:' | |||||
993 | del aa[aa.index(x)] |
|
987 | del aa[aa.index(x)] | |
994 | forget.append(x) |
|
988 | forget.append(x) | |
995 | continue |
|
989 | continue | |
996 |
elif x in |
|
990 | elif x in mm: | |
997 |
del |
|
991 | del mm[mm.index(x)] | |
998 | dd.append(x) |
|
992 | dd.append(x) | |
999 |
|
993 | |||
1000 |
|
|
994 | m = list(util.unique(mm)) | |
1001 | r = list(util.unique(dd)) |
|
995 | r = list(util.unique(dd)) | |
1002 | a = list(util.unique(aa)) |
|
996 | a = list(util.unique(aa)) | |
1003 |
filelist = |
|
997 | filelist = filter(matchfn, util.unique(m + r + a)) | |
1004 |
|
|
998 | self.printdiff(repo, patchparent, files=filelist, | |
1005 |
|
|
999 | changes=(m, a, r, [], u), fp=patchf) | |
1006 | patchf.close() |
|
1000 | patchf.close() | |
1007 |
|
1001 | |||
1008 | changes = repo.changelog.read(tip) |
|
1002 | changes = repo.changelog.read(tip) | |
1009 | repo.dirstate.setparents(*cparents) |
|
1003 | repo.dirstate.setparents(*cparents) | |
|
1004 | copies = [(f, repo.dirstate.copied(f)) for f in a] | |||
1010 | repo.dirstate.update(a, 'a') |
|
1005 | repo.dirstate.update(a, 'a') | |
|
1006 | for dst, src in copies: | |||
|
1007 | repo.dirstate.copy(src, dst) | |||
1011 | repo.dirstate.update(r, 'r') |
|
1008 | repo.dirstate.update(r, 'r') | |
1012 | repo.dirstate.update(c, 'n') |
|
1009 | # if the patch excludes a modified file, mark that file with mtime=0 | |
|
1010 | # so status can see it. | |||
|
1011 | mm = [] | |||
|
1012 | for i in range(len(m)-1, -1, -1): | |||
|
1013 | if not matchfn(m[i]): | |||
|
1014 | mm.append(m[i]) | |||
|
1015 | del m[i] | |||
|
1016 | repo.dirstate.update(m, 'n') | |||
|
1017 | repo.dirstate.update(mm, 'n', st_mtime=0) | |||
1013 | repo.dirstate.forget(forget) |
|
1018 | repo.dirstate.forget(forget) | |
1014 |
|
1019 | |||
1015 | if not msg: |
|
1020 | if not msg: | |
@@ -1025,7 +1030,7 b' class queue:' | |||||
1025 | self.applied[-1] = statusentry(revlog.hex(n), patch) |
|
1030 | self.applied[-1] = statusentry(revlog.hex(n), patch) | |
1026 | self.applied_dirty = 1 |
|
1031 | self.applied_dirty = 1 | |
1027 | else: |
|
1032 | else: | |
1028 |
|
|
1033 | self.printdiff(repo, patchparent, fp=patchf) | |
1029 | patchf.close() |
|
1034 | patchf.close() | |
1030 | self.pop(repo, force=True, wlock=wlock) |
|
1035 | self.pop(repo, force=True, wlock=wlock) | |
1031 | self.push(repo, force=True, wlock=wlock) |
|
1036 | self.push(repo, force=True, wlock=wlock) | |
@@ -1224,7 +1229,7 b' class queue:' | |||||
1224 | if not self.ui.verbose: |
|
1229 | if not self.ui.verbose: | |
1225 | p = pname |
|
1230 | p = pname | |
1226 | else: |
|
1231 | else: | |
1227 | p = str(self.series.index(pname)) + " " + p |
|
1232 | p = str(self.series.index(pname)) + " " + pname | |
1228 | return p |
|
1233 | return p | |
1229 |
|
1234 | |||
1230 | def top(self, repo): |
|
1235 | def top(self, repo): | |
@@ -1291,13 +1296,13 b' class queue:' | |||||
1291 | if qrepo: |
|
1296 | if qrepo: | |
1292 | qrepo.add(added) |
|
1297 | qrepo.add(added) | |
1293 |
|
1298 | |||
1294 | def delete(ui, repo, patch, **opts): |
|
1299 | def delete(ui, repo, patch, *patches, **opts): | |
1295 |
"""remove |
|
1300 | """remove patches from queue | |
1296 |
|
1301 | |||
1297 | The patch must not be applied. |
|
1302 | The patches must not be applied. | |
1298 |
With - |
|
1303 | With -k, the patch files are preserved in the patch directory.""" | |
1299 | q = repo.mq |
|
1304 | q = repo.mq | |
1300 |
q.delete(repo, patch, |
|
1305 | q.delete(repo, (patch,) + patches, keep=opts.get('keep')) | |
1301 | q.save_dirty() |
|
1306 | q.save_dirty() | |
1302 | return 0 |
|
1307 | return 0 | |
1303 |
|
1308 | |||
@@ -1419,17 +1424,24 b' def new(ui, repo, patch, **opts):' | |||||
1419 | changes unless -f is specified, in which case the patch will |
|
1424 | changes unless -f is specified, in which case the patch will | |
1420 | be initialised with them. |
|
1425 | be initialised with them. | |
1421 |
|
1426 | |||
1422 | -m or -l set the patch header as well as the commit message. |
|
1427 | -e, -m or -l set the patch header as well as the commit message. | |
1423 |
If ne |
|
1428 | If none is specified, the patch header is empty and the | |
1424 | commit message is 'New patch: PATCH'""" |
|
1429 | commit message is 'New patch: PATCH'""" | |
1425 | q = repo.mq |
|
1430 | q = repo.mq | |
1426 | message = commands.logmessage(opts) |
|
1431 | message = commands.logmessage(opts) | |
|
1432 | if opts['edit']: | |||
|
1433 | message = ui.edit(message, ui.username()) | |||
1427 | q.new(repo, patch, msg=message, force=opts['force']) |
|
1434 | q.new(repo, patch, msg=message, force=opts['force']) | |
1428 | q.save_dirty() |
|
1435 | q.save_dirty() | |
1429 | return 0 |
|
1436 | return 0 | |
1430 |
|
1437 | |||
1431 | def refresh(ui, repo, **opts): |
|
1438 | def refresh(ui, repo, *pats, **opts): | |
1432 |
"""update the current patch |
|
1439 | """update the current patch | |
|
1440 | ||||
|
1441 | If any file patterns are provided, the refreshed patch will contain only | |||
|
1442 | the modifications that match those patterns; the remaining modifications | |||
|
1443 | will remain in the working directory. | |||
|
1444 | """ | |||
1433 | q = repo.mq |
|
1445 | q = repo.mq | |
1434 | message = commands.logmessage(opts) |
|
1446 | message = commands.logmessage(opts) | |
1435 | if opts['edit']: |
|
1447 | if opts['edit']: | |
@@ -1438,14 +1450,13 b' def refresh(ui, repo, **opts):' | |||||
1438 | patch = q.applied[-1].name |
|
1450 | patch = q.applied[-1].name | |
1439 | (message, comment, user, date, hasdiff) = q.readheaders(patch) |
|
1451 | (message, comment, user, date, hasdiff) = q.readheaders(patch) | |
1440 | message = ui.edit('\n'.join(message), user or ui.username()) |
|
1452 | message = ui.edit('\n'.join(message), user or ui.username()) | |
1441 |
q.refresh(repo, msg=message, |
|
1453 | q.refresh(repo, pats, msg=message, **opts) | |
1442 | q.save_dirty() |
|
1454 | q.save_dirty() | |
1443 | return 0 |
|
1455 | return 0 | |
1444 |
|
1456 | |||
1445 |
def diff(ui, repo, * |
|
1457 | def diff(ui, repo, *pats, **opts): | |
1446 | """diff of the current patch""" |
|
1458 | """diff of the current patch""" | |
1447 | # deep in the dirstate code, the walkhelper method wants a list, not a tuple |
|
1459 | repo.mq.diff(repo, pats, opts) | |
1448 | repo.mq.diff(repo, list(files)) |
|
|||
1449 | return 0 |
|
1460 | return 0 | |
1450 |
|
1461 | |||
1451 | def fold(ui, repo, *files, **opts): |
|
1462 | def fold(ui, repo, *files, **opts): | |
@@ -1455,7 +1466,7 b' def fold(ui, repo, *files, **opts):' | |||||
1455 | applied to the current patch in the order given. If all the |
|
1466 | applied to the current patch in the order given. If all the | |
1456 | patches apply successfully, the current patch will be refreshed |
|
1467 | patches apply successfully, the current patch will be refreshed | |
1457 | with the new cumulative patch, and the folded patches will |
|
1468 | with the new cumulative patch, and the folded patches will | |
1458 |
be deleted. With - |
|
1469 | be deleted. With -k/--keep, the folded patch files will not | |
1459 | be removed afterwards. |
|
1470 | be removed afterwards. | |
1460 |
|
1471 | |||
1461 | The header for each folded patch will be concatenated with |
|
1472 | The header for each folded patch will be concatenated with | |
@@ -1477,20 +1488,21 b' def fold(ui, repo, *files, **opts):' | |||||
1477 | patches = [] |
|
1488 | patches = [] | |
1478 | messages = [] |
|
1489 | messages = [] | |
1479 | for f in files: |
|
1490 | for f in files: | |
1480 |
p |
|
1491 | p = q.lookup(f) | |
1481 |
if p |
|
1492 | if p in patches or p == parent: | |
1482 |
ui.warn(_('Skipping already folded patch %s') % p |
|
1493 | ui.warn(_('Skipping already folded patch %s') % p) | |
1483 |
if q.isapplied(p |
|
1494 | if q.isapplied(p): | |
1484 |
raise util.Abort(_('qfold cannot fold already applied patch %s') % p |
|
1495 | raise util.Abort(_('qfold cannot fold already applied patch %s') % p) | |
1485 |
patches.append(p |
|
1496 | patches.append(p) | |
1486 |
|
1497 | |||
1487 |
for p |
|
1498 | for p in patches: | |
1488 | if not message: |
|
1499 | if not message: | |
1489 |
messages.append(q.readheaders(p |
|
1500 | messages.append(q.readheaders(p)[0]) | |
1490 |
pf = q.join(p |
|
1501 | pf = q.join(p) | |
1491 | (patchsuccess, files, fuzz) = q.patch(repo, pf) |
|
1502 | (patchsuccess, files, fuzz) = q.patch(repo, pf) | |
1492 | if not patchsuccess: |
|
1503 | if not patchsuccess: | |
1493 |
raise util.Abort(_('Error folding patch %s') % p |
|
1504 | raise util.Abort(_('Error folding patch %s') % p) | |
|
1505 | patch.updatedir(ui, repo, files) | |||
1494 |
|
1506 | |||
1495 | if not message: |
|
1507 | if not message: | |
1496 | message, comments, user = q.readheaders(parent)[0:3] |
|
1508 | message, comments, user = q.readheaders(parent)[0:3] | |
@@ -1503,29 +1515,26 b' def fold(ui, repo, *files, **opts):' | |||||
1503 | message = ui.edit(message, user or ui.username()) |
|
1515 | message = ui.edit(message, user or ui.username()) | |
1504 |
|
1516 | |||
1505 | q.refresh(repo, msg=message) |
|
1517 | q.refresh(repo, msg=message) | |
1506 |
|
1518 | q.delete(repo, patches, keep=opts['keep']) | ||
1507 | for patch in patches: |
|
|||
1508 | q.delete(repo, patch, force=opts['force']) |
|
|||
1509 |
|
||||
1510 | q.save_dirty() |
|
1519 | q.save_dirty() | |
1511 |
|
1520 | |||
1512 | def guard(ui, repo, *args, **opts): |
|
1521 | def guard(ui, repo, *args, **opts): | |
1513 | '''set or print guards for a patch |
|
1522 | '''set or print guards for a patch | |
1514 |
|
1523 | |||
1515 |
|
|
1524 | Guards control whether a patch can be pushed. A patch with no | |
1516 |
guards is aways pushed. |
|
1525 | guards is always pushed. A patch with a positive guard ("+foo") is | |
1517 |
pushed only if qselect command |
|
1526 | pushed only if the qselect command has activated it. A patch with | |
1518 |
|
|
1527 | a negative guard ("-foo") is never pushed if the qselect command | |
1519 | guard "foo". |
|
1528 | has activated it. | |
1520 |
|
1529 | |||
1521 |
|
|
1530 | With no arguments, print the currently active guards. | |
1522 |
|
|
1531 | With arguments, set guards for the named patch. | |
1523 |
|
1532 | |||
1524 |
|
|
1533 | To set a negative guard "-foo" on topmost patch ("--" is needed so | |
1525 |
hg will not interpret "-foo" as a |
|
1534 | hg will not interpret "-foo" as an option): | |
1526 | hg qguard -- -foo |
|
1535 | hg qguard -- -foo | |
1527 |
|
1536 | |||
1528 |
|
|
1537 | To set guards on another patch: | |
1529 | hg qguard other.patch +2.6.17 -stable |
|
1538 | hg qguard other.patch +2.6.17 -stable | |
1530 | ''' |
|
1539 | ''' | |
1531 | def status(idx): |
|
1540 | def status(idx): | |
@@ -1731,38 +1740,57 b' def strip(ui, repo, rev, **opts):' | |||||
1731 | def select(ui, repo, *args, **opts): |
|
1740 | def select(ui, repo, *args, **opts): | |
1732 | '''set or print guarded patches to push |
|
1741 | '''set or print guarded patches to push | |
1733 |
|
1742 | |||
1734 |
|
|
1743 | Use the qguard command to set or print guards on patch, then use | |
1735 |
qselect to tell mq which guards to use. |
|
1744 | qselect to tell mq which guards to use. A patch will be pushed if it | |
|
1745 | has no guards or any positive guards match the currently selected guard, | |||
|
1746 | but will not be pushed if any negative guards match the current guard. | |||
|
1747 | For example: | |||
1736 |
|
1748 | |||
1737 |
qguard foo.patch -stable (n |
|
1749 | qguard foo.patch -stable (negative guard) | |
1738 |
qguard bar.patch +stable (pos |
|
1750 | qguard bar.patch +stable (positive guard) | |
1739 | qselect stable |
|
1751 | qselect stable | |
1740 |
|
1752 | |||
1741 |
|
|
1753 | This activates the "stable" guard. mq will skip foo.patch (because | |
1742 |
|
|
1754 | it has a negative match) but push bar.patch (because it | |
1743 | match). patch is pushed only if all posative guards match and no |
|
1755 | has a positive match). | |
1744 | nagative guards match. |
|
|||
1745 |
|
1756 | |||
1746 |
|
|
1757 | With no arguments, prints the currently active guards. | |
1747 |
|
|
1758 | With one argument, sets the active guard. | |
1748 |
|
1759 | |||
1749 |
|
|
1760 | Use -n/--none to deactivate guards (no other arguments needed). | |
1750 |
|
|
1761 | When no guards are active, patches with positive guards are skipped | |
1751 |
patches with n |
|
1762 | and patches with negative guards are pushed. | |
1752 |
|
1763 | |||
1753 | use -s/--series to print list of all guards in series file (no |
|
1764 | qselect can change the guards on applied patches. It does not pop | |
1754 | other arguments needed). use -v for more information.''' |
|
1765 | guarded patches by default. Use --pop to pop back to the last applied | |
|
1766 | patch that is not guarded. Use --reapply (which implies --pop) to push | |||
|
1767 | back to the current patch afterwards, but skip guarded patches. | |||
|
1768 | ||||
|
1769 | Use -s/--series to print a list of all guards in the series file (no | |||
|
1770 | other arguments needed). Use -v for more information.''' | |||
1755 |
|
1771 | |||
1756 | q = repo.mq |
|
1772 | q = repo.mq | |
1757 | guards = q.active() |
|
1773 | guards = q.active() | |
1758 | if args or opts['none']: |
|
1774 | if args or opts['none']: | |
|
1775 | old_unapplied = q.unapplied(repo) | |||
|
1776 | old_guarded = [i for i in xrange(len(q.applied)) if | |||
|
1777 | not q.pushable(i)[0]] | |||
1759 | q.set_active(args) |
|
1778 | q.set_active(args) | |
1760 | q.save_dirty() |
|
1779 | q.save_dirty() | |
1761 | if not args: |
|
1780 | if not args: | |
1762 | ui.status(_('guards deactivated\n')) |
|
1781 | ui.status(_('guards deactivated\n')) | |
1763 | if q.series: |
|
1782 | if not opts['pop'] and not opts['reapply']: | |
1764 | ui.status(_('%d of %d unapplied patches active\n') % |
|
1783 | unapplied = q.unapplied(repo) | |
1765 | (len(q.unapplied(repo)), len(q.series))) |
|
1784 | guarded = [i for i in xrange(len(q.applied)) | |
|
1785 | if not q.pushable(i)[0]] | |||
|
1786 | if len(unapplied) != len(old_unapplied): | |||
|
1787 | ui.status(_('number of unguarded, unapplied patches has ' | |||
|
1788 | 'changed from %d to %d\n') % | |||
|
1789 | (len(old_unapplied), len(unapplied))) | |||
|
1790 | if len(guarded) != len(old_guarded): | |||
|
1791 | ui.status(_('number of guarded, applied patches has changed ' | |||
|
1792 | 'from %d to %d\n') % | |||
|
1793 | (len(old_guarded), len(guarded))) | |||
1766 | elif opts['series']: |
|
1794 | elif opts['series']: | |
1767 | guards = {} |
|
1795 | guards = {} | |
1768 | noguards = 0 |
|
1796 | noguards = 0 | |
@@ -1790,9 +1818,51 b' def select(ui, repo, *args, **opts):' | |||||
1790 | ui.write(g, '\n') |
|
1818 | ui.write(g, '\n') | |
1791 | else: |
|
1819 | else: | |
1792 | ui.write(_('no active guards\n')) |
|
1820 | ui.write(_('no active guards\n')) | |
|
1821 | reapply = opts['reapply'] and q.applied and q.appliedname(-1) | |||
|
1822 | popped = False | |||
|
1823 | if opts['pop'] or opts['reapply']: | |||
|
1824 | for i in xrange(len(q.applied)): | |||
|
1825 | pushable, reason = q.pushable(i) | |||
|
1826 | if not pushable: | |||
|
1827 | ui.status(_('popping guarded patches\n')) | |||
|
1828 | popped = True | |||
|
1829 | if i == 0: | |||
|
1830 | q.pop(repo, all=True) | |||
|
1831 | else: | |||
|
1832 | q.pop(repo, i-1) | |||
|
1833 | break | |||
|
1834 | if popped: | |||
|
1835 | try: | |||
|
1836 | if reapply: | |||
|
1837 | ui.status(_('reapplying unguarded patches\n')) | |||
|
1838 | q.push(repo, reapply) | |||
|
1839 | finally: | |||
|
1840 | q.save_dirty() | |||
1793 |
|
1841 | |||
1794 | def reposetup(ui, repo): |
|
1842 | def reposetup(ui, repo): | |
1795 | class mqrepo(repo.__class__): |
|
1843 | class mqrepo(repo.__class__): | |
|
1844 | def abort_if_wdir_patched(self, errmsg, force=False): | |||
|
1845 | if self.mq.applied and not force: | |||
|
1846 | parent = revlog.hex(self.dirstate.parents()[0]) | |||
|
1847 | if parent in [s.rev for s in self.mq.applied]: | |||
|
1848 | raise util.Abort(errmsg) | |||
|
1849 | ||||
|
1850 | def commit(self, *args, **opts): | |||
|
1851 | if len(args) >= 6: | |||
|
1852 | force = args[5] | |||
|
1853 | else: | |||
|
1854 | force = opts.get('force') | |||
|
1855 | self.abort_if_wdir_patched( | |||
|
1856 | _('cannot commit over an applied mq patch'), | |||
|
1857 | force) | |||
|
1858 | ||||
|
1859 | return super(mqrepo, self).commit(*args, **opts) | |||
|
1860 | ||||
|
1861 | def push(self, remote, force=False, revs=None): | |||
|
1862 | if self.mq.applied and not force: | |||
|
1863 | raise util.Abort(_('source has mq patches applied')) | |||
|
1864 | return super(mqrepo, self).push(remote, force, revs) | |||
|
1865 | ||||
1796 | def tags(self): |
|
1866 | def tags(self): | |
1797 | if self.tagscache: |
|
1867 | if self.tagscache: | |
1798 | return self.tagscache |
|
1868 | return self.tagscache | |
@@ -1814,8 +1884,9 b' def reposetup(ui, repo):' | |||||
1814 |
|
1884 | |||
1815 | return tagscache |
|
1885 | return tagscache | |
1816 |
|
1886 | |||
1817 | repo.__class__ = mqrepo |
|
1887 | if repo.local(): | |
1818 | repo.mq = queue(ui, repo.join("")) |
|
1888 | repo.__class__ = mqrepo | |
|
1889 | repo.mq = queue(ui, repo.join("")) | |||
1819 |
|
1890 | |||
1820 | cmdtable = { |
|
1891 | cmdtable = { | |
1821 | "qapplied": (applied, [], 'hg qapplied [PATCH]'), |
|
1892 | "qapplied": (applied, [], 'hg qapplied [PATCH]'), | |
@@ -1833,15 +1904,18 b' cmdtable = {' | |||||
1833 | (commit, |
|
1904 | (commit, | |
1834 | commands.table["^commit|ci"][1], |
|
1905 | commands.table["^commit|ci"][1], | |
1835 | 'hg qcommit [OPTION]... [FILE]...'), |
|
1906 | 'hg qcommit [OPTION]... [FILE]...'), | |
1836 | "^qdiff": (diff, [], 'hg qdiff [FILE]...'), |
|
1907 | "^qdiff": (diff, | |
1837 | "qdelete": |
|
1908 | [('I', 'include', [], _('include names matching the given patterns')), | |
|
1909 | ('X', 'exclude', [], _('exclude names matching the given patterns'))], | |||
|
1910 | 'hg qdiff [-I] [-X] [FILE]...'), | |||
|
1911 | "qdelete|qremove|qrm": | |||
1838 | (delete, |
|
1912 | (delete, | |
1839 |
[(' |
|
1913 | [('k', 'keep', None, _('keep patch file'))], | |
1840 |
'hg qdelete [- |
|
1914 | 'hg qdelete [-k] PATCH'), | |
1841 | 'qfold': |
|
1915 | 'qfold': | |
1842 | (fold, |
|
1916 | (fold, | |
1843 | [('e', 'edit', None, _('edit patch header')), |
|
1917 | [('e', 'edit', None, _('edit patch header')), | |
1844 |
(' |
|
1918 | ('k', 'keep', None, _('keep folded patch files')), | |
1845 | ('m', 'message', '', _('set patch header to <text>')), |
|
1919 | ('m', 'message', '', _('set patch header to <text>')), | |
1846 | ('l', 'logfile', '', _('set patch header to contents of <file>'))], |
|
1920 | ('l', 'logfile', '', _('set patch header to contents of <file>'))], | |
1847 | 'hg qfold [-e] [-m <text>] [-l <file] PATCH...'), |
|
1921 | 'hg qfold [-e] [-m <text>] [-l <file] PATCH...'), | |
@@ -1862,10 +1936,11 b' cmdtable = {' | |||||
1862 | 'hg qinit [-c]'), |
|
1936 | 'hg qinit [-c]'), | |
1863 | "qnew": |
|
1937 | "qnew": | |
1864 | (new, |
|
1938 | (new, | |
1865 |
[(' |
|
1939 | [('e', 'edit', None, _('edit commit message')), | |
|
1940 | ('m', 'message', '', _('use <text> as commit message')), | |||
1866 | ('l', 'logfile', '', _('read the commit message from <file>')), |
|
1941 | ('l', 'logfile', '', _('read the commit message from <file>')), | |
1867 | ('f', 'force', None, _('import uncommitted changes into patch'))], |
|
1942 | ('f', 'force', None, _('import uncommitted changes into patch'))], | |
1868 | 'hg qnew [-m TEXT] [-l FILE] [-f] PATCH'), |
|
1943 | 'hg qnew [-e] [-m TEXT] [-l FILE] [-f] PATCH'), | |
1869 | "qnext": (next, [], 'hg qnext'), |
|
1944 | "qnext": (next, [], 'hg qnext'), | |
1870 | "qprev": (prev, [], 'hg qprev'), |
|
1945 | "qprev": (prev, [], 'hg qprev'), | |
1871 | "^qpop": |
|
1946 | "^qpop": | |
@@ -1887,8 +1962,10 b' cmdtable = {' | |||||
1887 | [('e', 'edit', None, _('edit commit message')), |
|
1962 | [('e', 'edit', None, _('edit commit message')), | |
1888 | ('m', 'message', '', _('change commit message with <text>')), |
|
1963 | ('m', 'message', '', _('change commit message with <text>')), | |
1889 | ('l', 'logfile', '', _('change commit message with <file> content')), |
|
1964 | ('l', 'logfile', '', _('change commit message with <file> content')), | |
1890 |
('s', 'short', None, 'short refresh') |
|
1965 | ('s', 'short', None, 'short refresh'), | |
1891 | 'hg qrefresh [-e] [-m TEXT] [-l FILE] [-s]'), |
|
1966 | ('I', 'include', [], _('include names matching the given patterns')), | |
|
1967 | ('X', 'exclude', [], _('exclude names matching the given patterns'))], | |||
|
1968 | 'hg qrefresh [-I] [-X] [-e] [-m TEXT] [-l FILE] [-s] FILES...'), | |||
1892 | 'qrename|qmv': |
|
1969 | 'qrename|qmv': | |
1893 | (rename, [], 'hg qrename PATCH1 [PATCH2]'), |
|
1970 | (rename, [], 'hg qrename PATCH1 [PATCH2]'), | |
1894 | "qrestore": |
|
1971 | "qrestore": | |
@@ -1907,8 +1984,11 b' cmdtable = {' | |||||
1907 | 'hg qsave [-m TEXT] [-l FILE] [-c] [-n NAME] [-e] [-f]'), |
|
1984 | 'hg qsave [-m TEXT] [-l FILE] [-c] [-n NAME] [-e] [-f]'), | |
1908 | "qselect": (select, |
|
1985 | "qselect": (select, | |
1909 | [('n', 'none', None, _('disable all guards')), |
|
1986 | [('n', 'none', None, _('disable all guards')), | |
1910 |
('s', 'series', None, _('list all guards in series file')) |
|
1987 | ('s', 'series', None, _('list all guards in series file')), | |
1911 | 'hg qselect [GUARDS]'), |
|
1988 | ('', 'pop', None, | |
|
1989 | _('pop to before first guarded applied patch')), | |||
|
1990 | ('', 'reapply', None, _('pop, then reapply patches'))], | |||
|
1991 | 'hg qselect [OPTION...] [GUARD...]'), | |||
1912 | "qseries": |
|
1992 | "qseries": | |
1913 | (series, |
|
1993 | (series, | |
1914 | [('m', 'missing', None, 'print patches not in series'), |
|
1994 | [('m', 'missing', None, 'print patches not in series'), | |
@@ -1923,4 +2003,3 b' cmdtable = {' | |||||
1923 | "qtop": (top, [], 'hg qtop'), |
|
2003 | "qtop": (top, [], 'hg qtop'), | |
1924 | "qunapplied": (unapplied, [], 'hg qunapplied [PATCH]'), |
|
2004 | "qunapplied": (unapplied, [], 'hg qunapplied [PATCH]'), | |
1925 | } |
|
2005 | } | |
1926 |
|
@@ -67,8 +67,8 b'' | |||||
67 | from mercurial.demandload import * |
|
67 | from mercurial.demandload import * | |
68 | from mercurial.i18n import gettext as _ |
|
68 | from mercurial.i18n import gettext as _ | |
69 | from mercurial.node import * |
|
69 | from mercurial.node import * | |
70 |
demandload(globals(), ' |
|
70 | demandload(globals(), 'mercurial:commands,patch,templater,util,mail') | |
71 | demandload(globals(), 'fnmatch socket time') |
|
71 | demandload(globals(), 'email.Parser fnmatch socket time') | |
72 |
|
72 | |||
73 | # template for single changeset can include email headers. |
|
73 | # template for single changeset can include email headers. | |
74 | single_template = ''' |
|
74 | single_template = ''' | |
@@ -229,8 +229,8 b' class notifier(object):' | |||||
229 | else: |
|
229 | else: | |
230 | self.ui.status(_('notify: sending %d subscribers %d changes\n') % |
|
230 | self.ui.status(_('notify: sending %d subscribers %d changes\n') % | |
231 | (len(self.subs), count)) |
|
231 | (len(self.subs), count)) | |
232 | mail = self.ui.sendmail() |
|
232 | mail.sendmail(self.ui, templater.email(msg['From']), | |
233 | mail.sendmail(templater.email(msg['From']), self.subs, msgtext) |
|
233 | self.subs, msgtext) | |
234 |
|
234 | |||
235 | def diff(self, node, ref): |
|
235 | def diff(self, node, ref): | |
236 | maxdiff = int(self.ui.config('notify', 'maxdiff', 300)) |
|
236 | maxdiff = int(self.ui.config('notify', 'maxdiff', 300)) | |
@@ -238,7 +238,7 b' class notifier(object):' | |||||
238 | return |
|
238 | return | |
239 | fp = templater.stringio() |
|
239 | fp = templater.stringio() | |
240 | prev = self.repo.changelog.parents(node)[0] |
|
240 | prev = self.repo.changelog.parents(node)[0] | |
241 |
|
|
241 | patch.diff(self.repo, fp, prev, ref) | |
242 | difflines = fp.getvalue().splitlines(1) |
|
242 | difflines = fp.getvalue().splitlines(1) | |
243 | if maxdiff > 0 and len(difflines) > maxdiff: |
|
243 | if maxdiff > 0 and len(difflines) > maxdiff: | |
244 | self.sio.write(_('\ndiffs (truncated from %d to %d lines):\n\n') % |
|
244 | self.sio.write(_('\ndiffs (truncated from %d to %d lines):\n\n') % |
@@ -23,26 +23,49 b'' | |||||
23 | # the changeset summary, so you can be sure you are sending the right |
|
23 | # the changeset summary, so you can be sure you are sending the right | |
24 | # changes. |
|
24 | # changes. | |
25 | # |
|
25 | # | |
26 | # It is best to run this script with the "-n" (test only) flag before |
|
26 | # To enable this extension: | |
27 | # firing it up "for real", in which case it will use your pager to |
|
|||
28 | # display each of the messages that it would send. |
|
|||
29 | # |
|
27 | # | |
30 | # The "-m" (mbox) option will create an mbox file instead of sending |
|
28 | # [extensions] | |
31 | # the messages directly. This can be reviewed e.g. with "mutt -R -f mbox", |
|
29 | # hgext.patchbomb = | |
32 | # and finally sent with "formail -s sendmail -bm -t < mbox". |
|
|||
33 | # |
|
30 | # | |
34 | # To configure other defaults, add a section like this to your hgrc |
|
31 | # To configure other defaults, add a section like this to your hgrc | |
35 | # file: |
|
32 | # file: | |
36 | # |
|
33 | # | |
37 | # [email] |
|
34 | # [email] | |
38 | # from = My Name <my@email> |
|
35 | # from = My Name <my@email> | |
39 | # to = recipient1, recipient2, ... |
|
36 | # to = recipient1, recipient2, ... | |
40 | # cc = cc1, cc2, ... |
|
37 | # cc = cc1, cc2, ... | |
41 | # bcc = bcc1, bcc2, ... |
|
38 | # bcc = bcc1, bcc2, ... | |
|
39 | # | |||
|
40 | # Then you can use the "hg email" command to mail a series of changesets | |||
|
41 | # as a patchbomb. | |||
|
42 | # | |||
|
43 | # To avoid sending patches prematurely, it is a good idea to first run | |||
|
44 | # the "email" command with the "-n" option (test only). You will be | |||
|
45 | # prompted for an email recipient address, a subject an an introductory | |||
|
46 | # message describing the patches of your patchbomb. Then when all is | |||
|
47 | # done, your pager will be fired up once for each patchbomb message, so | |||
|
48 | # you can verify everything is alright. | |||
|
49 | # | |||
|
50 | # The "-m" (mbox) option is also very useful. Instead of previewing | |||
|
51 | # each patchbomb message in a pager or sending the messages directly, | |||
|
52 | # it will create a UNIX mailbox file with the patch emails. This | |||
|
53 | # mailbox file can be previewed with any mail user agent which supports | |||
|
54 | # UNIX mbox files, i.e. with mutt: | |||
|
55 | # | |||
|
56 | # % mutt -R -f mbox | |||
|
57 | # | |||
|
58 | # When you are previewing the patchbomb messages, you can use `formail' | |||
|
59 | # (a utility that is commonly installed as part of the procmail package), | |||
|
60 | # to send each message out: | |||
|
61 | # | |||
|
62 | # % formail -s sendmail -bm -t < mbox | |||
|
63 | # | |||
|
64 | # That should be all. Now your patchbomb is on its way out. | |||
42 |
|
65 | |||
43 | from mercurial.demandload import * |
|
66 | from mercurial.demandload import * | |
44 | demandload(globals(), '''email.MIMEMultipart email.MIMEText email.Utils |
|
67 | demandload(globals(), '''email.MIMEMultipart email.MIMEText email.Utils | |
45 | mercurial:commands,hg,ui |
|
68 | mercurial:commands,hg,mail,ui | |
46 | os errno popen2 socket sys tempfile time''') |
|
69 | os errno popen2 socket sys tempfile time''') | |
47 | from mercurial.i18n import gettext as _ |
|
70 | from mercurial.i18n import gettext as _ | |
48 | from mercurial.node import * |
|
71 | from mercurial.node import * | |
@@ -241,7 +264,7 b' def patchbomb(ui, repo, *revs, **opts):' | |||||
241 | ui.write('\n') |
|
264 | ui.write('\n') | |
242 |
|
265 | |||
243 | if not opts['test'] and not opts['mbox']: |
|
266 | if not opts['test'] and not opts['mbox']: | |
244 |
mail = ui |
|
267 | mailer = mail.connect(ui) | |
245 | parent = None |
|
268 | parent = None | |
246 |
|
269 | |||
247 | # Calculate UTC offset |
|
270 | # Calculate UTC offset | |
@@ -290,7 +313,7 b' def patchbomb(ui, repo, *revs, **opts):' | |||||
290 | ui.status('Sending ', m['Subject'], ' ...\n') |
|
313 | ui.status('Sending ', m['Subject'], ' ...\n') | |
291 | # Exim does not remove the Bcc field |
|
314 | # Exim does not remove the Bcc field | |
292 | del m['Bcc'] |
|
315 | del m['Bcc'] | |
293 | mail.sendmail(sender, to + bcc + cc, m.as_string(0)) |
|
316 | mailer.sendmail(sender, to + bcc + cc, m.as_string(0)) | |
294 |
|
317 | |||
295 | cmdtable = { |
|
318 | cmdtable = { | |
296 | 'email': |
|
319 | 'email': |
@@ -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. |
This diff has been collapsed as it changes many lines, (697 lines changed) Show them Hide them | |||||
@@ -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,10 +10,10 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 |
|
13 | demandload(globals(), "fnmatch 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(), "cmdutil hgweb.server sshserver") | |
17 |
|
17 | |||
18 | class UnknownCommand(Exception): |
|
18 | class UnknownCommand(Exception): | |
19 | """Exception raised if command is not in the command table.""" |
|
19 | """Exception raised if command is not in the command table.""" | |
@@ -21,19 +21,10 b' class AmbiguousCommand(Exception):' | |||||
21 | """Exception raised if command shortcut matches more than one command.""" |
|
21 | """Exception raised if command shortcut matches more than one command.""" | |
22 |
|
22 | |||
23 | def bail_if_changed(repo): |
|
23 | def bail_if_changed(repo): | |
24 |
modified, added, removed, deleted |
|
24 | modified, added, removed, deleted = repo.status()[:4] | |
25 | if modified or added or removed or deleted: |
|
25 | if modified or added or removed or deleted: | |
26 | raise util.Abort(_("outstanding uncommitted changes")) |
|
26 | raise util.Abort(_("outstanding uncommitted changes")) | |
27 |
|
27 | |||
28 | def filterfiles(filters, files): |
|
|||
29 | l = [x for x in files if x in filters] |
|
|||
30 |
|
||||
31 | for t in filters: |
|
|||
32 | if t and t[-1] != "/": |
|
|||
33 | t += "/" |
|
|||
34 | l += [x for x in files if x.startswith(t)] |
|
|||
35 | return l |
|
|||
36 |
|
||||
37 | def relpath(repo, args): |
|
28 | def relpath(repo, args): | |
38 | cwd = repo.getcwd() |
|
29 | cwd = repo.getcwd() | |
39 | if cwd: |
|
30 | if cwd: | |
@@ -59,29 +50,6 b' def logmessage(opts):' | |||||
59 | (logfile, inst.strerror)) |
|
50 | (logfile, inst.strerror)) | |
60 | return message |
|
51 | return message | |
61 |
|
52 | |||
62 | def matchpats(repo, pats=[], opts={}, head=''): |
|
|||
63 | cwd = repo.getcwd() |
|
|||
64 | if not pats and cwd: |
|
|||
65 | opts['include'] = [os.path.join(cwd, i) for i in opts['include']] |
|
|||
66 | opts['exclude'] = [os.path.join(cwd, x) for x in opts['exclude']] |
|
|||
67 | cwd = '' |
|
|||
68 | return util.cmdmatcher(repo.root, cwd, pats or ['.'], opts.get('include'), |
|
|||
69 | opts.get('exclude'), head) |
|
|||
70 |
|
||||
71 | def makewalk(repo, pats, opts, node=None, head='', badmatch=None): |
|
|||
72 | files, matchfn, anypats = matchpats(repo, pats, opts, head) |
|
|||
73 | exact = dict(zip(files, files)) |
|
|||
74 | def walk(): |
|
|||
75 | for src, fn in repo.walk(node=node, files=files, match=matchfn, |
|
|||
76 | badmatch=badmatch): |
|
|||
77 | yield src, fn, util.pathto(repo.getcwd(), fn), fn in exact |
|
|||
78 | return files, matchfn, walk() |
|
|||
79 |
|
||||
80 | def walk(repo, pats, opts, node=None, head='', badmatch=None): |
|
|||
81 | files, matchfn, results = makewalk(repo, pats, opts, node, head, badmatch) |
|
|||
82 | for r in results: |
|
|||
83 | yield r |
|
|||
84 |
|
||||
85 | def walkchangerevs(ui, repo, pats, opts): |
|
53 | def walkchangerevs(ui, repo, pats, opts): | |
86 | '''Iterate over files and the revs they changed in. |
|
54 | '''Iterate over files and the revs they changed in. | |
87 |
|
55 | |||
@@ -124,7 +92,7 b' def walkchangerevs(ui, repo, pats, opts)' | |||||
124 | windowsize *= 2 |
|
92 | windowsize *= 2 | |
125 |
|
93 | |||
126 |
|
94 | |||
127 | files, matchfn, anypats = matchpats(repo, pats, opts) |
|
95 | files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts) | |
128 | follow = opts.get('follow') or opts.get('follow_first') |
|
96 | follow = opts.get('follow') or opts.get('follow_first') | |
129 |
|
97 | |||
130 | if repo.changelog.count() == 0: |
|
98 | if repo.changelog.count() == 0: | |
@@ -215,49 +183,59 b' def walkchangerevs(ui, repo, pats, opts)' | |||||
215 | fncache[rev] = matches |
|
183 | fncache[rev] = matches | |
216 | wanted[rev] = 1 |
|
184 | wanted[rev] = 1 | |
217 |
|
185 | |||
218 | def iterate(): |
|
186 | class followfilter: | |
219 | class followfilter: |
|
187 | def __init__(self, onlyfirst=False): | |
220 | def __init__(self, onlyfirst=False): |
|
188 | self.startrev = -1 | |
221 |
|
|
189 | self.roots = [] | |
222 |
|
|
190 | self.onlyfirst = onlyfirst | |
223 | self.onlyfirst = onlyfirst |
|
191 | ||
224 |
|
192 | def match(self, rev): | ||
225 |
def |
|
193 | def realparents(rev): | |
226 | def realparents(rev): |
|
194 | if self.onlyfirst: | |
227 | if self.onlyfirst: |
|
195 | return repo.changelog.parentrevs(rev)[0:1] | |
228 | return repo.changelog.parentrevs(rev)[0:1] |
|
196 | else: | |
229 | else: |
|
197 | return filter(lambda x: x != -1, repo.changelog.parentrevs(rev)) | |
230 | return filter(lambda x: x != -1, repo.changelog.parentrevs(rev)) |
|
198 | ||
231 |
|
199 | if self.startrev == -1: | ||
232 |
|
|
200 | self.startrev = rev | |
233 |
|
|
201 | return True | |
|
202 | ||||
|
203 | if rev > self.startrev: | |||
|
204 | # forward: all descendants | |||
|
205 | if not self.roots: | |||
|
206 | self.roots.append(self.startrev) | |||
|
207 | for parent in realparents(rev): | |||
|
208 | if parent in self.roots: | |||
|
209 | self.roots.append(rev) | |||
|
210 | return True | |||
|
211 | else: | |||
|
212 | # backwards: all parents | |||
|
213 | if not self.roots: | |||
|
214 | self.roots.extend(realparents(self.startrev)) | |||
|
215 | if rev in self.roots: | |||
|
216 | self.roots.remove(rev) | |||
|
217 | self.roots.extend(realparents(rev)) | |||
234 | return True |
|
218 | return True | |
235 |
|
219 | |||
236 | if rev > self.startrev: |
|
220 | return False | |
237 | # forward: all descendants |
|
221 | ||
238 | if not self.roots: |
|
222 | # it might be worthwhile to do this in the iterator if the rev range | |
239 | self.roots.append(self.startrev) |
|
223 | # is descending and the prune args are all within that range | |
240 | for parent in realparents(rev): |
|
224 | for rev in opts.get('prune', ()): | |
241 | if parent in self.roots: |
|
225 | rev = repo.changelog.rev(repo.lookup(rev)) | |
242 | self.roots.append(rev) |
|
226 | ff = followfilter() | |
243 | return True |
|
227 | stop = min(revs[0], revs[-1]) | |
244 | else: |
|
228 | for x in range(rev, stop-1, -1): | |
245 | # backwards: all parents |
|
229 | if ff.match(x) and wanted.has_key(x): | |
246 | if not self.roots: |
|
230 | del wanted[x] | |
247 | self.roots.extend(realparents(self.startrev)) |
|
231 | ||
248 | if rev in self.roots: |
|
232 | def iterate(): | |
249 | self.roots.remove(rev) |
|
|||
250 | self.roots.extend(realparents(rev)) |
|
|||
251 | return True |
|
|||
252 |
|
||||
253 | return False |
|
|||
254 |
|
||||
255 | if follow and not files: |
|
233 | if follow and not files: | |
256 | ff = followfilter(onlyfirst=opts.get('follow_first')) |
|
234 | ff = followfilter(onlyfirst=opts.get('follow_first')) | |
257 | def want(rev): |
|
235 | def want(rev): | |
258 |
if rev |
|
236 | if ff.match(rev) and rev in wanted: | |
259 |
return |
|
237 | return True | |
260 |
return |
|
238 | return False | |
261 | else: |
|
239 | else: | |
262 | def want(rev): |
|
240 | def want(rev): | |
263 | return rev in wanted |
|
241 | return rev in wanted | |
@@ -344,63 +322,6 b' def revrange(ui, repo, revs):' | |||||
344 | seen[rev] = 1 |
|
322 | seen[rev] = 1 | |
345 | yield str(rev) |
|
323 | yield str(rev) | |
346 |
|
324 | |||
347 | def make_filename(repo, pat, node, |
|
|||
348 | total=None, seqno=None, revwidth=None, pathname=None): |
|
|||
349 | node_expander = { |
|
|||
350 | 'H': lambda: hex(node), |
|
|||
351 | 'R': lambda: str(repo.changelog.rev(node)), |
|
|||
352 | 'h': lambda: short(node), |
|
|||
353 | } |
|
|||
354 | expander = { |
|
|||
355 | '%': lambda: '%', |
|
|||
356 | 'b': lambda: os.path.basename(repo.root), |
|
|||
357 | } |
|
|||
358 |
|
||||
359 | try: |
|
|||
360 | if node: |
|
|||
361 | expander.update(node_expander) |
|
|||
362 | if node and revwidth is not None: |
|
|||
363 | expander['r'] = (lambda: |
|
|||
364 | str(repo.changelog.rev(node)).zfill(revwidth)) |
|
|||
365 | if total is not None: |
|
|||
366 | expander['N'] = lambda: str(total) |
|
|||
367 | if seqno is not None: |
|
|||
368 | expander['n'] = lambda: str(seqno) |
|
|||
369 | if total is not None and seqno is not None: |
|
|||
370 | expander['n'] = lambda:str(seqno).zfill(len(str(total))) |
|
|||
371 | if pathname is not None: |
|
|||
372 | expander['s'] = lambda: os.path.basename(pathname) |
|
|||
373 | expander['d'] = lambda: os.path.dirname(pathname) or '.' |
|
|||
374 | expander['p'] = lambda: pathname |
|
|||
375 |
|
||||
376 | newname = [] |
|
|||
377 | patlen = len(pat) |
|
|||
378 | i = 0 |
|
|||
379 | while i < patlen: |
|
|||
380 | c = pat[i] |
|
|||
381 | if c == '%': |
|
|||
382 | i += 1 |
|
|||
383 | c = pat[i] |
|
|||
384 | c = expander[c]() |
|
|||
385 | newname.append(c) |
|
|||
386 | i += 1 |
|
|||
387 | return ''.join(newname) |
|
|||
388 | except KeyError, inst: |
|
|||
389 | raise util.Abort(_("invalid format spec '%%%s' in output file name"), |
|
|||
390 | inst.args[0]) |
|
|||
391 |
|
||||
392 | def make_file(repo, pat, node=None, |
|
|||
393 | total=None, seqno=None, revwidth=None, mode='wb', pathname=None): |
|
|||
394 | if not pat or pat == '-': |
|
|||
395 | return 'w' in mode and sys.stdout or sys.stdin |
|
|||
396 | if hasattr(pat, 'write') and 'w' in mode: |
|
|||
397 | return pat |
|
|||
398 | if hasattr(pat, 'read') and 'r' in mode: |
|
|||
399 | return pat |
|
|||
400 | return open(make_filename(repo, pat, node, total, seqno, revwidth, |
|
|||
401 | pathname), |
|
|||
402 | mode) |
|
|||
403 |
|
||||
404 | def write_bundle(cg, filename=None, compress=True): |
|
325 | def write_bundle(cg, filename=None, compress=True): | |
405 | """Write a bundle file and return its filename. |
|
326 | """Write a bundle file and return its filename. | |
406 |
|
327 | |||
@@ -453,74 +374,6 b' def write_bundle(cg, filename=None, comp' | |||||
453 | if cleanup is not None: |
|
374 | if cleanup is not None: | |
454 | os.unlink(cleanup) |
|
375 | os.unlink(cleanup) | |
455 |
|
376 | |||
456 | def dodiff(fp, ui, repo, node1, node2, files=None, match=util.always, |
|
|||
457 | changes=None, text=False, opts={}): |
|
|||
458 | if not node1: |
|
|||
459 | node1 = repo.dirstate.parents()[0] |
|
|||
460 | # reading the data for node1 early allows it to play nicely |
|
|||
461 | # with repo.changes and the revlog cache. |
|
|||
462 | change = repo.changelog.read(node1) |
|
|||
463 | mmap = repo.manifest.read(change[0]) |
|
|||
464 | date1 = util.datestr(change[2]) |
|
|||
465 |
|
||||
466 | if not changes: |
|
|||
467 | changes = repo.changes(node1, node2, files, match=match) |
|
|||
468 | modified, added, removed, deleted, unknown = changes |
|
|||
469 | if files: |
|
|||
470 | modified, added, removed = map(lambda x: filterfiles(files, x), |
|
|||
471 | (modified, added, removed)) |
|
|||
472 |
|
||||
473 | if not modified and not added and not removed: |
|
|||
474 | return |
|
|||
475 |
|
||||
476 | if node2: |
|
|||
477 | change = repo.changelog.read(node2) |
|
|||
478 | mmap2 = repo.manifest.read(change[0]) |
|
|||
479 | _date2 = util.datestr(change[2]) |
|
|||
480 | def date2(f): |
|
|||
481 | return _date2 |
|
|||
482 | def read(f): |
|
|||
483 | return repo.file(f).read(mmap2[f]) |
|
|||
484 | else: |
|
|||
485 | tz = util.makedate()[1] |
|
|||
486 | _date2 = util.datestr() |
|
|||
487 | def date2(f): |
|
|||
488 | try: |
|
|||
489 | return util.datestr((os.lstat(repo.wjoin(f)).st_mtime, tz)) |
|
|||
490 | except OSError, err: |
|
|||
491 | if err.errno != errno.ENOENT: raise |
|
|||
492 | return _date2 |
|
|||
493 | def read(f): |
|
|||
494 | return repo.wread(f) |
|
|||
495 |
|
||||
496 | if ui.quiet: |
|
|||
497 | r = None |
|
|||
498 | else: |
|
|||
499 | hexfunc = ui.verbose and hex or short |
|
|||
500 | r = [hexfunc(node) for node in [node1, node2] if node] |
|
|||
501 |
|
||||
502 | diffopts = ui.diffopts() |
|
|||
503 | showfunc = opts.get('show_function') or diffopts['showfunc'] |
|
|||
504 | ignorews = opts.get('ignore_all_space') or diffopts['ignorews'] |
|
|||
505 | ignorewsamount = opts.get('ignore_space_change') or \ |
|
|||
506 | diffopts['ignorewsamount'] |
|
|||
507 | ignoreblanklines = opts.get('ignore_blank_lines') or \ |
|
|||
508 | diffopts['ignoreblanklines'] |
|
|||
509 |
|
||||
510 | all = modified + added + removed |
|
|||
511 | all.sort() |
|
|||
512 | for f in all: |
|
|||
513 | to = None |
|
|||
514 | tn = None |
|
|||
515 | if f in mmap: |
|
|||
516 | to = repo.file(f).read(mmap[f]) |
|
|||
517 | if f not in removed: |
|
|||
518 | tn = read(f) |
|
|||
519 | fp.write(mdiff.unidiff(to, date1, tn, date2(f), f, r, text=text, |
|
|||
520 | showfunc=showfunc, ignorews=ignorews, |
|
|||
521 | ignorewsamount=ignorewsamount, |
|
|||
522 | ignoreblanklines=ignoreblanklines)) |
|
|||
523 |
|
||||
524 | def trimuser(ui, name, rev, revcache): |
|
377 | def trimuser(ui, name, rev, revcache): | |
525 | """trim the name of the user who committed a change""" |
|
378 | """trim the name of the user who committed a change""" | |
526 | user = revcache.get(rev) |
|
379 | user = revcache.get(rev) | |
@@ -550,17 +403,15 b' class changeset_printer(object):' | |||||
550 | changes = log.read(changenode) |
|
403 | changes = log.read(changenode) | |
551 | date = util.datestr(changes[2]) |
|
404 | date = util.datestr(changes[2]) | |
552 |
|
405 | |||
553 |
|
|
406 | hexfunc = self.ui.debugflag and hex or short | |
554 | for p in log.parents(changenode) |
|
407 | ||
|
408 | parents = [(log.rev(p), hexfunc(p)) for p in log.parents(changenode) | |||
555 | if self.ui.debugflag or p != nullid] |
|
409 | if self.ui.debugflag or p != nullid] | |
556 | if (not self.ui.debugflag and len(parents) == 1 and |
|
410 | if (not self.ui.debugflag and len(parents) == 1 and | |
557 | parents[0][0] == rev-1): |
|
411 | parents[0][0] == rev-1): | |
558 | parents = [] |
|
412 | parents = [] | |
559 |
|
413 | |||
560 | if self.ui.verbose: |
|
414 | self.ui.write(_("changeset: %d:%s\n") % (rev, hexfunc(changenode))) | |
561 | self.ui.write(_("changeset: %d:%s\n") % (rev, hex(changenode))) |
|
|||
562 | else: |
|
|||
563 | self.ui.write(_("changeset: %d:%s\n") % (rev, short(changenode))) |
|
|||
564 |
|
415 | |||
565 | for tag in self.repo.nodetags(changenode): |
|
416 | for tag in self.repo.nodetags(changenode): | |
566 | self.ui.status(_("tag: %s\n") % tag) |
|
417 | self.ui.status(_("tag: %s\n") % tag) | |
@@ -577,7 +428,7 b' class changeset_printer(object):' | |||||
577 | self.ui.status(_("date: %s\n") % date) |
|
428 | self.ui.status(_("date: %s\n") % date) | |
578 |
|
429 | |||
579 | if self.ui.debugflag: |
|
430 | if self.ui.debugflag: | |
580 |
files = self.repo. |
|
431 | files = self.repo.status(log.parents(changenode)[0], changenode)[:3] | |
581 | for key, value in zip([_("files:"), _("files+:"), _("files-:")], |
|
432 | for key, value in zip([_("files:"), _("files+:"), _("files-:")], | |
582 | files): |
|
433 | files): | |
583 | if value: |
|
434 | if value: | |
@@ -633,7 +484,7 b' def show_version(ui):' | |||||
633 | ui.write(_("Mercurial Distributed SCM (version %s)\n") |
|
484 | ui.write(_("Mercurial Distributed SCM (version %s)\n") | |
634 | % version.get_version()) |
|
485 | % version.get_version()) | |
635 | ui.status(_( |
|
486 | ui.status(_( | |
636 | "\nCopyright (C) 2005 Matt Mackall <mpm@selenic.com>\n" |
|
487 | "\nCopyright (C) 2005, 2006 Matt Mackall <mpm@selenic.com>\n" | |
637 | "This is free software; see the source for copying conditions. " |
|
488 | "This is free software; see the source for copying conditions. " | |
638 | "There is NO\nwarranty; " |
|
489 | "There is NO\nwarranty; " | |
639 | "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" |
|
490 | "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" | |
@@ -654,7 +505,7 b' def help_(ui, name=None, with_version=Fa' | |||||
654 | if with_version: |
|
505 | if with_version: | |
655 | show_version(ui) |
|
506 | show_version(ui) | |
656 | ui.write('\n') |
|
507 | ui.write('\n') | |
657 | aliases, i = findcmd(name) |
|
508 | aliases, i = findcmd(ui, name) | |
658 | # synopsis |
|
509 | # synopsis | |
659 | ui.write("%s\n\n" % i[2]) |
|
510 | ui.write("%s\n\n" % i[2]) | |
660 |
|
511 | |||
@@ -787,7 +638,7 b' def add(ui, repo, *pats, **opts):' | |||||
787 | """ |
|
638 | """ | |
788 |
|
639 | |||
789 | names = [] |
|
640 | names = [] | |
790 | for src, abs, rel, exact in walk(repo, pats, opts): |
|
641 | for src, abs, rel, exact in cmdutil.walk(repo, pats, opts): | |
791 | if exact: |
|
642 | if exact: | |
792 | if ui.verbose: |
|
643 | if ui.verbose: | |
793 | ui.status(_('adding %s\n') % rel) |
|
644 | ui.status(_('adding %s\n') % rel) | |
@@ -801,33 +652,21 b' def add(ui, repo, *pats, **opts):' | |||||
801 | def addremove(ui, repo, *pats, **opts): |
|
652 | def addremove(ui, repo, *pats, **opts): | |
802 | """add all new files, delete all missing files (DEPRECATED) |
|
653 | """add all new files, delete all missing files (DEPRECATED) | |
803 |
|
654 | |||
804 | (DEPRECATED) |
|
|||
805 | Add all new files and remove all missing files from the repository. |
|
655 | Add all new files and remove all missing files from the repository. | |
806 |
|
656 | |||
807 | New files are ignored if they match any of the patterns in .hgignore. As |
|
657 | New files are ignored if they match any of the patterns in .hgignore. As | |
808 | with add, these changes take effect at the next commit. |
|
658 | with add, these changes take effect at the next commit. | |
809 |
|
659 | |||
810 | This command is now deprecated and will be removed in a future |
|
660 | Use the -s option to detect renamed files. With a parameter > 0, | |
811 | release. Please use add and remove --after instead. |
|
661 | this compares every removed file with every added file and records | |
|
662 | those similar enough as renames. This option takes a percentage | |||
|
663 | between 0 (disabled) and 100 (files must be identical) as its | |||
|
664 | parameter. Detecting renamed files this way can be expensive. | |||
812 | """ |
|
665 | """ | |
813 | ui.warn(_('(the addremove command is deprecated; use add and remove ' |
|
666 | sim = float(opts.get('similarity') or 0) | |
814 | '--after instead)\n')) |
|
667 | if sim < 0 or sim > 100: | |
815 | return addremove_lock(ui, repo, pats, opts) |
|
668 | raise util.Abort(_('similarity must be between 0 and 100')) | |
816 |
|
669 | return cmdutil.addremove(repo, pats, opts, similarity=sim/100.) | ||
817 | def addremove_lock(ui, repo, pats, opts, wlock=None): |
|
|||
818 | add, remove = [], [] |
|
|||
819 | for src, abs, rel, exact in walk(repo, pats, opts): |
|
|||
820 | if src == 'f' and repo.dirstate.state(abs) == '?': |
|
|||
821 | add.append(abs) |
|
|||
822 | if ui.verbose or not exact: |
|
|||
823 | ui.status(_('adding %s\n') % ((pats and rel) or abs)) |
|
|||
824 | if repo.dirstate.state(abs) != 'r' and not os.path.exists(rel): |
|
|||
825 | remove.append(abs) |
|
|||
826 | if ui.verbose or not exact: |
|
|||
827 | ui.status(_('removing %s\n') % ((pats and rel) or abs)) |
|
|||
828 | if not opts.get('dry_run'): |
|
|||
829 | repo.add(add, wlock=wlock) |
|
|||
830 | repo.remove(remove, wlock=wlock) |
|
|||
831 |
|
670 | |||
832 | def annotate(ui, repo, *pats, **opts): |
|
671 | def annotate(ui, repo, *pats, **opts): | |
833 | """show changeset information per file line |
|
672 | """show changeset information per file line | |
@@ -870,7 +709,8 b' def annotate(ui, repo, *pats, **opts):' | |||||
870 |
|
709 | |||
871 | ctx = repo.changectx(opts['rev'] or repo.dirstate.parents()[0]) |
|
710 | ctx = repo.changectx(opts['rev'] or repo.dirstate.parents()[0]) | |
872 |
|
711 | |||
873 |
for src, abs, rel, exact in walk(repo, pats, opts, |
|
712 | for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, | |
|
713 | node=ctx.node()): | |||
874 | fctx = ctx.filectx(abs) |
|
714 | fctx = ctx.filectx(abs) | |
875 | if not opts['text'] and util.binary(fctx.data()): |
|
715 | if not opts['text'] and util.binary(fctx.data()): | |
876 | ui.write(_("%s: binary file\n") % ((pats and rel) or abs)) |
|
716 | ui.write(_("%s: binary file\n") % ((pats and rel) or abs)) | |
@@ -922,10 +762,10 b' def archive(ui, repo, dest, **opts):' | |||||
922 | raise util.Abort(_('uncommitted merge - please provide a ' |
|
762 | raise util.Abort(_('uncommitted merge - please provide a ' | |
923 | 'specific revision')) |
|
763 | 'specific revision')) | |
924 |
|
764 | |||
925 | dest = make_filename(repo, dest, node) |
|
765 | dest = cmdutil.make_filename(repo, dest, node) | |
926 | if os.path.realpath(dest) == repo.root: |
|
766 | if os.path.realpath(dest) == repo.root: | |
927 | raise util.Abort(_('repository root cannot be destination')) |
|
767 | raise util.Abort(_('repository root cannot be destination')) | |
928 | dummy, matchfn, dummy = matchpats(repo, [], opts) |
|
768 | dummy, matchfn, dummy = cmdutil.matchpats(repo, [], opts) | |
929 | kind = opts.get('type') or 'files' |
|
769 | kind = opts.get('type') or 'files' | |
930 | prefix = opts['prefix'] |
|
770 | prefix = opts['prefix'] | |
931 | if dest == '-': |
|
771 | if dest == '-': | |
@@ -933,7 +773,7 b' def archive(ui, repo, dest, **opts):' | |||||
933 | raise util.Abort(_('cannot archive plain files to stdout')) |
|
773 | raise util.Abort(_('cannot archive plain files to stdout')) | |
934 | dest = sys.stdout |
|
774 | dest = sys.stdout | |
935 | if not prefix: prefix = os.path.basename(repo.root) + '-%h' |
|
775 | if not prefix: prefix = os.path.basename(repo.root) + '-%h' | |
936 | prefix = make_filename(repo, prefix, node) |
|
776 | prefix = cmdutil.make_filename(repo, prefix, node) | |
937 | archival.archive(repo, dest, node, kind, not opts['no_decode'], |
|
777 | archival.archive(repo, dest, node, kind, not opts['no_decode'], | |
938 | matchfn, prefix) |
|
778 | matchfn, prefix) | |
939 |
|
779 | |||
@@ -978,6 +818,7 b' def backout(ui, repo, rev, **opts):' | |||||
978 | parent = p1 |
|
818 | parent = p1 | |
979 | hg.clean(repo, node, show_stats=False) |
|
819 | hg.clean(repo, node, show_stats=False) | |
980 | revert_opts = opts.copy() |
|
820 | revert_opts = opts.copy() | |
|
821 | revert_opts['all'] = True | |||
981 | revert_opts['rev'] = hex(parent) |
|
822 | revert_opts['rev'] = hex(parent) | |
982 | revert(ui, repo, **revert_opts) |
|
823 | revert(ui, repo, **revert_opts) | |
983 | commit_opts = opts.copy() |
|
824 | commit_opts = opts.copy() | |
@@ -1037,8 +878,9 b' def cat(ui, repo, file1, *pats, **opts):' | |||||
1037 | %p root-relative path name of file being printed |
|
878 | %p root-relative path name of file being printed | |
1038 | """ |
|
879 | """ | |
1039 | ctx = repo.changectx(opts['rev'] or "-1") |
|
880 | ctx = repo.changectx(opts['rev'] or "-1") | |
1040 |
for src, abs, rel, exact in walk(repo, (file1,) + pats, opts, |
|
881 | for src, abs, rel, exact in cmdutil.walk(repo, (file1,) + pats, opts, | |
1041 | fp = make_file(repo, opts['output'], ctx.node(), pathname=abs) |
|
882 | ctx.node()): | |
|
883 | fp = cmdutil.make_file(repo, opts['output'], ctx.node(), pathname=abs) | |||
1042 | fp.write(ctx.filectx(abs).data()) |
|
884 | fp.write(ctx.filectx(abs).data()) | |
1043 |
|
885 | |||
1044 | def clone(ui, source, dest=None, **opts): |
|
886 | def clone(ui, source, dest=None, **opts): | |
@@ -1100,11 +942,10 b' def commit(ui, repo, *pats, **opts):' | |||||
1100 | message = logmessage(opts) |
|
942 | message = logmessage(opts) | |
1101 |
|
943 | |||
1102 | if opts['addremove']: |
|
944 | if opts['addremove']: | |
1103 |
addremove |
|
945 | cmdutil.addremove(repo, pats, opts) | |
1104 | fns, match, anypats = matchpats(repo, pats, opts) |
|
946 | fns, match, anypats = cmdutil.matchpats(repo, pats, opts) | |
1105 | if pats: |
|
947 | if pats: | |
1106 | modified, added, removed, deleted, unknown = ( |
|
948 | modified, added, removed = repo.status(files=fns, match=match)[:3] | |
1107 | repo.changes(files=fns, match=match)) |
|
|||
1108 | files = modified + added + removed |
|
949 | files = modified + added + removed | |
1109 | else: |
|
950 | else: | |
1110 | files = [] |
|
951 | files = [] | |
@@ -1259,7 +1100,7 b' def docopy(ui, repo, pats, opts, wlock):' | |||||
1259 | copylist = [] |
|
1100 | copylist = [] | |
1260 | for pat in pats: |
|
1101 | for pat in pats: | |
1261 | srcs = [] |
|
1102 | srcs = [] | |
1262 | for tag, abssrc, relsrc, exact in walk(repo, [pat], opts): |
|
1103 | for tag, abssrc, relsrc, exact in cmdutil.walk(repo, [pat], opts): | |
1263 | origsrc = okaytocopy(abssrc, relsrc, exact) |
|
1104 | origsrc = okaytocopy(abssrc, relsrc, exact) | |
1264 | if origsrc: |
|
1105 | if origsrc: | |
1265 | srcs.append((origsrc, abssrc, relsrc, exact)) |
|
1106 | srcs.append((origsrc, abssrc, relsrc, exact)) | |
@@ -1311,7 +1152,7 b" def debugcomplete(ui, cmd='', **opts):" | |||||
1311 | options = [] |
|
1152 | options = [] | |
1312 | otables = [globalopts] |
|
1153 | otables = [globalopts] | |
1313 | if cmd: |
|
1154 | if cmd: | |
1314 | aliases, entry = findcmd(cmd) |
|
1155 | aliases, entry = findcmd(ui, cmd) | |
1315 | otables.append(entry[1]) |
|
1156 | otables.append(entry[1]) | |
1316 | for t in otables: |
|
1157 | for t in otables: | |
1317 | for o in t: |
|
1158 | for o in t: | |
@@ -1321,7 +1162,7 b" def debugcomplete(ui, cmd='', **opts):" | |||||
1321 | ui.write("%s\n" % "\n".join(options)) |
|
1162 | ui.write("%s\n" % "\n".join(options)) | |
1322 | return |
|
1163 | return | |
1323 |
|
1164 | |||
1324 | clist = findpossible(cmd).keys() |
|
1165 | clist = findpossible(ui, cmd).keys() | |
1325 | clist.sort() |
|
1166 | clist.sort() | |
1326 | ui.write("%s\n" % "\n".join(clist)) |
|
1167 | ui.write("%s\n" % "\n".join(clist)) | |
1327 |
|
1168 | |||
@@ -1333,9 +1174,9 b' def debugrebuildstate(ui, repo, rev=None' | |||||
1333 | rev = repo.lookup(rev) |
|
1174 | rev = repo.lookup(rev) | |
1334 | change = repo.changelog.read(rev) |
|
1175 | change = repo.changelog.read(rev) | |
1335 | n = change[0] |
|
1176 | n = change[0] | |
1336 |
files = repo.manifest.read |
|
1177 | files = repo.manifest.read(n) | |
1337 | wlock = repo.wlock() |
|
1178 | wlock = repo.wlock() | |
1338 |
repo.dirstate.rebuild(rev, files |
|
1179 | repo.dirstate.rebuild(rev, files) | |
1339 |
|
1180 | |||
1340 | def debugcheckstate(ui, repo): |
|
1181 | def debugcheckstate(ui, repo): | |
1341 | """validate the correctness of the current dirstate""" |
|
1182 | """validate the correctness of the current dirstate""" | |
@@ -1476,7 +1317,7 b' def debugrename(ui, repo, file, rev=None' | |||||
1476 |
|
1317 | |||
1477 | def debugwalk(ui, repo, *pats, **opts): |
|
1318 | def debugwalk(ui, repo, *pats, **opts): | |
1478 | """show how files match on given patterns""" |
|
1319 | """show how files match on given patterns""" | |
1479 | items = list(walk(repo, pats, opts)) |
|
1320 | items = list(cmdutil.walk(repo, pats, opts)) | |
1480 | if not items: |
|
1321 | if not items: | |
1481 | return |
|
1322 | return | |
1482 | fmt = '%%s %%-%ds %%-%ds %%s' % ( |
|
1323 | fmt = '%%s %%-%ds %%-%ds %%s' % ( | |
@@ -1505,37 +1346,10 b' def diff(ui, repo, *pats, **opts):' | |||||
1505 | """ |
|
1346 | """ | |
1506 | node1, node2 = revpair(ui, repo, opts['rev']) |
|
1347 | node1, node2 = revpair(ui, repo, opts['rev']) | |
1507 |
|
1348 | |||
1508 | fns, matchfn, anypats = matchpats(repo, pats, opts) |
|
1349 | fns, matchfn, anypats = cmdutil.matchpats(repo, pats, opts) | |
1509 |
|
1350 | |||
1510 |
|
|
1351 | patch.diff(repo, node1, node2, fns, match=matchfn, | |
1511 | text=opts['text'], opts=opts) |
|
1352 | opts=patch.diffopts(ui, opts)) | |
1512 |
|
||||
1513 | def doexport(ui, repo, changeset, seqno, total, revwidth, opts): |
|
|||
1514 | node = repo.lookup(changeset) |
|
|||
1515 | parents = [p for p in repo.changelog.parents(node) if p != nullid] |
|
|||
1516 | if opts['switch_parent']: |
|
|||
1517 | parents.reverse() |
|
|||
1518 | prev = (parents and parents[0]) or nullid |
|
|||
1519 | change = repo.changelog.read(node) |
|
|||
1520 |
|
||||
1521 | fp = make_file(repo, opts['output'], node, total=total, seqno=seqno, |
|
|||
1522 | revwidth=revwidth) |
|
|||
1523 | if fp != sys.stdout: |
|
|||
1524 | ui.note("%s\n" % fp.name) |
|
|||
1525 |
|
||||
1526 | fp.write("# HG changeset patch\n") |
|
|||
1527 | fp.write("# User %s\n" % change[1]) |
|
|||
1528 | fp.write("# Date %d %d\n" % change[2]) |
|
|||
1529 | fp.write("# Node ID %s\n" % hex(node)) |
|
|||
1530 | fp.write("# Parent %s\n" % hex(prev)) |
|
|||
1531 | if len(parents) > 1: |
|
|||
1532 | fp.write("# Parent %s\n" % hex(parents[1])) |
|
|||
1533 | fp.write(change[4].rstrip()) |
|
|||
1534 | fp.write("\n\n") |
|
|||
1535 |
|
||||
1536 | dodiff(fp, ui, repo, prev, node, text=opts['text']) |
|
|||
1537 | if fp != sys.stdout: |
|
|||
1538 | fp.close() |
|
|||
1539 |
|
1353 | |||
1540 | def export(ui, repo, *changesets, **opts): |
|
1354 | def export(ui, repo, *changesets, **opts): | |
1541 | """dump the header and diffs for one or more changesets |
|
1355 | """dump the header and diffs for one or more changesets | |
@@ -1566,15 +1380,14 b' def export(ui, repo, *changesets, **opts' | |||||
1566 | """ |
|
1380 | """ | |
1567 | if not changesets: |
|
1381 | if not changesets: | |
1568 | raise util.Abort(_("export requires at least one changeset")) |
|
1382 | raise util.Abort(_("export requires at least one changeset")) | |
1569 | seqno = 0 |
|
|||
1570 | revs = list(revrange(ui, repo, changesets)) |
|
1383 | revs = list(revrange(ui, repo, changesets)) | |
1571 |
|
|
1384 | if len(revs) > 1: | |
1572 | revwidth = max(map(len, revs)) |
|
1385 | ui.note(_('exporting patches:\n')) | |
1573 | msg = len(revs) > 1 and _("Exporting patches:\n") or _("Exporting patch:\n") |
|
1386 | else: | |
1574 | ui.note(msg) |
|
1387 | ui.note(_('exporting patch:\n')) | |
1575 | for cset in revs: |
|
1388 | patch.export(repo, map(repo.lookup, revs), template=opts['output'], | |
1576 | seqno += 1 |
|
1389 | switch_parent=opts['switch_parent'], | |
1577 | doexport(ui, repo, cset, seqno, total, revwidth, opts) |
|
1390 | opts=patch.diffopts(ui, opts)) | |
1578 |
|
1391 | |||
1579 | def forget(ui, repo, *pats, **opts): |
|
1392 | def forget(ui, repo, *pats, **opts): | |
1580 | """don't add the specified files on the next commit (DEPRECATED) |
|
1393 | """don't add the specified files on the next commit (DEPRECATED) | |
@@ -1587,7 +1400,7 b' def forget(ui, repo, *pats, **opts):' | |||||
1587 | """ |
|
1400 | """ | |
1588 | ui.warn(_("(the forget command is deprecated; use revert instead)\n")) |
|
1401 | ui.warn(_("(the forget command is deprecated; use revert instead)\n")) | |
1589 | forget = [] |
|
1402 | forget = [] | |
1590 | for src, abs, rel, exact in walk(repo, pats, opts): |
|
1403 | for src, abs, rel, exact in cmdutil.walk(repo, pats, opts): | |
1591 | if repo.dirstate.state(abs) == 'a': |
|
1404 | if repo.dirstate.state(abs) == 'a': | |
1592 | forget.append(abs) |
|
1405 | forget.append(abs) | |
1593 | if ui.verbose or not exact: |
|
1406 | if ui.verbose or not exact: | |
@@ -1644,42 +1457,56 b' def grep(ui, repo, pattern, *pats, **opt' | |||||
1644 | self.linenum = linenum |
|
1457 | self.linenum = linenum | |
1645 | self.colstart = colstart |
|
1458 | self.colstart = colstart | |
1646 | self.colend = colend |
|
1459 | self.colend = colend | |
|
1460 | ||||
1647 | def __eq__(self, other): |
|
1461 | def __eq__(self, other): | |
1648 | return self.line == other.line |
|
1462 | return self.line == other.line | |
1649 | def __hash__(self): |
|
|||
1650 | return hash(self.line) |
|
|||
1651 |
|
1463 | |||
1652 | matches = {} |
|
1464 | matches = {} | |
|
1465 | copies = {} | |||
1653 | def grepbody(fn, rev, body): |
|
1466 | def grepbody(fn, rev, body): | |
1654 |
matches[rev].setdefault(fn, |
|
1467 | matches[rev].setdefault(fn, []) | |
1655 | m = matches[rev][fn] |
|
1468 | m = matches[rev][fn] | |
1656 | for lnum, cstart, cend, line in matchlines(body): |
|
1469 | for lnum, cstart, cend, line in matchlines(body): | |
1657 | s = linestate(line, lnum, cstart, cend) |
|
1470 | s = linestate(line, lnum, cstart, cend) | |
1658 |
m |
|
1471 | m.append(s) | |
1659 |
|
1472 | |||
1660 | # FIXME: prev isn't used, why ? |
|
1473 | def difflinestates(a, b): | |
|
1474 | sm = difflib.SequenceMatcher(None, a, b) | |||
|
1475 | for tag, alo, ahi, blo, bhi in sm.get_opcodes(): | |||
|
1476 | if tag == 'insert': | |||
|
1477 | for i in range(blo, bhi): | |||
|
1478 | yield ('+', b[i]) | |||
|
1479 | elif tag == 'delete': | |||
|
1480 | for i in range(alo, ahi): | |||
|
1481 | yield ('-', a[i]) | |||
|
1482 | elif tag == 'replace': | |||
|
1483 | for i in range(alo, ahi): | |||
|
1484 | yield ('-', a[i]) | |||
|
1485 | for i in range(blo, bhi): | |||
|
1486 | yield ('+', b[i]) | |||
|
1487 | ||||
1661 | prev = {} |
|
1488 | prev = {} | |
1662 | ucache = {} |
|
1489 | ucache = {} | |
1663 | def display(fn, rev, states, prevstates): |
|
1490 | def display(fn, rev, states, prevstates): | |
1664 | diff = list(sets.Set(states).symmetric_difference(sets.Set(prevstates))) |
|
|||
1665 | diff.sort(lambda x, y: cmp(x.linenum, y.linenum)) |
|
|||
1666 | counts = {'-': 0, '+': 0} |
|
1491 | counts = {'-': 0, '+': 0} | |
1667 | filerevmatches = {} |
|
1492 | filerevmatches = {} | |
1668 | for l in diff: |
|
1493 | if incrementing or not opts['all']: | |
|
1494 | a, b = prevstates, states | |||
|
1495 | else: | |||
|
1496 | a, b = states, prevstates | |||
|
1497 | for change, l in difflinestates(a, b): | |||
1669 | if incrementing or not opts['all']: |
|
1498 | if incrementing or not opts['all']: | |
1670 | change = ((l in prevstates) and '-') or '+' |
|
|||
1671 | r = rev |
|
1499 | r = rev | |
1672 | else: |
|
1500 | else: | |
1673 | change = ((l in states) and '-') or '+' |
|
|||
1674 | r = prev[fn] |
|
1501 | r = prev[fn] | |
1675 |
cols = [fn, str(r |
|
1502 | cols = [fn, str(r)] | |
1676 | if opts['line_number']: |
|
1503 | if opts['line_number']: | |
1677 | cols.append(str(l.linenum)) |
|
1504 | cols.append(str(l.linenum)) | |
1678 | if opts['all']: |
|
1505 | if opts['all']: | |
1679 | cols.append(change) |
|
1506 | cols.append(change) | |
1680 | if opts['user']: |
|
1507 | if opts['user']: | |
1681 |
cols.append(trimuser(ui, getchange(r |
|
1508 | cols.append(trimuser(ui, getchange(r)[1], rev, | |
1682 |
|
|
1509 | ucache)) | |
1683 | if opts['files_with_matches']: |
|
1510 | if opts['files_with_matches']: | |
1684 | c = (fn, rev) |
|
1511 | c = (fn, rev) | |
1685 | if c in filerevmatches: |
|
1512 | if c in filerevmatches: | |
@@ -1696,6 +1523,7 b' def grep(ui, repo, pattern, *pats, **opt' | |||||
1696 | changeiter, getchange, matchfn = walkchangerevs(ui, repo, pats, opts) |
|
1523 | changeiter, getchange, matchfn = walkchangerevs(ui, repo, pats, opts) | |
1697 | count = 0 |
|
1524 | count = 0 | |
1698 | incrementing = False |
|
1525 | incrementing = False | |
|
1526 | follow = opts.get('follow') | |||
1699 | for st, rev, fns in changeiter: |
|
1527 | for st, rev, fns in changeiter: | |
1700 | if st == 'window': |
|
1528 | if st == 'window': | |
1701 | incrementing = rev |
|
1529 | incrementing = rev | |
@@ -1710,20 +1538,31 b' def grep(ui, repo, pattern, *pats, **opt' | |||||
1710 | fstate.setdefault(fn, {}) |
|
1538 | fstate.setdefault(fn, {}) | |
1711 | try: |
|
1539 | try: | |
1712 | grepbody(fn, rev, getfile(fn).read(mf[fn])) |
|
1540 | grepbody(fn, rev, getfile(fn).read(mf[fn])) | |
|
1541 | if follow: | |||
|
1542 | copied = getfile(fn).renamed(mf[fn]) | |||
|
1543 | if copied: | |||
|
1544 | copies.setdefault(rev, {})[fn] = copied[0] | |||
1713 | except KeyError: |
|
1545 | except KeyError: | |
1714 | pass |
|
1546 | pass | |
1715 | elif st == 'iter': |
|
1547 | elif st == 'iter': | |
1716 | states = matches[rev].items() |
|
1548 | states = matches[rev].items() | |
1717 | states.sort() |
|
1549 | states.sort() | |
1718 | for fn, m in states: |
|
1550 | for fn, m in states: | |
|
1551 | copy = copies.get(rev, {}).get(fn) | |||
1719 | if fn in skip: |
|
1552 | if fn in skip: | |
|
1553 | if copy: | |||
|
1554 | skip[copy] = True | |||
1720 | continue |
|
1555 | continue | |
1721 | if incrementing or not opts['all'] or fstate[fn]: |
|
1556 | if incrementing or not opts['all'] or fstate[fn]: | |
1722 | pos, neg = display(fn, rev, m, fstate[fn]) |
|
1557 | pos, neg = display(fn, rev, m, fstate[fn]) | |
1723 | count += pos + neg |
|
1558 | count += pos + neg | |
1724 | if pos and not opts['all']: |
|
1559 | if pos and not opts['all']: | |
1725 | skip[fn] = True |
|
1560 | skip[fn] = True | |
|
1561 | if copy: | |||
|
1562 | skip[copy] = True | |||
1726 | fstate[fn] = m |
|
1563 | fstate[fn] = m | |
|
1564 | if copy: | |||
|
1565 | fstate[copy] = m | |||
1727 | prev[fn] = rev |
|
1566 | prev[fn] = rev | |
1728 |
|
1567 | |||
1729 | if not incrementing: |
|
1568 | if not incrementing: | |
@@ -1732,7 +1571,8 b' def grep(ui, repo, pattern, *pats, **opt' | |||||
1732 | for fn, state in fstate: |
|
1571 | for fn, state in fstate: | |
1733 | if fn in skip: |
|
1572 | if fn in skip: | |
1734 | continue |
|
1573 | continue | |
1735 | display(fn, rev, {}, state) |
|
1574 | if fn not in copies.get(prev[fn], {}): | |
|
1575 | display(fn, rev, {}, state) | |||
1736 | return (count == 0 and 1) or 0 |
|
1576 | return (count == 0 and 1) or 0 | |
1737 |
|
1577 | |||
1738 | def heads(ui, repo, **opts): |
|
1578 | def heads(ui, repo, **opts): | |
@@ -1769,8 +1609,8 b' def identify(ui, repo):' | |||||
1769 | ui.write(_("unknown\n")) |
|
1609 | ui.write(_("unknown\n")) | |
1770 | return |
|
1610 | return | |
1771 |
|
1611 | |||
1772 |
hexfunc = ui. |
|
1612 | hexfunc = ui.debugflag and hex or short | |
1773 |
modified, added, removed, deleted |
|
1613 | modified, added, removed, deleted = repo.status()[:4] | |
1774 | output = ["%s%s" % |
|
1614 | output = ["%s%s" % | |
1775 | ('+'.join([hexfunc(parent) for parent in parents]), |
|
1615 | ('+'.join([hexfunc(parent) for parent in parents]), | |
1776 | (modified or added or removed or deleted) and "+" or "")] |
|
1616 | (modified or added or removed or deleted) and "+" or "")] | |
@@ -1814,81 +1654,23 b' def import_(ui, repo, patch1, *patches, ' | |||||
1814 | d = opts["base"] |
|
1654 | d = opts["base"] | |
1815 | strip = opts["strip"] |
|
1655 | strip = opts["strip"] | |
1816 |
|
1656 | |||
1817 | mailre = re.compile(r'(?:From |[\w-]+:)') |
|
1657 | wlock = repo.wlock() | |
1818 |
|
1658 | lock = repo.lock() | ||
1819 | # attempt to detect the start of a patch |
|
1659 | ||
1820 | # (this heuristic is borrowed from quilt) |
|
1660 | for p in patches: | |
1821 | diffre = re.compile(r'^(?:Index:[ \t]|diff[ \t]|RCS file: |' + |
|
1661 | pf = os.path.join(d, p) | |
1822 | 'retrieving revision [0-9]+(\.[0-9]+)*$|' + |
|
1662 | ||
1823 | '(---|\*\*\*)[ \t])', re.MULTILINE) |
|
|||
1824 |
|
||||
1825 | for patch in patches: |
|
|||
1826 | pf = os.path.join(d, patch) |
|
|||
1827 |
|
||||
1828 | message = None |
|
|||
1829 | user = None |
|
|||
1830 | date = None |
|
|||
1831 | hgpatch = False |
|
|||
1832 |
|
||||
1833 | p = email.Parser.Parser() |
|
|||
1834 | if pf == '-': |
|
1663 | if pf == '-': | |
1835 | msg = p.parse(sys.stdin) |
|
|||
1836 | ui.status(_("applying patch from stdin\n")) |
|
1664 | ui.status(_("applying patch from stdin\n")) | |
|
1665 | tmpname, message, user, date = patch.extract(ui, sys.stdin) | |||
1837 | else: |
|
1666 | else: | |
1838 | msg = p.parse(file(pf)) |
|
1667 | ui.status(_("applying %s\n") % p) | |
1839 | ui.status(_("applying %s\n") % patch) |
|
1668 | tmpname, message, user, date = patch.extract(ui, file(pf)) | |
1840 |
|
1669 | |||
1841 | fd, tmpname = tempfile.mkstemp(prefix='hg-patch-') |
|
1670 | if tmpname is None: | |
1842 | tmpfp = os.fdopen(fd, 'w') |
|
1671 | raise util.Abort(_('no diffs found')) | |
|
1672 | ||||
1843 | try: |
|
1673 | try: | |
1844 | message = msg['Subject'] |
|
|||
1845 | if message: |
|
|||
1846 | message = message.replace('\n\t', ' ') |
|
|||
1847 | ui.debug('Subject: %s\n' % message) |
|
|||
1848 | user = msg['From'] |
|
|||
1849 | if user: |
|
|||
1850 | ui.debug('From: %s\n' % user) |
|
|||
1851 | diffs_seen = 0 |
|
|||
1852 | ok_types = ('text/plain', 'text/x-diff', 'text/x-patch') |
|
|||
1853 | for part in msg.walk(): |
|
|||
1854 | content_type = part.get_content_type() |
|
|||
1855 | ui.debug('Content-Type: %s\n' % content_type) |
|
|||
1856 | if content_type not in ok_types: |
|
|||
1857 | continue |
|
|||
1858 | payload = part.get_payload(decode=True) |
|
|||
1859 | m = diffre.search(payload) |
|
|||
1860 | if m: |
|
|||
1861 | ui.debug(_('found patch at byte %d\n') % m.start(0)) |
|
|||
1862 | diffs_seen += 1 |
|
|||
1863 | hgpatch = False |
|
|||
1864 | fp = cStringIO.StringIO() |
|
|||
1865 | if message: |
|
|||
1866 | fp.write(message) |
|
|||
1867 | fp.write('\n') |
|
|||
1868 | for line in payload[:m.start(0)].splitlines(): |
|
|||
1869 | if line.startswith('# HG changeset patch'): |
|
|||
1870 | ui.debug(_('patch generated by hg export\n')) |
|
|||
1871 | hgpatch = True |
|
|||
1872 | # drop earlier commit message content |
|
|||
1873 | fp.seek(0) |
|
|||
1874 | fp.truncate() |
|
|||
1875 | elif hgpatch: |
|
|||
1876 | if line.startswith('# User '): |
|
|||
1877 | user = line[7:] |
|
|||
1878 | ui.debug('From: %s\n' % user) |
|
|||
1879 | elif line.startswith("# Date "): |
|
|||
1880 | date = line[7:] |
|
|||
1881 | if not line.startswith('# '): |
|
|||
1882 | fp.write(line) |
|
|||
1883 | fp.write('\n') |
|
|||
1884 | message = fp.getvalue() |
|
|||
1885 | if tmpfp: |
|
|||
1886 | tmpfp.write(payload) |
|
|||
1887 | if not payload.endswith('\n'): |
|
|||
1888 | tmpfp.write('\n') |
|
|||
1889 | elif not diffs_seen and message and content_type == 'text/plain': |
|
|||
1890 | message += '\n' + payload |
|
|||
1891 |
|
||||
1892 | if opts['message']: |
|
1674 | if opts['message']: | |
1893 | # pickup the cmdline msg |
|
1675 | # pickup the cmdline msg | |
1894 | message = opts['message'] |
|
1676 | message = opts['message'] | |
@@ -1900,18 +1682,9 b' def import_(ui, repo, patch1, *patches, ' | |||||
1900 | message = None |
|
1682 | message = None | |
1901 | ui.debug(_('message:\n%s\n') % message) |
|
1683 | ui.debug(_('message:\n%s\n') % message) | |
1902 |
|
1684 | |||
1903 | tmpfp.close() |
|
1685 | files, fuzz = patch.patch(tmpname, ui, strip=strip, cwd=repo.root) | |
1904 | if not diffs_seen: |
|
1686 | files = patch.updatedir(ui, repo, files, wlock=wlock) | |
1905 | raise util.Abort(_('no diffs found')) |
|
1687 | repo.commit(files, message, user, date, wlock=wlock, lock=lock) | |
1906 |
|
||||
1907 | files = util.patch(strip, tmpname, ui, cwd=repo.root) |
|
|||
1908 | if len(files) > 0: |
|
|||
1909 | cfiles = files |
|
|||
1910 | cwd = repo.getcwd() |
|
|||
1911 | if cwd: |
|
|||
1912 | cfiles = [util.pathto(cwd, f) for f in files] |
|
|||
1913 | addremove_lock(ui, repo, cfiles, {}) |
|
|||
1914 | repo.commit(files, message, user, date) |
|
|||
1915 | finally: |
|
1688 | finally: | |
1916 | os.unlink(tmpname) |
|
1689 | os.unlink(tmpname) | |
1917 |
|
1690 | |||
@@ -1964,7 +1737,7 b' def incoming(ui, repo, source="default",' | |||||
1964 | displayer.show(changenode=n) |
|
1737 | displayer.show(changenode=n) | |
1965 | if opts['patch']: |
|
1738 | if opts['patch']: | |
1966 | prev = (parents and parents[0]) or nullid |
|
1739 | prev = (parents and parents[0]) or nullid | |
1967 |
|
|
1740 | patch.diff(other, prev, n, fp=repo.ui) | |
1968 | ui.write("\n") |
|
1741 | ui.write("\n") | |
1969 | finally: |
|
1742 | finally: | |
1970 | if hasattr(other, 'close'): |
|
1743 | if hasattr(other, 'close'): | |
@@ -2012,8 +1785,8 b' def locate(ui, repo, *pats, **opts):' | |||||
2012 | else: |
|
1785 | else: | |
2013 | node = None |
|
1786 | node = None | |
2014 |
|
1787 | |||
2015 | for src, abs, rel, exact in walk(repo, pats, opts, node=node, |
|
1788 | for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, node=node, | |
2016 | head='(?:.*/|)'): |
|
1789 | head='(?:.*/|)'): | |
2017 | if not node and repo.dirstate.state(abs) == '?': |
|
1790 | if not node and repo.dirstate.state(abs) == '?': | |
2018 | continue |
|
1791 | continue | |
2019 | if opts['fullpath']: |
|
1792 | if opts['fullpath']: | |
@@ -2115,7 +1888,7 b' def log(ui, repo, *pats, **opts):' | |||||
2115 | displayer.show(rev, brinfo=br) |
|
1888 | displayer.show(rev, brinfo=br) | |
2116 | if opts['patch']: |
|
1889 | if opts['patch']: | |
2117 | prev = (parents and parents[0]) or nullid |
|
1890 | prev = (parents and parents[0]) or nullid | |
2118 |
|
|
1891 | patch.diff(repo, prev, changenode, match=matchfn, fp=du) | |
2119 | du.write("\n\n") |
|
1892 | du.write("\n\n") | |
2120 | elif st == 'iter': |
|
1893 | elif st == 'iter': | |
2121 | if count == limit: break |
|
1894 | if count == limit: break | |
@@ -2146,12 +1919,12 b' def manifest(ui, repo, rev=None):' | |||||
2146 | else: |
|
1919 | else: | |
2147 | n = repo.manifest.tip() |
|
1920 | n = repo.manifest.tip() | |
2148 | m = repo.manifest.read(n) |
|
1921 | m = repo.manifest.read(n) | |
2149 | mf = repo.manifest.readflags(n) |
|
|||
2150 | files = m.keys() |
|
1922 | files = m.keys() | |
2151 | files.sort() |
|
1923 | files.sort() | |
2152 |
|
1924 | |||
2153 | for f in files: |
|
1925 | for f in files: | |
2154 |
ui.write("%40s %3s %s\n" % (hex(m[f]), |
|
1926 | ui.write("%40s %3s %s\n" % (hex(m[f]), | |
|
1927 | m.execf(f) and "755" or "644", f)) | |||
2155 |
|
1928 | |||
2156 | def merge(ui, repo, node=None, force=None, branch=None): |
|
1929 | def merge(ui, repo, node=None, force=None, branch=None): | |
2157 | """Merge working directory with another revision |
|
1930 | """Merge working directory with another revision | |
@@ -2160,9 +1933,29 b' def merge(ui, repo, node=None, force=Non' | |||||
2160 | requested revision. Files that changed between either parent are |
|
1933 | requested revision. Files that changed between either parent are | |
2161 | marked as changed for the next commit and a commit must be |
|
1934 | marked as changed for the next commit and a commit must be | |
2162 | performed before any further updates are allowed. |
|
1935 | performed before any further updates are allowed. | |
|
1936 | ||||
|
1937 | If no revision is specified, the working directory's parent is a | |||
|
1938 | head revision, and the repository contains exactly one other head, | |||
|
1939 | the other head is merged with by default. Otherwise, an explicit | |||
|
1940 | revision to merge with must be provided. | |||
2163 | """ |
|
1941 | """ | |
2164 |
|
1942 | |||
2165 | node = _lookup(repo, node, branch) |
|
1943 | if node: | |
|
1944 | node = _lookup(repo, node, branch) | |||
|
1945 | else: | |||
|
1946 | heads = repo.heads() | |||
|
1947 | if len(heads) > 2: | |||
|
1948 | raise util.Abort(_('repo has %d heads - ' | |||
|
1949 | 'please merge with an explicit rev') % | |||
|
1950 | len(heads)) | |||
|
1951 | if len(heads) == 1: | |||
|
1952 | raise util.Abort(_('there is nothing to merge - ' | |||
|
1953 | 'use "hg update" instead')) | |||
|
1954 | parent = repo.dirstate.parents()[0] | |||
|
1955 | if parent not in heads: | |||
|
1956 | raise util.Abort(_('working dir not at a head rev - ' | |||
|
1957 | 'use "hg update" or merge with an explicit rev')) | |||
|
1958 | node = parent == heads[0] and heads[-1] or heads[0] | |||
2166 | return hg.merge(repo, node, force=force) |
|
1959 | return hg.merge(repo, node, force=force) | |
2167 |
|
1960 | |||
2168 | def outgoing(ui, repo, dest=None, **opts): |
|
1961 | def outgoing(ui, repo, dest=None, **opts): | |
@@ -2196,7 +1989,7 b' def outgoing(ui, repo, dest=None, **opts' | |||||
2196 | displayer.show(changenode=n) |
|
1989 | displayer.show(changenode=n) | |
2197 | if opts['patch']: |
|
1990 | if opts['patch']: | |
2198 | prev = (parents and parents[0]) or nullid |
|
1991 | prev = (parents and parents[0]) or nullid | |
2199 |
|
|
1992 | patch.diff(repo, prev, n) | |
2200 | ui.write("\n") |
|
1993 | ui.write("\n") | |
2201 |
|
1994 | |||
2202 | def parents(ui, repo, file_=None, rev=None, branches=None, **opts): |
|
1995 | def parents(ui, repo, file_=None, rev=None, branches=None, **opts): | |
@@ -2409,12 +2202,12 b' def remove(ui, repo, *pats, **opts):' | |||||
2409 | names = [] |
|
2202 | names = [] | |
2410 | if not opts['after'] and not pats: |
|
2203 | if not opts['after'] and not pats: | |
2411 | raise util.Abort(_('no files specified')) |
|
2204 | raise util.Abort(_('no files specified')) | |
2412 | files, matchfn, anypats = matchpats(repo, pats, opts) |
|
2205 | files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts) | |
2413 | exact = dict.fromkeys(files) |
|
2206 | exact = dict.fromkeys(files) | |
2414 |
mardu = map(dict.fromkeys, repo. |
|
2207 | mardu = map(dict.fromkeys, repo.status(files=files, match=matchfn))[:5] | |
2415 | modified, added, removed, deleted, unknown = mardu |
|
2208 | modified, added, removed, deleted, unknown = mardu | |
2416 | remove, forget = [], [] |
|
2209 | remove, forget = [], [] | |
2417 | for src, abs, rel, exact in walk(repo, pats, opts): |
|
2210 | for src, abs, rel, exact in cmdutil.walk(repo, pats, opts): | |
2418 | reason = None |
|
2211 | reason = None | |
2419 | if abs not in deleted and opts['after']: |
|
2212 | if abs not in deleted and opts['after']: | |
2420 | reason = _('is still present') |
|
2213 | reason = _('is still present') | |
@@ -2494,8 +2287,12 b' def revert(ui, repo, *pats, **opts):' | |||||
2494 |
|
2287 | |||
2495 | If names are given, all files matching the names are reverted. |
|
2288 | If names are given, all files matching the names are reverted. | |
2496 |
|
2289 | |||
2497 |
If no arguments are given, |
|
2290 | If no arguments are given, no files are reverted. | |
2498 | """ |
|
2291 | """ | |
|
2292 | ||||
|
2293 | if not pats and not opts['all']: | |||
|
2294 | raise util.Abort(_('no files or directories specified')) | |||
|
2295 | ||||
2499 | parent, p2 = repo.dirstate.parents() |
|
2296 | parent, p2 = repo.dirstate.parents() | |
2500 | if opts['rev']: |
|
2297 | if opts['rev']: | |
2501 | node = repo.lookup(opts['rev']) |
|
2298 | node = repo.lookup(opts['rev']) | |
@@ -2521,20 +2318,21 b' def revert(ui, repo, *pats, **opts):' | |||||
2521 |
|
2318 | |||
2522 | # walk dirstate. |
|
2319 | # walk dirstate. | |
2523 |
|
2320 | |||
2524 |
for src, abs, rel, exact in walk(repo, pats, opts, |
|
2321 | for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, | |
|
2322 | badmatch=mf.has_key): | |||
2525 | names[abs] = (rel, exact) |
|
2323 | names[abs] = (rel, exact) | |
2526 | if src == 'b': |
|
2324 | if src == 'b': | |
2527 | target_only[abs] = True |
|
2325 | target_only[abs] = True | |
2528 |
|
2326 | |||
2529 | # walk target manifest. |
|
2327 | # walk target manifest. | |
2530 |
|
2328 | |||
2531 | for src, abs, rel, exact in walk(repo, pats, opts, node=node, |
|
2329 | for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, node=node, | |
2532 | badmatch=names.has_key): |
|
2330 | badmatch=names.has_key): | |
2533 | if abs in names: continue |
|
2331 | if abs in names: continue | |
2534 | names[abs] = (rel, exact) |
|
2332 | names[abs] = (rel, exact) | |
2535 | target_only[abs] = True |
|
2333 | target_only[abs] = True | |
2536 |
|
2334 | |||
2537 |
changes = repo. |
|
2335 | changes = repo.status(match=names.has_key, wlock=wlock)[:5] | |
2538 | modified, added, removed, deleted, unknown = map(dict.fromkeys, changes) |
|
2336 | modified, added, removed, deleted, unknown = map(dict.fromkeys, changes) | |
2539 |
|
2337 | |||
2540 | revert = ([], _('reverting %s\n')) |
|
2338 | revert = ([], _('reverting %s\n')) | |
@@ -2741,7 +2539,7 b' def status(ui, repo, *pats, **opts):' | |||||
2741 |
|
2539 | |||
2742 | all = opts['all'] |
|
2540 | all = opts['all'] | |
2743 |
|
2541 | |||
2744 | files, matchfn, anypats = matchpats(repo, pats, opts) |
|
2542 | files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts) | |
2745 | cwd = (pats and repo.getcwd()) or '' |
|
2543 | cwd = (pats and repo.getcwd()) or '' | |
2746 | modified, added, removed, deleted, unknown, ignored, clean = [ |
|
2544 | modified, added, removed, deleted, unknown, ignored, clean = [ | |
2747 | [util.pathto(cwd, x) for x in n] |
|
2545 | [util.pathto(cwd, x) for x in n] | |
@@ -2801,17 +2599,20 b' def tag(ui, repo, name, rev_=None, **opt' | |||||
2801 | if opts['rev']: |
|
2599 | if opts['rev']: | |
2802 | rev_ = opts['rev'] |
|
2600 | rev_ = opts['rev'] | |
2803 | if rev_: |
|
2601 | if rev_: | |
2804 |
r = |
|
2602 | r = repo.lookup(rev_) | |
2805 | else: |
|
2603 | else: | |
2806 | p1, p2 = repo.dirstate.parents() |
|
2604 | p1, p2 = repo.dirstate.parents() | |
2807 | if p1 == nullid: |
|
2605 | if p1 == nullid: | |
2808 | raise util.Abort(_('no revision to tag')) |
|
2606 | raise util.Abort(_('no revision to tag')) | |
2809 | if p2 != nullid: |
|
2607 | if p2 != nullid: | |
2810 | raise util.Abort(_('outstanding uncommitted merges')) |
|
2608 | raise util.Abort(_('outstanding uncommitted merges')) | |
2811 |
r = |
|
2609 | r = p1 | |
2812 |
|
2610 | |||
2813 | repo.tag(name, r, opts['local'], opts['message'], opts['user'], |
|
2611 | message = opts['message'] | |
2814 | opts['date']) |
|
2612 | if not message: | |
|
2613 | message = _('Added tag %s for changeset %s') % (name, short(r)) | |||
|
2614 | ||||
|
2615 | repo.tag(name, r, message, opts['local'], opts['user'], opts['date']) | |||
2815 |
|
2616 | |||
2816 | def tags(ui, repo): |
|
2617 | def tags(ui, repo): | |
2817 | """list repository tags |
|
2618 | """list repository tags | |
@@ -2823,9 +2624,10 b' def tags(ui, repo):' | |||||
2823 |
|
2624 | |||
2824 | l = repo.tagslist() |
|
2625 | l = repo.tagslist() | |
2825 | l.reverse() |
|
2626 | l.reverse() | |
|
2627 | hexfunc = ui.debugflag and hex or short | |||
2826 | for t, n in l: |
|
2628 | for t, n in l: | |
2827 | try: |
|
2629 | try: | |
2828 | r = "%5d:%s" % (repo.changelog.rev(n), hex(n)) |
|
2630 | r = "%5d:%s" % (repo.changelog.rev(n), hexfunc(n)) | |
2829 | except KeyError: |
|
2631 | except KeyError: | |
2830 | r = " ?:?" |
|
2632 | r = " ?:?" | |
2831 | if ui.quiet: |
|
2633 | if ui.quiet: | |
@@ -2844,7 +2646,7 b' def tip(ui, repo, **opts):' | |||||
2844 | br = repo.branchlookup([n]) |
|
2646 | br = repo.branchlookup([n]) | |
2845 | show_changeset(ui, repo, opts).show(changenode=n, brinfo=br) |
|
2647 | show_changeset(ui, repo, opts).show(changenode=n, brinfo=br) | |
2846 | if opts['patch']: |
|
2648 | if opts['patch']: | |
2847 |
|
|
2649 | patch.diff(repo, repo.changelog.parents(n)[0], n) | |
2848 |
|
2650 | |||
2849 | def unbundle(ui, repo, fname, **opts): |
|
2651 | def unbundle(ui, repo, fname, **opts): | |
2850 | """apply a changegroup file |
|
2652 | """apply a changegroup file | |
@@ -2957,11 +2759,14 b' table = {' | |||||
2957 | ('X', 'exclude', [], _('exclude names matching the given patterns')), |
|
2759 | ('X', 'exclude', [], _('exclude names matching the given patterns')), | |
2958 | ('n', 'dry-run', None, _('do not perform actions, just print output'))], |
|
2760 | ('n', 'dry-run', None, _('do not perform actions, just print output'))], | |
2959 | _('hg add [OPTION]... [FILE]...')), |
|
2761 | _('hg add [OPTION]... [FILE]...')), | |
2960 |
" |
|
2762 | "addremove": | |
2961 | (addremove, |
|
2763 | (addremove, | |
2962 | [('I', 'include', [], _('include names matching the given patterns')), |
|
2764 | [('I', 'include', [], _('include names matching the given patterns')), | |
2963 | ('X', 'exclude', [], _('exclude names matching the given patterns')), |
|
2765 | ('X', 'exclude', [], _('exclude names matching the given patterns')), | |
2964 | ('n', 'dry-run', None, _('do not perform actions, just print output'))], |
|
2766 | ('n', 'dry-run', None, | |
|
2767 | _('do not perform actions, just print output')), | |||
|
2768 | ('s', 'similarity', '', | |||
|
2769 | _('guess renamed files by similarity (0<=s<=1)'))], | |||
2965 | _('hg addremove [OPTION]... [FILE]...')), |
|
2770 | _('hg addremove [OPTION]... [FILE]...')), | |
2966 | "^annotate": |
|
2771 | "^annotate": | |
2967 | (annotate, |
|
2772 | (annotate, | |
@@ -3067,6 +2872,7 b' table = {' | |||||
3067 | ('a', 'text', None, _('treat all files as text')), |
|
2872 | ('a', 'text', None, _('treat all files as text')), | |
3068 | ('p', 'show-function', None, |
|
2873 | ('p', 'show-function', None, | |
3069 | _('show which function each change is in')), |
|
2874 | _('show which function each change is in')), | |
|
2875 | ('g', 'git', None, _('use git extended diff format')), | |||
3070 | ('w', 'ignore-all-space', None, |
|
2876 | ('w', 'ignore-all-space', None, | |
3071 | _('ignore white space when comparing lines')), |
|
2877 | _('ignore white space when comparing lines')), | |
3072 | ('b', 'ignore-space-change', None, |
|
2878 | ('b', 'ignore-space-change', None, | |
@@ -3091,6 +2897,8 b' table = {' | |||||
3091 | (grep, |
|
2897 | (grep, | |
3092 | [('0', 'print0', None, _('end fields with NUL')), |
|
2898 | [('0', 'print0', None, _('end fields with NUL')), | |
3093 | ('', 'all', None, _('print all revisions that match')), |
|
2899 | ('', 'all', None, _('print all revisions that match')), | |
|
2900 | ('f', 'follow', None, | |||
|
2901 | _('follow changeset history, or file history across copies and renames')), | |||
3094 | ('i', 'ignore-case', None, _('ignore case when matching')), |
|
2902 | ('i', 'ignore-case', None, _('ignore case when matching')), | |
3095 | ('l', 'files-with-matches', None, |
|
2903 | ('l', 'files-with-matches', None, | |
3096 | _('print only filenames and revs that match')), |
|
2904 | _('print only filenames and revs that match')), | |
@@ -3127,7 +2935,7 b' table = {' | |||||
3127 | ('n', 'newest-first', None, _('show newest record first')), |
|
2935 | ('n', 'newest-first', None, _('show newest record first')), | |
3128 | ('', 'bundle', '', _('file to store the bundles into')), |
|
2936 | ('', 'bundle', '', _('file to store the bundles into')), | |
3129 | ('p', 'patch', None, _('show patch')), |
|
2937 | ('p', 'patch', None, _('show patch')), | |
3130 | ('r', 'rev', [], _('a specific revision you would like to pull')), |
|
2938 | ('r', 'rev', [], _('a specific revision up to which you would like to pull')), | |
3131 | ('', 'template', '', _('display with template')), |
|
2939 | ('', 'template', '', _('display with template')), | |
3132 | ('e', 'ssh', '', _('specify ssh command to use')), |
|
2940 | ('e', 'ssh', '', _('specify ssh command to use')), | |
3133 | ('', 'remotecmd', '', |
|
2941 | ('', 'remotecmd', '', | |
@@ -3164,6 +2972,7 b' table = {' | |||||
3164 | ('', 'style', '', _('display using template map file')), |
|
2972 | ('', 'style', '', _('display using template map file')), | |
3165 | ('m', 'only-merges', None, _('show only merges')), |
|
2973 | ('m', 'only-merges', None, _('show only merges')), | |
3166 | ('p', 'patch', None, _('show patch')), |
|
2974 | ('p', 'patch', None, _('show patch')), | |
|
2975 | ('P', 'prune', [], _('do not display revision or any of its ancestors')), | |||
3167 | ('', 'template', '', _('display with template')), |
|
2976 | ('', 'template', '', _('display with template')), | |
3168 | ('I', 'include', [], _('include names matching the given patterns')), |
|
2977 | ('I', 'include', [], _('include names matching the given patterns')), | |
3169 | ('X', 'exclude', [], _('exclude names matching the given patterns'))], |
|
2978 | ('X', 'exclude', [], _('exclude names matching the given patterns'))], | |
@@ -3202,7 +3011,7 b' table = {' | |||||
3202 | ('e', 'ssh', '', _('specify ssh command to use')), |
|
3011 | ('e', 'ssh', '', _('specify ssh command to use')), | |
3203 | ('f', 'force', None, |
|
3012 | ('f', 'force', None, | |
3204 | _('run even when remote repository is unrelated')), |
|
3013 | _('run even when remote repository is unrelated')), | |
3205 | ('r', 'rev', [], _('a specific revision you would like to pull')), |
|
3014 | ('r', 'rev', [], _('a specific revision up to which you would like to pull')), | |
3206 | ('', 'remotecmd', '', |
|
3015 | ('', 'remotecmd', '', | |
3207 | _('specify hg command to run on the remote side'))], |
|
3016 | _('specify hg command to run on the remote side'))], | |
3208 | _('hg pull [-u] [-r REV]... [-e FILE] [--remotecmd FILE] [SOURCE]')), |
|
3017 | _('hg pull [-u] [-r REV]... [-e FILE] [--remotecmd FILE] [SOURCE]')), | |
@@ -3242,7 +3051,8 b' table = {' | |||||
3242 | _('hg rename [OPTION]... SOURCE... DEST')), |
|
3051 | _('hg rename [OPTION]... SOURCE... DEST')), | |
3243 | "^revert": |
|
3052 | "^revert": | |
3244 | (revert, |
|
3053 | (revert, | |
3245 | [('r', 'rev', '', _('revision to revert to')), |
|
3054 | [('a', 'all', None, _('revert all changes when no arguments given')), | |
|
3055 | ('r', 'rev', '', _('revision to revert to')), | |||
3246 | ('', 'no-backup', None, _('do not save backup copies of files')), |
|
3056 | ('', 'no-backup', None, _('do not save backup copies of files')), | |
3247 | ('I', 'include', [], _('include names matching given patterns')), |
|
3057 | ('I', 'include', [], _('include names matching given patterns')), | |
3248 | ('X', 'exclude', [], _('exclude names matching given patterns')), |
|
3058 | ('X', 'exclude', [], _('exclude names matching given patterns')), | |
@@ -3341,7 +3151,7 b' norepo = ("clone init version help debug' | |||||
3341 | " debugindex debugindexdot") |
|
3151 | " debugindex debugindexdot") | |
3342 | optionalrepo = ("paths serve debugconfig") |
|
3152 | optionalrepo = ("paths serve debugconfig") | |
3343 |
|
3153 | |||
3344 | def findpossible(cmd): |
|
3154 | def findpossible(ui, cmd): | |
3345 | """ |
|
3155 | """ | |
3346 | Return cmd -> (aliases, command table entry) |
|
3156 | Return cmd -> (aliases, command table entry) | |
3347 | for each matching command. |
|
3157 | for each matching command. | |
@@ -3354,7 +3164,7 b' def findpossible(cmd):' | |||||
3354 | found = None |
|
3164 | found = None | |
3355 | if cmd in aliases: |
|
3165 | if cmd in aliases: | |
3356 | found = cmd |
|
3166 | found = cmd | |
3357 | else: |
|
3167 | elif not ui.config("ui", "strict"): | |
3358 | for a in aliases: |
|
3168 | for a in aliases: | |
3359 | if a.startswith(cmd): |
|
3169 | if a.startswith(cmd): | |
3360 | found = a |
|
3170 | found = a | |
@@ -3370,9 +3180,9 b' def findpossible(cmd):' | |||||
3370 |
|
3180 | |||
3371 | return choice |
|
3181 | return choice | |
3372 |
|
3182 | |||
3373 | def findcmd(cmd): |
|
3183 | def findcmd(ui, cmd): | |
3374 | """Return (aliases, command table entry) for command string.""" |
|
3184 | """Return (aliases, command table entry) for command string.""" | |
3375 | choice = findpossible(cmd) |
|
3185 | choice = findpossible(ui, cmd) | |
3376 |
|
3186 | |||
3377 | if choice.has_key(cmd): |
|
3187 | if choice.has_key(cmd): | |
3378 | return choice[cmd] |
|
3188 | return choice[cmd] | |
@@ -3407,7 +3217,7 b' def parse(ui, args):' | |||||
3407 |
|
3217 | |||
3408 | if args: |
|
3218 | if args: | |
3409 | cmd, args = args[0], args[1:] |
|
3219 | cmd, args = args[0], args[1:] | |
3410 | aliases, i = findcmd(cmd) |
|
3220 | aliases, i = findcmd(ui, cmd) | |
3411 | cmd = aliases[0] |
|
3221 | cmd = aliases[0] | |
3412 | defaults = ui.config("defaults", cmd) |
|
3222 | defaults = ui.config("defaults", cmd) | |
3413 | if defaults: |
|
3223 | if defaults: | |
@@ -3446,18 +3256,11 b' def findext(name):' | |||||
3446 | return sys.modules[v] |
|
3256 | return sys.modules[v] | |
3447 | raise KeyError(name) |
|
3257 | raise KeyError(name) | |
3448 |
|
3258 | |||
3449 | def dispatch(args): |
|
3259 | def load_extensions(ui): | |
3450 | for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM': |
|
3260 | added = [] | |
3451 | num = getattr(signal, name, None) |
|
3261 | for ext_name, load_from_name in ui.extensions(): | |
3452 | if num: signal.signal(num, catchterm) |
|
3262 | if ext_name in external: | |
3453 |
|
3263 | continue | ||
3454 | try: |
|
|||
3455 | u = ui.ui(traceback='--traceback' in sys.argv[1:]) |
|
|||
3456 | except util.Abort, inst: |
|
|||
3457 | sys.stderr.write(_("abort: %s\n") % inst) |
|
|||
3458 | return -1 |
|
|||
3459 |
|
||||
3460 | for ext_name, load_from_name in u.extensions(): |
|
|||
3461 | try: |
|
3264 | try: | |
3462 | if load_from_name: |
|
3265 | if load_from_name: | |
3463 | # the module will be loaded in sys.modules |
|
3266 | # the module will be loaded in sys.modules | |
@@ -3477,23 +3280,36 b' def dispatch(args):' | |||||
3477 | except ImportError: |
|
3280 | except ImportError: | |
3478 | mod = importh(ext_name) |
|
3281 | mod = importh(ext_name) | |
3479 | external[ext_name] = mod.__name__ |
|
3282 | external[ext_name] = mod.__name__ | |
|
3283 | added.append((mod, ext_name)) | |||
3480 | except (util.SignalInterrupt, KeyboardInterrupt): |
|
3284 | except (util.SignalInterrupt, KeyboardInterrupt): | |
3481 | raise |
|
3285 | raise | |
3482 | except Exception, inst: |
|
3286 | except Exception, inst: | |
3483 |
u.warn(_("*** failed to import extension %s: %s\n") % |
|
3287 | ui.warn(_("*** failed to import extension %s: %s\n") % | |
3484 | if u.print_exc(): |
|
3288 | (ext_name, inst)) | |
|
3289 | if ui.print_exc(): | |||
3485 | return 1 |
|
3290 | return 1 | |
3486 |
|
3291 | |||
3487 | for name in external.itervalues(): |
|
3292 | for mod, name in added: | |
3488 | mod = sys.modules[name] |
|
|||
3489 | uisetup = getattr(mod, 'uisetup', None) |
|
3293 | uisetup = getattr(mod, 'uisetup', None) | |
3490 | if uisetup: |
|
3294 | if uisetup: | |
3491 | uisetup(u) |
|
3295 | uisetup(ui) | |
3492 | cmdtable = getattr(mod, 'cmdtable', {}) |
|
3296 | cmdtable = getattr(mod, 'cmdtable', {}) | |
3493 | for t in cmdtable: |
|
3297 | for t in cmdtable: | |
3494 | if t in table: |
|
3298 | if t in table: | |
3495 | u.warn(_("module %s overrides %s\n") % (name, t)) |
|
3299 | ui.warn(_("module %s overrides %s\n") % (name, t)) | |
3496 | table.update(cmdtable) |
|
3300 | table.update(cmdtable) | |
|
3301 | ||||
|
3302 | def dispatch(args): | |||
|
3303 | for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM': | |||
|
3304 | num = getattr(signal, name, None) | |||
|
3305 | if num: signal.signal(num, catchterm) | |||
|
3306 | ||||
|
3307 | try: | |||
|
3308 | u = ui.ui(traceback='--traceback' in sys.argv[1:], | |||
|
3309 | readhooks=[load_extensions]) | |||
|
3310 | except util.Abort, inst: | |||
|
3311 | sys.stderr.write(_("abort: %s\n") % inst) | |||
|
3312 | return -1 | |||
3497 |
|
3313 | |||
3498 | try: |
|
3314 | try: | |
3499 | cmd, func, args, options, cmdoptions = parse(u, args) |
|
3315 | cmd, func, args, options, cmdoptions = parse(u, args) | |
@@ -3545,6 +3361,7 b' def dispatch(args):' | |||||
3545 | mod = sys.modules[name] |
|
3361 | mod = sys.modules[name] | |
3546 | if hasattr(mod, 'reposetup'): |
|
3362 | if hasattr(mod, 'reposetup'): | |
3547 | mod.reposetup(u, repo) |
|
3363 | mod.reposetup(u, repo) | |
|
3364 | hg.repo_setup_hooks.append(mod.reposetup) | |||
3548 | except hg.RepoError: |
|
3365 | except hg.RepoError: | |
3549 | if cmd not in optionalrepo.split(): |
|
3366 | if cmd not in optionalrepo.split(): | |
3550 | raise |
|
3367 | raise |
@@ -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. |
@@ -109,9 +109,9 b' def demandload(scope, modules):' | |||||
109 | mod = mod[:col] |
|
109 | mod = mod[:col] | |
110 | else: |
|
110 | else: | |
111 | fromlist = [] |
|
111 | fromlist = [] | |
112 | as = None |
|
112 | as_ = None | |
113 | if '@' in mod: |
|
113 | if '@' in mod: | |
114 | mod, as = mod.split("@") |
|
114 | mod, as_ = mod.split("@") | |
115 | importer = _importer(scope, mod, fromlist) |
|
115 | importer = _importer(scope, mod, fromlist) | |
116 | if fromlist: |
|
116 | if fromlist: | |
117 | for name in fromlist: |
|
117 | for name in fromlist: | |
@@ -130,6 +130,6 b' def demandload(scope, modules):' | |||||
130 | continue |
|
130 | continue | |
131 | else: |
|
131 | else: | |
132 | basemod = mod |
|
132 | basemod = mod | |
133 | if not as: |
|
133 | if not as_: | |
134 | as = basemod |
|
134 | as_ = basemod | |
135 | scope[as] = _replacer(importer, as) |
|
135 | scope[as_] = _replacer(importer, as_) |
@@ -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. | |
@@ -10,7 +10,7 b' of the GNU General Public License, incor' | |||||
10 | from node import * |
|
10 | from node import * | |
11 | from i18n import gettext as _ |
|
11 | from i18n import gettext as _ | |
12 | from demandload import * |
|
12 | from demandload import * | |
13 | demandload(globals(), "struct os time bisect stat util re errno") |
|
13 | demandload(globals(), "struct os time bisect stat strutil util re errno") | |
14 |
|
14 | |||
15 | class dirstate(object): |
|
15 | class dirstate(object): | |
16 | format = ">cllll" |
|
16 | format = ">cllll" | |
@@ -22,6 +22,7 b' class dirstate(object):' | |||||
22 | self.ui = ui |
|
22 | self.ui = ui | |
23 | self.map = None |
|
23 | self.map = None | |
24 | self.pl = None |
|
24 | self.pl = None | |
|
25 | self.dirs = None | |||
25 | self.copies = {} |
|
26 | self.copies = {} | |
26 | self.ignorefunc = None |
|
27 | self.ignorefunc = None | |
27 | self.blockignore = False |
|
28 | self.blockignore = False | |
@@ -197,6 +198,38 b' class dirstate(object):' | |||||
197 | def copied(self, file): |
|
198 | def copied(self, file): | |
198 | return self.copies.get(file, None) |
|
199 | return self.copies.get(file, None) | |
199 |
|
200 | |||
|
201 | def initdirs(self): | |||
|
202 | if self.dirs is None: | |||
|
203 | self.dirs = {} | |||
|
204 | for f in self.map: | |||
|
205 | self.updatedirs(f, 1) | |||
|
206 | ||||
|
207 | def updatedirs(self, path, delta): | |||
|
208 | if self.dirs is not None: | |||
|
209 | for c in strutil.findall(path, '/'): | |||
|
210 | pc = path[:c] | |||
|
211 | self.dirs.setdefault(pc, 0) | |||
|
212 | self.dirs[pc] += delta | |||
|
213 | ||||
|
214 | def checkshadows(self, files): | |||
|
215 | def prefixes(f): | |||
|
216 | for c in strutil.rfindall(f, '/'): | |||
|
217 | yield f[:c] | |||
|
218 | self.lazyread() | |||
|
219 | self.initdirs() | |||
|
220 | seendirs = {} | |||
|
221 | for f in files: | |||
|
222 | if self.dirs.get(f): | |||
|
223 | raise util.Abort(_('directory named %r already in dirstate') % | |||
|
224 | f) | |||
|
225 | for d in prefixes(f): | |||
|
226 | if d in seendirs: | |||
|
227 | break | |||
|
228 | if d in self.map: | |||
|
229 | raise util.Abort(_('file named %r already in dirstate') % | |||
|
230 | d) | |||
|
231 | seendirs[d] = True | |||
|
232 | ||||
200 | def update(self, files, state, **kw): |
|
233 | def update(self, files, state, **kw): | |
201 | ''' current states: |
|
234 | ''' current states: | |
202 | n normal |
|
235 | n normal | |
@@ -207,10 +240,16 b' class dirstate(object):' | |||||
207 | if not files: return |
|
240 | if not files: return | |
208 | self.lazyread() |
|
241 | self.lazyread() | |
209 | self.markdirty() |
|
242 | self.markdirty() | |
|
243 | if state == "a": | |||
|
244 | self.initdirs() | |||
|
245 | self.checkshadows(files) | |||
210 | for f in files: |
|
246 | for f in files: | |
211 | if state == "r": |
|
247 | if state == "r": | |
212 | self.map[f] = ('r', 0, 0, 0) |
|
248 | self.map[f] = ('r', 0, 0, 0) | |
|
249 | self.updatedirs(f, -1) | |||
213 | else: |
|
250 | else: | |
|
251 | if state == "a": | |||
|
252 | self.updatedirs(f, 1) | |||
214 | s = os.lstat(self.wjoin(f)) |
|
253 | s = os.lstat(self.wjoin(f)) | |
215 | st_size = kw.get('st_size', s.st_size) |
|
254 | st_size = kw.get('st_size', s.st_size) | |
216 | st_mtime = kw.get('st_mtime', s.st_mtime) |
|
255 | st_mtime = kw.get('st_mtime', s.st_mtime) | |
@@ -222,9 +261,11 b' class dirstate(object):' | |||||
222 | if not files: return |
|
261 | if not files: return | |
223 | self.lazyread() |
|
262 | self.lazyread() | |
224 | self.markdirty() |
|
263 | self.markdirty() | |
|
264 | self.initdirs() | |||
225 | for f in files: |
|
265 | for f in files: | |
226 | try: |
|
266 | try: | |
227 | del self.map[f] |
|
267 | del self.map[f] | |
|
268 | self.updatedirs(f, -1) | |||
228 | except KeyError: |
|
269 | except KeyError: | |
229 | self.ui.warn(_("not in dirstate: %s!\n") % f) |
|
270 | self.ui.warn(_("not in dirstate: %s!\n") % f) | |
230 | pass |
|
271 | pass | |
@@ -232,14 +273,15 b' class dirstate(object):' | |||||
232 | def clear(self): |
|
273 | def clear(self): | |
233 | self.map = {} |
|
274 | self.map = {} | |
234 | self.copies = {} |
|
275 | self.copies = {} | |
|
276 | self.dirs = None | |||
235 | self.markdirty() |
|
277 | self.markdirty() | |
236 |
|
278 | |||
237 | def rebuild(self, parent, files): |
|
279 | def rebuild(self, parent, files): | |
238 | self.clear() |
|
280 | self.clear() | |
239 | umask = os.umask(0) |
|
281 | umask = os.umask(0) | |
240 | os.umask(umask) |
|
282 | os.umask(umask) | |
241 |
for f |
|
283 | for f in files: | |
242 |
if |
|
284 | if files.execf(f): | |
243 | self.map[f] = ('n', ~umask, -1, 0) |
|
285 | self.map[f] = ('n', ~umask, -1, 0) | |
244 | else: |
|
286 | else: | |
245 | self.map[f] = ('n', ~umask & 0666, -1, 0) |
|
287 | self.map[f] = ('n', ~umask & 0666, -1, 0) | |
@@ -476,7 +518,7 b' class dirstate(object):' | |||||
476 | if size >= 0 and (size != st.st_size |
|
518 | if size >= 0 and (size != st.st_size | |
477 | or (mode ^ st.st_mode) & 0100): |
|
519 | or (mode ^ st.st_mode) & 0100): | |
478 | modified.append(fn) |
|
520 | modified.append(fn) | |
479 | elif time != st.st_mtime: |
|
521 | elif time != int(st.st_mtime): | |
480 | lookup.append(fn) |
|
522 | lookup.append(fn) | |
481 | elif list_clean: |
|
523 | elif list_clean: | |
482 | clean.append(fn) |
|
524 | clean.append(fn) |
@@ -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. | |
@@ -65,6 +65,26 b' class filelog(revlog):' | |||||
65 | return (m["copy"], bin(m["copyrev"])) |
|
65 | return (m["copy"], bin(m["copyrev"])) | |
66 | return False |
|
66 | return False | |
67 |
|
67 | |||
|
68 | def size(self, rev): | |||
|
69 | """return the size of a given revision""" | |||
|
70 | ||||
|
71 | # for revisions with renames, we have to go the slow way | |||
|
72 | node = self.node(rev) | |||
|
73 | if self.renamed(node): | |||
|
74 | return len(self.read(node)) | |||
|
75 | ||||
|
76 | return revlog.size(self, rev) | |||
|
77 | ||||
|
78 | def cmp(self, node, text): | |||
|
79 | """compare text with a given file revision""" | |||
|
80 | ||||
|
81 | # for renames, we have to go the slow way | |||
|
82 | if self.renamed(node): | |||
|
83 | t2 = self.read(node) | |||
|
84 | return t2 != text | |||
|
85 | ||||
|
86 | return revlog.cmp(self, node, text) | |||
|
87 | ||||
68 | def annotate(self, node): |
|
88 | def annotate(self, node): | |
69 |
|
89 | |||
70 | def decorate(text, rev): |
|
90 | def decorate(text, rev): | |
@@ -76,31 +96,59 b' class filelog(revlog):' | |||||
76 | return child |
|
96 | return child | |
77 |
|
97 | |||
78 | # find all ancestors |
|
98 | # find all ancestors | |
79 | needed = {node:1} |
|
99 | needed = {(self, node):1} | |
80 |
|
|
100 | files = [self] | |
|
101 | visit = [(self, node)] | |||
81 | while visit: |
|
102 | while visit: | |
82 | n = visit.pop(0) |
|
103 | f, n = visit.pop(0) | |
83 |
|
|
104 | rn = f.renamed(n) | |
84 |
|
|
105 | if rn: | |
85 |
|
|
106 | f, n = rn | |
86 | visit.append(p) |
|
107 | f = filelog(self.opener, f, self.defversion) | |
|
108 | files.insert(0, f) | |||
|
109 | if (f, n) not in needed: | |||
|
110 | needed[(f, n)] = 1 | |||
|
111 | else: | |||
|
112 | needed[(f, n)] += 1 | |||
|
113 | for p in f.parents(n): | |||
|
114 | if p == nullid: | |||
|
115 | continue | |||
|
116 | if (f, p) not in needed: | |||
|
117 | needed[(f, p)] = 1 | |||
|
118 | visit.append((f, p)) | |||
87 | else: |
|
119 | else: | |
88 | # count how many times we'll use this |
|
120 | # count how many times we'll use this | |
89 | needed[p] += 1 |
|
121 | needed[(f, p)] += 1 | |
90 |
|
122 | |||
91 | # sort by revision which is a topological order |
|
123 | # sort by revision (per file) which is a topological order | |
92 | visit = [ (self.rev(n), n) for n in needed.keys() ] |
|
124 | visit = [] | |
93 | visit.sort() |
|
125 | for f in files: | |
|
126 | fn = [(f.rev(n[1]), f, n[1]) for n in needed.keys() if n[0] == f] | |||
|
127 | fn.sort() | |||
|
128 | visit.extend(fn) | |||
94 | hist = {} |
|
129 | hist = {} | |
95 |
|
130 | |||
96 |
for |
|
131 | for i in range(len(visit)): | |
97 | curr = decorate(self.read(n), self.linkrev(n)) |
|
132 | r, f, n = visit[i] | |
98 | for p in self.parents(n): |
|
133 | curr = decorate(f.read(n), f.linkrev(n)) | |
|
134 | if r == -1: | |||
|
135 | continue | |||
|
136 | parents = f.parents(n) | |||
|
137 | # follow parents across renames | |||
|
138 | if r < 1 and i > 0: | |||
|
139 | j = i | |||
|
140 | while j > 0 and visit[j][1] == f: | |||
|
141 | j -= 1 | |||
|
142 | parents = (visit[j][2],) | |||
|
143 | f = visit[j][1] | |||
|
144 | else: | |||
|
145 | parents = f.parents(n) | |||
|
146 | for p in parents: | |||
99 | if p != nullid: |
|
147 | if p != nullid: | |
100 | curr = pair(hist[p], curr) |
|
148 | curr = pair(hist[p], curr) | |
101 | # trim the history of unneeded revs |
|
149 | # trim the history of unneeded revs | |
102 | needed[p] -= 1 |
|
150 | needed[(f, p)] -= 1 | |
103 | if not needed[p]: |
|
151 | if not needed[(f, p)]: | |
104 | del hist[p] |
|
152 | del hist[p] | |
105 | hist[n] = curr |
|
153 | hist[n] = curr | |
106 |
|
154 |
@@ -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. | |
@@ -48,9 +49,14 b' def islocal(repo):' | |||||
48 | return False |
|
49 | return False | |
49 | return repo.local() |
|
50 | return repo.local() | |
50 |
|
51 | |||
|
52 | repo_setup_hooks = [] | |||
|
53 | ||||
51 | def repository(ui, path=None, create=False): |
|
54 | def repository(ui, path=None, create=False): | |
52 | """return a repository object for the specified path""" |
|
55 | """return a repository object for the specified path""" | |
53 |
re |
|
56 | repo = _lookup(path).instance(ui, path, create) | |
|
57 | for hook in repo_setup_hooks: | |||
|
58 | hook(ui, repo) | |||
|
59 | return repo | |||
54 |
|
60 | |||
55 | def defaultdest(source): |
|
61 | def defaultdest(source): | |
56 | '''return default destination of clone if none is given''' |
|
62 | '''return default destination of clone if none is given''' |
@@ -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. | |
@@ -11,7 +11,7 b' import os.path' | |||||
11 | import mimetypes |
|
11 | import mimetypes | |
12 | from mercurial.demandload import demandload |
|
12 | from mercurial.demandload import demandload | |
13 | demandload(globals(), "re zlib ConfigParser mimetools cStringIO sys tempfile") |
|
13 | demandload(globals(), "re zlib ConfigParser mimetools cStringIO sys tempfile") | |
14 | demandload(globals(), "mercurial:mdiff,ui,hg,util,archival,streamclone") |
|
14 | demandload(globals(), "mercurial:mdiff,ui,hg,util,archival,streamclone,patch") | |
15 | demandload(globals(), "mercurial:templater") |
|
15 | demandload(globals(), "mercurial:templater") | |
16 | demandload(globals(), "mercurial.hgweb.common:get_mtime,staticfile") |
|
16 | demandload(globals(), "mercurial.hgweb.common:get_mtime,staticfile") | |
17 | from mercurial.node import * |
|
17 | from mercurial.node import * | |
@@ -129,37 +129,27 b' class hgweb(object):' | |||||
129 | date1 = util.datestr(change1[2]) |
|
129 | date1 = util.datestr(change1[2]) | |
130 | date2 = util.datestr(change2[2]) |
|
130 | date2 = util.datestr(change2[2]) | |
131 |
|
131 | |||
132 |
modified, added, removed, deleted, unknown = r. |
|
132 | modified, added, removed, deleted, unknown = r.status(node1, node2)[:5] | |
133 | if files: |
|
133 | if files: | |
134 | modified, added, removed = map(lambda x: filterfiles(files, x), |
|
134 | modified, added, removed = map(lambda x: filterfiles(files, x), | |
135 | (modified, added, removed)) |
|
135 | (modified, added, removed)) | |
136 |
|
136 | |||
137 |
diffopts = self.repo.ui |
|
137 | diffopts = patch.diffopts(self.repo.ui) | |
138 | showfunc = diffopts['showfunc'] |
|
|||
139 | ignorews = diffopts['ignorews'] |
|
|||
140 | ignorewsamount = diffopts['ignorewsamount'] |
|
|||
141 | ignoreblanklines = diffopts['ignoreblanklines'] |
|
|||
142 | for f in modified: |
|
138 | for f in modified: | |
143 | to = r.file(f).read(mmap1[f]) |
|
139 | to = r.file(f).read(mmap1[f]) | |
144 | tn = r.file(f).read(mmap2[f]) |
|
140 | tn = r.file(f).read(mmap2[f]) | |
145 | yield diffblock(mdiff.unidiff(to, date1, tn, date2, f, |
|
141 | yield diffblock(mdiff.unidiff(to, date1, tn, date2, f, | |
146 | showfunc=showfunc, ignorews=ignorews, |
|
142 | opts=diffopts), f, tn) | |
147 | ignorewsamount=ignorewsamount, |
|
|||
148 | ignoreblanklines=ignoreblanklines), f, tn) |
|
|||
149 | for f in added: |
|
143 | for f in added: | |
150 | to = None |
|
144 | to = None | |
151 | tn = r.file(f).read(mmap2[f]) |
|
145 | tn = r.file(f).read(mmap2[f]) | |
152 | yield diffblock(mdiff.unidiff(to, date1, tn, date2, f, |
|
146 | yield diffblock(mdiff.unidiff(to, date1, tn, date2, f, | |
153 | showfunc=showfunc, ignorews=ignorews, |
|
147 | opts=diffopts), f, tn) | |
154 | ignorewsamount=ignorewsamount, |
|
|||
155 | ignoreblanklines=ignoreblanklines), f, tn) |
|
|||
156 | for f in removed: |
|
148 | for f in removed: | |
157 | to = r.file(f).read(mmap1[f]) |
|
149 | to = r.file(f).read(mmap1[f]) | |
158 | tn = None |
|
150 | tn = None | |
159 | yield diffblock(mdiff.unidiff(to, date1, tn, date2, f, |
|
151 | yield diffblock(mdiff.unidiff(to, date1, tn, date2, f, | |
160 | showfunc=showfunc, ignorews=ignorews, |
|
152 | opts=diffopts), f, tn) | |
161 | ignorewsamount=ignorewsamount, |
|
|||
162 | ignoreblanklines=ignoreblanklines), f, tn) |
|
|||
163 |
|
153 | |||
164 | def changelog(self, pos, shortlog=False): |
|
154 | def changelog(self, pos, shortlog=False): | |
165 | def changenav(**map): |
|
155 | def changenav(**map): | |
@@ -398,7 +388,7 b' class hgweb(object):' | |||||
398 | parent=self.siblings(fl.parents(n), fl.rev, file=f), |
|
388 | parent=self.siblings(fl.parents(n), fl.rev, file=f), | |
399 | child=self.siblings(fl.children(n), fl.rev, file=f), |
|
389 | child=self.siblings(fl.children(n), fl.rev, file=f), | |
400 | rename=self.renamelink(fl, n), |
|
390 | rename=self.renamelink(fl, n), | |
401 |
permissions=self.repo.manifest.read |
|
391 | permissions=self.repo.manifest.read(mfn).execf(f)) | |
402 |
|
392 | |||
403 | def fileannotate(self, f, node): |
|
393 | def fileannotate(self, f, node): | |
404 | bcache = {} |
|
394 | bcache = {} | |
@@ -452,7 +442,7 b' class hgweb(object):' | |||||
452 | rename=self.renamelink(fl, n), |
|
442 | rename=self.renamelink(fl, n), | |
453 | parent=self.siblings(fl.parents(n), fl.rev, file=f), |
|
443 | parent=self.siblings(fl.parents(n), fl.rev, file=f), | |
454 | child=self.siblings(fl.children(n), fl.rev, file=f), |
|
444 | child=self.siblings(fl.children(n), fl.rev, file=f), | |
455 |
permissions=self.repo.manifest.read |
|
445 | permissions=self.repo.manifest.read(mfn).execf(f)) | |
456 |
|
446 | |||
457 | def manifest(self, mnode, path): |
|
447 | def manifest(self, mnode, path): | |
458 | man = self.repo.manifest |
|
448 | man = self.repo.manifest | |
@@ -462,7 +452,6 b' class hgweb(object):' | |||||
462 | rev = man.rev(mn) |
|
452 | rev = man.rev(mn) | |
463 | changerev = man.linkrev(mn) |
|
453 | changerev = man.linkrev(mn) | |
464 | node = self.repo.changelog.node(changerev) |
|
454 | node = self.repo.changelog.node(changerev) | |
465 | mff = man.readflags(mn) |
|
|||
466 |
|
455 | |||
467 | files = {} |
|
456 | files = {} | |
468 |
|
457 | |||
@@ -496,7 +485,7 b' class hgweb(object):' | |||||
496 | "filenode": hex(fnode), |
|
485 | "filenode": hex(fnode), | |
497 | "parity": self.stripes(parity), |
|
486 | "parity": self.stripes(parity), | |
498 | "basename": f, |
|
487 | "basename": f, | |
499 |
"permissions": mf |
|
488 | "permissions": mf.execf(full)} | |
500 | parity += 1 |
|
489 | parity += 1 | |
501 |
|
490 | |||
502 | def dirlist(**map): |
|
491 | 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. | |
@@ -169,7 +169,7 b' class localrepository(repo.repository):' | |||||
169 |
|
169 | |||
170 | tag_disallowed = ':\r\n' |
|
170 | tag_disallowed = ':\r\n' | |
171 |
|
171 | |||
172 |
def tag(self, name, node, |
|
172 | def tag(self, name, node, message, local, user, date): | |
173 | '''tag a revision with a symbolic name. |
|
173 | '''tag a revision with a symbolic name. | |
174 |
|
174 | |||
175 | if local is True, the tag is stored in a per-repository file. |
|
175 | if local is True, the tag is stored in a per-repository file. | |
@@ -191,27 +191,24 b' class localrepository(repo.repository):' | |||||
191 | if c in name: |
|
191 | if c in name: | |
192 | raise util.Abort(_('%r cannot be used in a tag name') % c) |
|
192 | raise util.Abort(_('%r cannot be used in a tag name') % c) | |
193 |
|
193 | |||
194 | self.hook('pretag', throw=True, node=node, tag=name, local=local) |
|
194 | self.hook('pretag', throw=True, node=hex(node), tag=name, local=local) | |
195 |
|
195 | |||
196 | if local: |
|
196 | if local: | |
197 | self.opener('localtags', 'a').write('%s %s\n' % (node, name)) |
|
197 | self.opener('localtags', 'a').write('%s %s\n' % (hex(node), name)) | |
198 | self.hook('tag', node=node, tag=name, local=local) |
|
198 | self.hook('tag', node=hex(node), tag=name, local=local) | |
199 | return |
|
199 | return | |
200 |
|
200 | |||
201 |
for x in self. |
|
201 | for x in self.status()[:5]: | |
202 | if '.hgtags' in x: |
|
202 | if '.hgtags' in x: | |
203 | raise util.Abort(_('working copy of .hgtags is changed ' |
|
203 | raise util.Abort(_('working copy of .hgtags is changed ' | |
204 | '(please commit .hgtags manually)')) |
|
204 | '(please commit .hgtags manually)')) | |
205 |
|
205 | |||
206 | self.wfile('.hgtags', 'ab').write('%s %s\n' % (node, name)) |
|
206 | self.wfile('.hgtags', 'ab').write('%s %s\n' % (hex(node), name)) | |
207 | if self.dirstate.state('.hgtags') == '?': |
|
207 | if self.dirstate.state('.hgtags') == '?': | |
208 | self.add(['.hgtags']) |
|
208 | self.add(['.hgtags']) | |
209 |
|
209 | |||
210 | if not message: |
|
|||
211 | message = _('Added tag %s for changeset %s') % (name, node) |
|
|||
212 |
|
||||
213 | self.commit(['.hgtags'], message, user, date) |
|
210 | self.commit(['.hgtags'], message, user, date) | |
214 | self.hook('tag', node=node, tag=name, local=local) |
|
211 | self.hook('tag', node=hex(node), tag=name, local=local) | |
215 |
|
212 | |||
216 | def tags(self): |
|
213 | def tags(self): | |
217 | '''return a mapping of tag to node''' |
|
214 | '''return a mapping of tag to node''' | |
@@ -470,8 +467,7 b' class localrepository(repo.repository):' | |||||
470 | p2 = p2 or self.dirstate.parents()[1] or nullid |
|
467 | p2 = p2 or self.dirstate.parents()[1] or nullid | |
471 | c1 = self.changelog.read(p1) |
|
468 | c1 = self.changelog.read(p1) | |
472 | c2 = self.changelog.read(p2) |
|
469 | c2 = self.changelog.read(p2) | |
473 | m1 = self.manifest.read(c1[0]) |
|
470 | m1 = self.manifest.read(c1[0]).copy() | |
474 | mf1 = self.manifest.readflags(c1[0]) |
|
|||
475 | m2 = self.manifest.read(c2[0]) |
|
471 | m2 = self.manifest.read(c2[0]) | |
476 | changed = [] |
|
472 | changed = [] | |
477 |
|
473 | |||
@@ -484,36 +480,32 b' class localrepository(repo.repository):' | |||||
484 | wlock = self.wlock() |
|
480 | wlock = self.wlock() | |
485 | l = self.lock() |
|
481 | l = self.lock() | |
486 | tr = self.transaction() |
|
482 | tr = self.transaction() | |
487 | mm = m1.copy() |
|
|||
488 | mfm = mf1.copy() |
|
|||
489 | linkrev = self.changelog.count() |
|
483 | linkrev = self.changelog.count() | |
490 | for f in files: |
|
484 | for f in files: | |
491 | try: |
|
485 | try: | |
492 | t = self.wread(f) |
|
486 | t = self.wread(f) | |
493 |
|
|
487 | m1.set(f, util.is_exec(self.wjoin(f), m1.execf(f))) | |
494 | r = self.file(f) |
|
488 | r = self.file(f) | |
495 | mfm[f] = tm |
|
|||
496 |
|
489 | |||
497 | (entry, fp1, fp2) = self.checkfilemerge(f, t, r, m1, m2) |
|
490 | (entry, fp1, fp2) = self.checkfilemerge(f, t, r, m1, m2) | |
498 | if entry: |
|
491 | if entry: | |
499 |
m |
|
492 | m1[f] = entry | |
500 | continue |
|
493 | continue | |
501 |
|
494 | |||
502 |
m |
|
495 | m1[f] = r.add(t, {}, tr, linkrev, fp1, fp2) | |
503 | changed.append(f) |
|
496 | changed.append(f) | |
504 | if update_dirstate: |
|
497 | if update_dirstate: | |
505 | self.dirstate.update([f], "n") |
|
498 | self.dirstate.update([f], "n") | |
506 | except IOError: |
|
499 | except IOError: | |
507 | try: |
|
500 | try: | |
508 |
del m |
|
501 | del m1[f] | |
509 | del mfm[f] |
|
|||
510 | if update_dirstate: |
|
502 | if update_dirstate: | |
511 | self.dirstate.forget([f]) |
|
503 | self.dirstate.forget([f]) | |
512 | except: |
|
504 | except: | |
513 | # deleted from p2? |
|
505 | # deleted from p2? | |
514 | pass |
|
506 | pass | |
515 |
|
507 | |||
516 |
mnode = self.manifest.add(m |
|
508 | mnode = self.manifest.add(m1, tr, linkrev, c1[0], c2[0]) | |
517 | user = user or self.ui.username() |
|
509 | user = user or self.ui.username() | |
518 | n = self.changelog.add(mnode, changed, text, tr, p1, p2, user, date) |
|
510 | n = self.changelog.add(mnode, changed, text, tr, p1, p2, user, date) | |
519 | tr.close() |
|
511 | tr.close() | |
@@ -537,15 +529,14 b' class localrepository(repo.repository):' | |||||
537 | else: |
|
529 | else: | |
538 | self.ui.warn(_("%s not tracked!\n") % f) |
|
530 | self.ui.warn(_("%s not tracked!\n") % f) | |
539 | else: |
|
531 | else: | |
540 |
modified, added, removed, deleted, unknown = self. |
|
532 | modified, added, removed, deleted, unknown = self.status(match=match)[:5] | |
541 | commit = modified + added |
|
533 | commit = modified + added | |
542 | remove = removed |
|
534 | remove = removed | |
543 |
|
535 | |||
544 | p1, p2 = self.dirstate.parents() |
|
536 | p1, p2 = self.dirstate.parents() | |
545 | c1 = self.changelog.read(p1) |
|
537 | c1 = self.changelog.read(p1) | |
546 | c2 = self.changelog.read(p2) |
|
538 | c2 = self.changelog.read(p2) | |
547 | m1 = self.manifest.read(c1[0]) |
|
539 | m1 = self.manifest.read(c1[0]).copy() | |
548 | mf1 = self.manifest.readflags(c1[0]) |
|
|||
549 | m2 = self.manifest.read(c2[0]) |
|
540 | m2 = self.manifest.read(c2[0]) | |
550 |
|
541 | |||
551 | if not commit and not remove and not force and p2 == nullid: |
|
542 | if not commit and not remove and not force and p2 == nullid: | |
@@ -571,7 +562,7 b' class localrepository(repo.repository):' | |||||
571 | for f in commit: |
|
562 | for f in commit: | |
572 | self.ui.note(f + "\n") |
|
563 | self.ui.note(f + "\n") | |
573 | try: |
|
564 | try: | |
574 |
m |
|
565 | m1.set(f, util.is_exec(self.wjoin(f), m1.execf(f))) | |
575 | t = self.wread(f) |
|
566 | t = self.wread(f) | |
576 | except IOError: |
|
567 | except IOError: | |
577 | self.ui.warn(_("trouble committing %s!\n") % f) |
|
568 | self.ui.warn(_("trouble committing %s!\n") % f) | |
@@ -598,12 +589,11 b' class localrepository(repo.repository):' | |||||
598 | changed.append(f) |
|
589 | changed.append(f) | |
599 |
|
590 | |||
600 | # update manifest |
|
591 | # update manifest | |
601 | m1 = m1.copy() |
|
|||
602 | m1.update(new) |
|
592 | m1.update(new) | |
603 | for f in remove: |
|
593 | for f in remove: | |
604 | if f in m1: |
|
594 | if f in m1: | |
605 | del m1[f] |
|
595 | del m1[f] | |
606 |
mn = self.manifest.add(m1 |
|
596 | mn = self.manifest.add(m1, tr, linkrev, c1[0], c2[0], | |
607 | (new, remove)) |
|
597 | (new, remove)) | |
608 |
|
598 | |||
609 | # add changeset |
|
599 | # add changeset | |
@@ -675,8 +665,7 b' class localrepository(repo.repository):' | |||||
675 |
|
665 | |||
676 | def fcmp(fn, mf): |
|
666 | def fcmp(fn, mf): | |
677 | t1 = self.wread(fn) |
|
667 | t1 = self.wread(fn) | |
678 |
|
|
668 | return self.file(fn).cmp(mf.get(fn, nullid), t1) | |
679 | return cmp(t1, t2) |
|
|||
680 |
|
669 | |||
681 | def mfmatches(node): |
|
670 | def mfmatches(node): | |
682 | change = self.changelog.read(node) |
|
671 | change = self.changelog.read(node) | |
@@ -718,8 +707,10 b' class localrepository(repo.repository):' | |||||
718 | for f in lookup: |
|
707 | for f in lookup: | |
719 | if fcmp(f, mf2): |
|
708 | if fcmp(f, mf2): | |
720 | modified.append(f) |
|
709 | modified.append(f) | |
721 |
el |
|
710 | else: | |
722 |
|
|
711 | clean.append(f) | |
|
712 | if wlock is not None: | |||
|
713 | self.dirstate.update([f], "n") | |||
723 | else: |
|
714 | else: | |
724 | # we are comparing working dir against non-parent |
|
715 | # we are comparing working dir against non-parent | |
725 | # generate a pseudo-manifest for the working dir |
|
716 | # generate a pseudo-manifest for the working dir | |
@@ -758,16 +749,6 b' class localrepository(repo.repository):' | |||||
758 | l.sort() |
|
749 | l.sort() | |
759 | return (modified, added, removed, deleted, unknown, ignored, clean) |
|
750 | return (modified, added, removed, deleted, unknown, ignored, clean) | |
760 |
|
751 | |||
761 | def changes(self, node1=None, node2=None, files=[], match=util.always, |
|
|||
762 | wlock=None, list_ignored=False, list_clean=False): |
|
|||
763 | '''DEPRECATED - use status instead''' |
|
|||
764 | marduit = self.status(node1, node2, files, match, wlock, |
|
|||
765 | list_ignored, list_clean) |
|
|||
766 | if list_ignored: |
|
|||
767 | return marduit[:-1] |
|
|||
768 | else: |
|
|||
769 | return marduit[:-2] |
|
|||
770 |
|
||||
771 | def add(self, list, wlock=None): |
|
752 | def add(self, list, wlock=None): | |
772 | if not wlock: |
|
753 | if not wlock: | |
773 | wlock = self.wlock() |
|
754 | wlock = self.wlock() | |
@@ -816,7 +797,6 b' class localrepository(repo.repository):' | |||||
816 | def undelete(self, list, wlock=None): |
|
797 | def undelete(self, list, wlock=None): | |
817 | p = self.dirstate.parents()[0] |
|
798 | p = self.dirstate.parents()[0] | |
818 | mn = self.changelog.read(p)[0] |
|
799 | mn = self.changelog.read(p)[0] | |
819 | mf = self.manifest.readflags(mn) |
|
|||
820 | m = self.manifest.read(mn) |
|
800 | m = self.manifest.read(mn) | |
821 | if not wlock: |
|
801 | if not wlock: | |
822 | wlock = self.wlock() |
|
802 | wlock = self.wlock() | |
@@ -826,7 +806,7 b' class localrepository(repo.repository):' | |||||
826 | else: |
|
806 | else: | |
827 | t = self.file(f).read(m[f]) |
|
807 | t = self.file(f).read(m[f]) | |
828 | self.wwrite(f, t) |
|
808 | self.wwrite(f, t) | |
829 |
util.set_exec(self.wjoin(f), m |
|
809 | util.set_exec(self.wjoin(f), m.execf(f)) | |
830 | self.dirstate.update([f], "n") |
|
810 | self.dirstate.update([f], "n") | |
831 |
|
811 | |||
832 | def copy(self, source, dest, wlock=None): |
|
812 | def copy(self, source, dest, wlock=None): | |
@@ -1122,7 +1102,7 b' class localrepository(repo.repository):' | |||||
1122 | else: |
|
1102 | else: | |
1123 | raise util.Abort(_("repository is unrelated")) |
|
1103 | raise util.Abort(_("repository is unrelated")) | |
1124 |
|
1104 | |||
1125 |
self.ui. |
|
1105 | self.ui.debug(_("found new changesets starting at ") + | |
1126 | " ".join([short(f) for f in fetch]) + "\n") |
|
1106 | " ".join([short(f) for f in fetch]) + "\n") | |
1127 |
|
1107 | |||
1128 | self.ui.debug(_("%d total queries\n") % reqcnt) |
|
1108 | self.ui.debug(_("%d total queries\n") % reqcnt) |
@@ -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. | |
@@ -19,14 +19,41 b' def splitnewlines(text):' | |||||
19 | lines[-1] = lines[-1][:-1] |
|
19 | lines[-1] = lines[-1][:-1] | |
20 | return lines |
|
20 | return lines | |
21 |
|
21 | |||
22 | def unidiff(a, ad, b, bd, fn, r=None, text=False, |
|
22 | class diffopts(object): | |
23 | showfunc=False, ignorews=False, ignorewsamount=False, |
|
23 | '''context is the number of context lines | |
24 | ignoreblanklines=False): |
|
24 | text treats all files as text | |
|
25 | showfunc enables diff -p output | |||
|
26 | git enables the git extended patch format | |||
|
27 | ignorews ignores all whitespace changes in the diff | |||
|
28 | ignorewsamount ignores changes in the amount of whitespace | |||
|
29 | ignoreblanklines ignores changes whose lines are all blank''' | |||
25 |
|
30 | |||
|
31 | defaults = { | |||
|
32 | 'context': 3, | |||
|
33 | 'text': False, | |||
|
34 | 'showfunc': True, | |||
|
35 | 'git': False, | |||
|
36 | 'ignorews': False, | |||
|
37 | 'ignorewsamount': False, | |||
|
38 | 'ignoreblanklines': False, | |||
|
39 | } | |||
|
40 | ||||
|
41 | __slots__ = defaults.keys() | |||
|
42 | ||||
|
43 | def __init__(self, **opts): | |||
|
44 | for k in self.__slots__: | |||
|
45 | v = opts.get(k) | |||
|
46 | if v is None: | |||
|
47 | v = self.defaults[k] | |||
|
48 | setattr(self, k, v) | |||
|
49 | ||||
|
50 | defaultopts = diffopts() | |||
|
51 | ||||
|
52 | def unidiff(a, ad, b, bd, fn, r=None, opts=defaultopts): | |||
26 | if not a and not b: return "" |
|
53 | if not a and not b: return "" | |
27 | epoch = util.datestr((0, 0)) |
|
54 | epoch = util.datestr((0, 0)) | |
28 |
|
55 | |||
29 | if not text and (util.binary(a) or util.binary(b)): |
|
56 | if not opts.text and (util.binary(a) or util.binary(b)): | |
30 | l = ['Binary file %s has changed\n' % fn] |
|
57 | l = ['Binary file %s has changed\n' % fn] | |
31 | elif not a: |
|
58 | elif not a: | |
32 | b = splitnewlines(b) |
|
59 | b = splitnewlines(b) | |
@@ -49,10 +76,7 b' def unidiff(a, ad, b, bd, fn, r=None, te' | |||||
49 | else: |
|
76 | else: | |
50 | al = splitnewlines(a) |
|
77 | al = splitnewlines(a) | |
51 | bl = splitnewlines(b) |
|
78 | bl = splitnewlines(b) | |
52 | l = list(bunidiff(a, b, al, bl, "a/" + fn, "b/" + fn, |
|
79 | l = list(bunidiff(a, b, al, bl, "a/" + fn, "b/" + fn, opts=opts)) | |
53 | showfunc=showfunc, ignorews=ignorews, |
|
|||
54 | ignorewsamount=ignorewsamount, |
|
|||
55 | ignoreblanklines=ignoreblanklines)) |
|
|||
56 | if not l: return "" |
|
80 | if not l: return "" | |
57 | # difflib uses a space, rather than a tab |
|
81 | # difflib uses a space, rather than a tab | |
58 | l[0] = "%s\t%s\n" % (l[0][:-2], ad) |
|
82 | l[0] = "%s\t%s\n" % (l[0][:-2], ad) | |
@@ -72,21 +96,15 b' def unidiff(a, ad, b, bd, fn, r=None, te' | |||||
72 | # t1 and t2 are the text to be diffed |
|
96 | # t1 and t2 are the text to be diffed | |
73 | # l1 and l2 are the text broken up into lines |
|
97 | # l1 and l2 are the text broken up into lines | |
74 | # header1 and header2 are the filenames for the diff output |
|
98 | # header1 and header2 are the filenames for the diff output | |
75 | # context is the number of context lines |
|
99 | def bunidiff(t1, t2, l1, l2, header1, header2, opts=defaultopts): | |
76 | # showfunc enables diff -p output |
|
|||
77 | # ignorews ignores all whitespace changes in the diff |
|
|||
78 | # ignorewsamount ignores changes in the amount of whitespace |
|
|||
79 | # ignoreblanklines ignores changes whose lines are all blank |
|
|||
80 | def bunidiff(t1, t2, l1, l2, header1, header2, context=3, showfunc=False, |
|
|||
81 | ignorews=False, ignorewsamount=False, ignoreblanklines=False): |
|
|||
82 | def contextend(l, len): |
|
100 | def contextend(l, len): | |
83 | ret = l + context |
|
101 | ret = l + opts.context | |
84 | if ret > len: |
|
102 | if ret > len: | |
85 | ret = len |
|
103 | ret = len | |
86 | return ret |
|
104 | return ret | |
87 |
|
105 | |||
88 | def contextstart(l): |
|
106 | def contextstart(l): | |
89 | ret = l - context |
|
107 | ret = l - opts.context | |
90 | if ret < 0: |
|
108 | if ret < 0: | |
91 | return 0 |
|
109 | return 0 | |
92 | return ret |
|
110 | return ret | |
@@ -101,7 +119,7 b' def bunidiff(t1, t2, l1, l2, header1, he' | |||||
101 | blen = b2 - bstart + aend - a2 |
|
119 | blen = b2 - bstart + aend - a2 | |
102 |
|
120 | |||
103 | func = "" |
|
121 | func = "" | |
104 | if showfunc: |
|
122 | if opts.showfunc: | |
105 | # walk backwards from the start of the context |
|
123 | # walk backwards from the start of the context | |
106 | # to find a line starting with an alphanumeric char. |
|
124 | # to find a line starting with an alphanumeric char. | |
107 | for x in xrange(astart, -1, -1): |
|
125 | for x in xrange(astart, -1, -1): | |
@@ -119,14 +137,14 b' def bunidiff(t1, t2, l1, l2, header1, he' | |||||
119 |
|
137 | |||
120 | header = [ "--- %s\t\n" % header1, "+++ %s\t\n" % header2 ] |
|
138 | header = [ "--- %s\t\n" % header1, "+++ %s\t\n" % header2 ] | |
121 |
|
139 | |||
122 | if showfunc: |
|
140 | if opts.showfunc: | |
123 | funcre = re.compile('\w') |
|
141 | funcre = re.compile('\w') | |
124 | if ignorewsamount: |
|
142 | if opts.ignorewsamount: | |
125 | wsamountre = re.compile('[ \t]+') |
|
143 | wsamountre = re.compile('[ \t]+') | |
126 | wsappendedre = re.compile(' \n') |
|
144 | wsappendedre = re.compile(' \n') | |
127 | if ignoreblanklines: |
|
145 | if opts.ignoreblanklines: | |
128 | wsblanklinesre = re.compile('\n') |
|
146 | wsblanklinesre = re.compile('\n') | |
129 | if ignorews: |
|
147 | if opts.ignorews: | |
130 | wsre = re.compile('[ \t]') |
|
148 | wsre = re.compile('[ \t]') | |
131 |
|
149 | |||
132 | # bdiff.blocks gives us the matching sequences in the files. The loop |
|
150 | # bdiff.blocks gives us the matching sequences in the files. The loop | |
@@ -159,13 +177,13 b' def bunidiff(t1, t2, l1, l2, header1, he' | |||||
159 | if not old and not new: |
|
177 | if not old and not new: | |
160 | continue |
|
178 | continue | |
161 |
|
179 | |||
162 | if ignoreblanklines: |
|
180 | if opts.ignoreblanklines: | |
163 | wsold = wsblanklinesre.sub('', "".join(old)) |
|
181 | wsold = wsblanklinesre.sub('', "".join(old)) | |
164 | wsnew = wsblanklinesre.sub('', "".join(new)) |
|
182 | wsnew = wsblanklinesre.sub('', "".join(new)) | |
165 | if wsold == wsnew: |
|
183 | if wsold == wsnew: | |
166 | continue |
|
184 | continue | |
167 |
|
185 | |||
168 | if ignorewsamount: |
|
186 | if opts.ignorewsamount: | |
169 | wsold = wsamountre.sub(' ', "".join(old)) |
|
187 | wsold = wsamountre.sub(' ', "".join(old)) | |
170 | wsold = wsappendedre.sub('\n', wsold) |
|
188 | wsold = wsappendedre.sub('\n', wsold) | |
171 | wsnew = wsamountre.sub(' ', "".join(new)) |
|
189 | wsnew = wsamountre.sub(' ', "".join(new)) | |
@@ -173,7 +191,7 b' def bunidiff(t1, t2, l1, l2, header1, he' | |||||
173 | if wsold == wsnew: |
|
191 | if wsold == wsnew: | |
174 | continue |
|
192 | continue | |
175 |
|
193 | |||
176 | if ignorews: |
|
194 | if opts.ignorews: | |
177 | wsold = wsre.sub('', "".join(old)) |
|
195 | wsold = wsre.sub('', "".join(old)) | |
178 | wsnew = wsre.sub('', "".join(new)) |
|
196 | wsnew = wsre.sub('', "".join(new)) | |
179 | if wsold == wsnew: |
|
197 | if wsold == wsnew: | |
@@ -184,7 +202,7 b' def bunidiff(t1, t2, l1, l2, header1, he' | |||||
184 | prev = None |
|
202 | prev = None | |
185 | if hunk: |
|
203 | if hunk: | |
186 | # join with the previous hunk if it falls inside the context |
|
204 | # join with the previous hunk if it falls inside the context | |
187 | if astart < hunk[1] + context + 1: |
|
205 | if astart < hunk[1] + opts.context + 1: | |
188 | prev = hunk |
|
206 | prev = hunk | |
189 | astart = hunk[1] |
|
207 | astart = hunk[1] | |
190 | bstart = hunk[3] |
|
208 | bstart = hunk[3] |
@@ -10,6 +10,11 b' from i18n import gettext as _' | |||||
10 | from demandload import * |
|
10 | from demandload import * | |
11 | demandload(globals(), "util os tempfile") |
|
11 | demandload(globals(), "util os tempfile") | |
12 |
|
12 | |||
|
13 | def fmerge(f, local, other, ancestor): | |||
|
14 | """merge executable flags""" | |||
|
15 | a, b, c = ancestor.execf(f), local.execf(f), other.execf(f) | |||
|
16 | return ((a^b) | (a^c)) ^ a | |||
|
17 | ||||
13 | def merge3(repo, fn, my, other, p1, p2): |
|
18 | def merge3(repo, fn, my, other, p1, p2): | |
14 | """perform a 3-way merge in the working directory""" |
|
19 | """perform a 3-way merge in the working directory""" | |
15 |
|
20 | |||
@@ -75,7 +80,7 b' def update(repo, node, branchmerge=False' | |||||
75 | raise util.Abort(_("update spans branches, use 'hg merge' " |
|
80 | raise util.Abort(_("update spans branches, use 'hg merge' " | |
76 | "or 'hg update -C' to lose changes")) |
|
81 | "or 'hg update -C' to lose changes")) | |
77 |
|
82 | |||
78 |
modified, added, removed, deleted, unknown = repo. |
|
83 | modified, added, removed, deleted, unknown = repo.status()[:5] | |
79 | if branchmerge and not forcemerge: |
|
84 | if branchmerge and not forcemerge: | |
80 | if modified or added or removed: |
|
85 | if modified or added or removed: | |
81 | raise util.Abort(_("outstanding uncommitted changes")) |
|
86 | raise util.Abort(_("outstanding uncommitted changes")) | |
@@ -84,18 +89,13 b' def update(repo, node, branchmerge=False' | |||||
84 | m2n = repo.changelog.read(p2)[0] |
|
89 | m2n = repo.changelog.read(p2)[0] | |
85 | man = repo.manifest.ancestor(m1n, m2n) |
|
90 | man = repo.manifest.ancestor(m1n, m2n) | |
86 | m1 = repo.manifest.read(m1n) |
|
91 | m1 = repo.manifest.read(m1n) | |
87 | mf1 = repo.manifest.readflags(m1n) |
|
|||
88 | m2 = repo.manifest.read(m2n).copy() |
|
92 | m2 = repo.manifest.read(m2n).copy() | |
89 | mf2 = repo.manifest.readflags(m2n) |
|
|||
90 | ma = repo.manifest.read(man) |
|
93 | ma = repo.manifest.read(man) | |
91 | mfa = repo.manifest.readflags(man) |
|
|||
92 |
|
94 | |||
93 | if not forcemerge and not overwrite: |
|
95 | if not force: | |
94 | for f in unknown: |
|
96 | for f in unknown: | |
95 | if f in m2: |
|
97 | if f in m2: | |
96 |
|
|
98 | if repo.file(f).cmp(m2[f], repo.wread(f)): | |
97 | t2 = repo.file(f).read(m2[f]) |
|
|||
98 | if cmp(t1, t2) != 0: |
|
|||
99 | raise util.Abort(_("'%s' already exists in the working" |
|
99 | raise util.Abort(_("'%s' already exists in the working" | |
100 | " dir and differs from remote") % f) |
|
100 | " dir and differs from remote") % f) | |
101 |
|
101 | |||
@@ -103,22 +103,27 b' def update(repo, node, branchmerge=False' | |||||
103 | # we care about merging |
|
103 | # we care about merging | |
104 | repo.ui.note(_("resolving manifests\n")) |
|
104 | repo.ui.note(_("resolving manifests\n")) | |
105 | repo.ui.debug(_(" overwrite %s branchmerge %s partial %s linear %s\n") % |
|
105 | repo.ui.debug(_(" overwrite %s branchmerge %s partial %s linear %s\n") % | |
106 |
(overwrite, branchmerge, partial |
|
106 | (overwrite, branchmerge, bool(partial), linear_path)) | |
107 | repo.ui.debug(_(" ancestor %s local %s remote %s\n") % |
|
107 | repo.ui.debug(_(" ancestor %s local %s remote %s\n") % | |
108 | (short(man), short(m1n), short(m2n))) |
|
108 | (short(man), short(m1n), short(m2n))) | |
109 |
|
109 | |||
110 | merge = {} |
|
110 | merge = {} | |
111 | get = {} |
|
111 | get = {} | |
112 | remove = [] |
|
112 | remove = [] | |
|
113 | forget = [] | |||
113 |
|
114 | |||
114 | # construct a working dir manifest |
|
115 | # construct a working dir manifest | |
115 | mw = m1.copy() |
|
116 | mw = m1.copy() | |
116 | mfw = mf1.copy() |
|
|||
117 | umap = dict.fromkeys(unknown) |
|
117 | umap = dict.fromkeys(unknown) | |
118 |
|
118 | |||
119 | for f in added + modified + unknown: |
|
119 | for f in added + modified + unknown: | |
120 | mw[f] = "" |
|
120 | mw[f] = "" | |
121 | mfw[f] = util.is_exec(repo.wjoin(f), mfw.get(f, False)) |
|
121 | # is the wfile new and matches m2? | |
|
122 | if (f not in m1 and f in m2 and | |||
|
123 | not repo.file(f).cmp(m2[f], repo.wread(f))): | |||
|
124 | mw[f] = m2[f] | |||
|
125 | ||||
|
126 | mw.set(f, util.is_exec(repo.wjoin(f), mw.execf(f))) | |||
122 |
|
127 | |||
123 | for f in deleted + removed: |
|
128 | for f in deleted + removed: | |
124 | if f in mw: |
|
129 | if f in mw: | |
@@ -129,8 +134,8 b' def update(repo, node, branchmerge=False' | |||||
129 | # the file, then we need to remove it from the dirstate, to |
|
134 | # the file, then we need to remove it from the dirstate, to | |
130 | # prevent the dirstate from listing the file when it is no |
|
135 | # prevent the dirstate from listing the file when it is no | |
131 | # longer in the manifest. |
|
136 | # longer in the manifest. | |
132 |
if |
|
137 | if linear_path and f not in m2: | |
133 |
|
|
138 | forget.append(f) | |
134 |
|
139 | |||
135 | # Compare manifests |
|
140 | # Compare manifests | |
136 | for f, n in mw.iteritems(): |
|
141 | for f, n in mw.iteritems(): | |
@@ -139,46 +144,32 b' def update(repo, node, branchmerge=False' | |||||
139 | if f in m2: |
|
144 | if f in m2: | |
140 | s = 0 |
|
145 | s = 0 | |
141 |
|
146 | |||
142 | # is the wfile new since m1, and match m2? |
|
|||
143 | if f not in m1: |
|
|||
144 | t1 = repo.wread(f) |
|
|||
145 | t2 = repo.file(f).read(m2[f]) |
|
|||
146 | if cmp(t1, t2) == 0: |
|
|||
147 | n = m2[f] |
|
|||
148 | del t1, t2 |
|
|||
149 |
|
||||
150 | # are files different? |
|
147 | # are files different? | |
151 | if n != m2[f]: |
|
148 | if n != m2[f]: | |
152 | a = ma.get(f, nullid) |
|
149 | a = ma.get(f, nullid) | |
153 | # are both different from the ancestor? |
|
150 | # are both different from the ancestor? | |
154 | if n != a and m2[f] != a: |
|
151 | if n != a and m2[f] != a: | |
155 | repo.ui.debug(_(" %s versions differ, resolve\n") % f) |
|
152 | repo.ui.debug(_(" %s versions differ, resolve\n") % f) | |
156 | # merge executable bits |
|
153 | merge[f] = (fmerge(f, mw, m2, ma), m1.get(f, nullid), m2[f]) | |
157 | # "if we changed or they changed, change in merge" |
|
|||
158 | a, b, c = mfa.get(f, 0), mfw[f], mf2[f] |
|
|||
159 | mode = ((a^b) | (a^c)) ^ a |
|
|||
160 | merge[f] = (m1.get(f, nullid), m2[f], mode) |
|
|||
161 | s = 1 |
|
154 | s = 1 | |
162 | # are we clobbering? |
|
155 | # are we clobbering? | |
163 | # is remote's version newer? |
|
156 | # is remote's version newer? | |
164 | # or are we going back in time? |
|
157 | # or are we going back in time? | |
165 | elif overwrite or m2[f] != a or (p2 == pa and mw[f] == m1[f]): |
|
158 | 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) |
|
159 | repo.ui.debug(_(" remote %s is newer, get\n") % f) | |
167 | get[f] = m2[f] |
|
160 | get[f] = (m2.execf(f), m2[f]) | |
168 | s = 1 |
|
161 | s = 1 | |
169 | elif f in umap or f in added: |
|
162 | elif f in umap or f in added: | |
170 | # this unknown file is the same as the checkout |
|
163 | # this unknown file is the same as the checkout | |
171 | # we need to reset the dirstate if the file was added |
|
164 | # we need to reset the dirstate if the file was added | |
172 | get[f] = m2[f] |
|
165 | get[f] = (m2.execf(f), m2[f]) | |
173 |
|
166 | |||
174 |
if not s and m |
|
167 | if not s and mw.execf(f) != m2.execf(f): | |
175 | if overwrite: |
|
168 | if overwrite: | |
176 | repo.ui.debug(_(" updating permissions for %s\n") % f) |
|
169 | repo.ui.debug(_(" updating permissions for %s\n") % f) | |
177 |
util.set_exec(repo.wjoin(f), m |
|
170 | util.set_exec(repo.wjoin(f), m2.execf(f)) | |
178 | else: |
|
171 | else: | |
179 |
|
|
172 | if fmerge(f, mw, m2, ma) != mw.execf(f): | |
180 | mode = ((a^b) | (a^c)) ^ a |
|
|||
181 | if mode != b: |
|
|||
182 | repo.ui.debug(_(" updating permissions for %s\n") |
|
173 | repo.ui.debug(_(" updating permissions for %s\n") | |
183 | % f) |
|
174 | % f) | |
184 | util.set_exec(repo.wjoin(f), mode) |
|
175 | util.set_exec(repo.wjoin(f), mode) | |
@@ -221,22 +212,24 b' def update(repo, node, branchmerge=False' | |||||
221 | (_("remote changed %s which local deleted\n") % f) + |
|
212 | (_("remote changed %s which local deleted\n") % f) + | |
222 | _("(k)eep or (d)elete?"), _("[kd]"), _("k")) |
|
213 | _("(k)eep or (d)elete?"), _("[kd]"), _("k")) | |
223 | if r == _("k"): |
|
214 | if r == _("k"): | |
224 | get[f] = n |
|
215 | get[f] = (m2.execf(f), n) | |
225 | elif f not in ma: |
|
216 | elif f not in ma: | |
226 | repo.ui.debug(_("remote created %s\n") % f) |
|
217 | repo.ui.debug(_("remote created %s\n") % f) | |
227 | get[f] = n |
|
218 | get[f] = (m2.execf(f), n) | |
228 | else: |
|
219 | else: | |
229 | if overwrite or p2 == pa: # going backwards? |
|
220 | if overwrite or p2 == pa: # going backwards? | |
230 | repo.ui.debug(_("local deleted %s, recreating\n") % f) |
|
221 | repo.ui.debug(_("local deleted %s, recreating\n") % f) | |
231 | get[f] = n |
|
222 | get[f] = (m2.execf(f), n) | |
232 | else: |
|
223 | else: | |
233 | repo.ui.debug(_("local deleted %s\n") % f) |
|
224 | repo.ui.debug(_("local deleted %s\n") % f) | |
234 |
|
225 | |||
235 | del mw, m1, m2, ma |
|
226 | del mw, m1, m2, ma | |
236 |
|
227 | |||
|
228 | ### apply phase | |||
|
229 | ||||
237 | if overwrite: |
|
230 | if overwrite: | |
238 | for f in merge: |
|
231 | for f in merge: | |
239 |
get[f] = merge[f][ |
|
232 | get[f] = merge[f][:2] | |
240 | merge = {} |
|
233 | merge = {} | |
241 |
|
234 | |||
242 | if linear_path or overwrite: |
|
235 | if linear_path or overwrite: | |
@@ -254,17 +247,13 b' def update(repo, node, branchmerge=False' | |||||
254 | files = get.keys() |
|
247 | files = get.keys() | |
255 | files.sort() |
|
248 | files.sort() | |
256 | for f in files: |
|
249 | for f in files: | |
|
250 | flag, node = get[f] | |||
257 | if f[0] == "/": |
|
251 | if f[0] == "/": | |
258 | continue |
|
252 | continue | |
259 | repo.ui.note(_("getting %s\n") % f) |
|
253 | repo.ui.note(_("getting %s\n") % f) | |
260 |
t = repo.file(f).read( |
|
254 | t = repo.file(f).read(node) | |
261 | repo.wwrite(f, t) |
|
255 | repo.wwrite(f, t) | |
262 |
util.set_exec(repo.wjoin(f), |
|
256 | util.set_exec(repo.wjoin(f), flag) | |
263 | if not partial: |
|
|||
264 | if branchmerge: |
|
|||
265 | repo.dirstate.update([f], 'n', st_mtime=-1) |
|
|||
266 | else: |
|
|||
267 | repo.dirstate.update([f], 'n') |
|
|||
268 |
|
257 | |||
269 | # merge the tricky bits |
|
258 | # merge the tricky bits | |
270 | unresolved = [] |
|
259 | unresolved = [] | |
@@ -272,24 +261,11 b' def update(repo, node, branchmerge=False' | |||||
272 | files.sort() |
|
261 | files.sort() | |
273 | for f in files: |
|
262 | for f in files: | |
274 | repo.ui.status(_("merging %s\n") % f) |
|
263 | repo.ui.status(_("merging %s\n") % f) | |
275 |
my, other |
|
264 | flag, my, other = merge[f] | |
276 | ret = merge3(repo, f, my, other, xp1, xp2) |
|
265 | ret = merge3(repo, f, my, other, xp1, xp2) | |
277 | if ret: |
|
266 | if ret: | |
278 | unresolved.append(f) |
|
267 | unresolved.append(f) | |
279 | util.set_exec(repo.wjoin(f), flag) |
|
268 | util.set_exec(repo.wjoin(f), flag) | |
280 | if not partial: |
|
|||
281 | if branchmerge: |
|
|||
282 | # We've done a branch merge, mark this file as merged |
|
|||
283 | # so that we properly record the merger later |
|
|||
284 | repo.dirstate.update([f], 'm') |
|
|||
285 | else: |
|
|||
286 | # We've update-merged a locally modified file, so |
|
|||
287 | # we set the dirstate to emulate a normal checkout |
|
|||
288 | # of that file some time in the past. Thus our |
|
|||
289 | # merge will appear as a normal local file |
|
|||
290 | # modification. |
|
|||
291 | f_len = len(repo.file(f).read(other)) |
|
|||
292 | repo.dirstate.update([f], 'n', st_size=f_len, st_mtime=-1) |
|
|||
293 |
|
269 | |||
294 | remove.sort() |
|
270 | remove.sort() | |
295 | for f in remove: |
|
271 | for f in remove: | |
@@ -301,14 +277,40 b' def update(repo, node, branchmerge=False' | |||||
301 | if inst.errno != errno.ENOENT: |
|
277 | if inst.errno != errno.ENOENT: | |
302 | repo.ui.warn(_("update failed to remove %s: %s!\n") % |
|
278 | repo.ui.warn(_("update failed to remove %s: %s!\n") % | |
303 | (f, inst.strerror)) |
|
279 | (f, inst.strerror)) | |
|
280 | ||||
|
281 | # update dirstate | |||
304 | if not partial: |
|
282 | if not partial: | |
|
283 | repo.dirstate.setparents(p1, p2) | |||
|
284 | repo.dirstate.forget(forget) | |||
305 | if branchmerge: |
|
285 | if branchmerge: | |
306 | repo.dirstate.update(remove, 'r') |
|
286 | repo.dirstate.update(remove, 'r') | |
307 | else: |
|
287 | else: | |
308 | repo.dirstate.forget(remove) |
|
288 | repo.dirstate.forget(remove) | |
309 |
|
289 | |||
310 | if not partial: |
|
290 | files = get.keys() | |
311 | repo.dirstate.setparents(p1, p2) |
|
291 | files.sort() | |
|
292 | for f in files: | |||
|
293 | if branchmerge: | |||
|
294 | repo.dirstate.update([f], 'n', st_mtime=-1) | |||
|
295 | else: | |||
|
296 | repo.dirstate.update([f], 'n') | |||
|
297 | ||||
|
298 | files = merge.keys() | |||
|
299 | files.sort() | |||
|
300 | for f in files: | |||
|
301 | if branchmerge: | |||
|
302 | # We've done a branch merge, mark this file as merged | |||
|
303 | # so that we properly record the merger later | |||
|
304 | repo.dirstate.update([f], 'm') | |||
|
305 | else: | |||
|
306 | # We've update-merged a locally modified file, so | |||
|
307 | # we set the dirstate to emulate a normal checkout | |||
|
308 | # of that file some time in the past. Thus our | |||
|
309 | # merge will appear as a normal local file | |||
|
310 | # modification. | |||
|
311 | fl = repo.file(f) | |||
|
312 | f_len = fl.size(fl.rev(other)) | |||
|
313 | repo.dirstate.update([f], 'n', st_size=f_len, st_mtime=-1) | |||
312 |
|
314 | |||
313 | if show_stats: |
|
315 | if show_stats: | |
314 | stats = ((len(get), _("updated")), |
|
316 | stats = ((len(get), _("updated")), |
@@ -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. | |
@@ -39,9 +39,9 b' def demandload(scope, modules):' | |||||
39 | except: |
|
39 | except: | |
40 | module = m |
|
40 | module = m | |
41 | fromlist = [] |
|
41 | fromlist = [] | |
42 | as = None |
|
42 | as_ = None | |
43 | if '@' in module: |
|
43 | if '@' in module: | |
44 |
module, as = module.split( |
|
44 | module, as_ = module.split('@') | |
45 | mod = __import__(module, scope, scope, fromlist) |
|
45 | mod = __import__(module, scope, scope, fromlist) | |
46 | if fromlist == []: |
|
46 | if fromlist == []: | |
47 | # mod is only the top package, but we need all packages |
|
47 | # mod is only the top package, but we need all packages | |
@@ -50,9 +50,9 b' def demandload(scope, modules):' | |||||
50 | mn = comp[0] |
|
50 | mn = comp[0] | |
51 | while True: |
|
51 | while True: | |
52 | # mn and mod.__name__ might not be the same |
|
52 | # mn and mod.__name__ might not be the same | |
53 | if not as: |
|
53 | if not as_: | |
54 | as = mn |
|
54 | as_ = mn | |
55 | scope[as] = mod |
|
55 | scope[as_] = mod | |
56 | requiredmodules[mod.__name__] = 1 |
|
56 | requiredmodules[mod.__name__] = 1 | |
57 | if len(comp) == i: break |
|
57 | if len(comp) == i: break | |
58 | mod = getattr(mod,comp[i]) |
|
58 | mod = getattr(mod,comp[i]) |
@@ -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. | |
@@ -766,6 +766,19 b' class revlog(object):' | |||||
766 |
|
766 | |||
767 | raise RevlogError(_("No match found")) |
|
767 | raise RevlogError(_("No match found")) | |
768 |
|
768 | |||
|
769 | def cmp(self, node, text): | |||
|
770 | """compare text with a given file revision""" | |||
|
771 | p1, p2 = self.parents(node) | |||
|
772 | return hash(text, p1, p2) != node | |||
|
773 | ||||
|
774 | def makenode(self, node, text): | |||
|
775 | """calculate a file nodeid for text, descended or possibly | |||
|
776 | unchanged from node""" | |||
|
777 | ||||
|
778 | if self.cmp(node, text): | |||
|
779 | return hash(text, node, nullid) | |||
|
780 | return node | |||
|
781 | ||||
769 | def diff(self, a, b): |
|
782 | def diff(self, a, b): | |
770 | """return a delta between two revisions""" |
|
783 | """return a delta between two revisions""" | |
771 | return mdiff.textdiff(a, b) |
|
784 | return mdiff.textdiff(a, b) |
@@ -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. |
@@ -459,7 +459,7 b' class changeset_templater(object):' | |||||
459 | yield x |
|
459 | yield x | |
460 |
|
460 | |||
461 | if self.ui.debugflag: |
|
461 | if self.ui.debugflag: | |
462 |
files = self.repo. |
|
462 | files = self.repo.status(log.parents(changenode)[0], changenode)[:3] | |
463 | def showfiles(**args): |
|
463 | def showfiles(**args): | |
464 | for x in showlist('file', files[0], **args): yield x |
|
464 | for x in showlist('file', files[0], **args): yield x | |
465 | def showadds(**args): |
|
465 | def showadds(**args): |
@@ -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,22 +1,24 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. | |
7 |
|
7 | |||
8 | from i18n import gettext as _ |
|
8 | from i18n import gettext as _ | |
9 | from demandload import * |
|
9 | from demandload import * | |
10 |
demandload(globals(), "errno getpass os re s |
|
10 | demandload(globals(), "errno getpass os re socket sys tempfile") | |
11 | demandload(globals(), "ConfigParser templater traceback util") |
|
11 | demandload(globals(), "ConfigParser mdiff templater traceback util") | |
12 |
|
12 | |||
13 | class ui(object): |
|
13 | class ui(object): | |
14 | def __init__(self, verbose=False, debug=False, quiet=False, |
|
14 | def __init__(self, verbose=False, debug=False, quiet=False, | |
15 |
interactive=True, traceback=False, parentui=None |
|
15 | interactive=True, traceback=False, parentui=None, | |
|
16 | readhooks=[]): | |||
16 | self.overlay = {} |
|
17 | self.overlay = {} | |
17 | if parentui is None: |
|
18 | if parentui is None: | |
18 | # this is the parent of all ui children |
|
19 | # this is the parent of all ui children | |
19 | self.parentui = None |
|
20 | self.parentui = None | |
|
21 | self.readhooks = list(readhooks) | |||
20 | self.cdata = ConfigParser.SafeConfigParser() |
|
22 | self.cdata = ConfigParser.SafeConfigParser() | |
21 | self.readconfig(util.rcpath()) |
|
23 | self.readconfig(util.rcpath()) | |
22 |
|
24 | |||
@@ -34,6 +36,7 b' class ui(object):' | |||||
34 | else: |
|
36 | else: | |
35 | # parentui may point to an ui object which is already a child |
|
37 | # parentui may point to an ui object which is already a child | |
36 | self.parentui = parentui.parentui or parentui |
|
38 | self.parentui = parentui.parentui or parentui | |
|
39 | self.readhooks = list(parentui.readhooks or readhooks) | |||
37 | parent_cdata = self.parentui.cdata |
|
40 | parent_cdata = self.parentui.cdata | |
38 | self.cdata = ConfigParser.SafeConfigParser(parent_cdata.defaults()) |
|
41 | self.cdata = ConfigParser.SafeConfigParser(parent_cdata.defaults()) | |
39 | # make interpolation work |
|
42 | # make interpolation work | |
@@ -78,6 +81,8 b' class ui(object):' | |||||
78 | for name, path in self.configitems("paths"): |
|
81 | for name, path in self.configitems("paths"): | |
79 | if path and "://" not in path and not os.path.isabs(path): |
|
82 | if path and "://" not in path and not os.path.isabs(path): | |
80 | self.cdata.set("paths", name, os.path.join(root, path)) |
|
83 | self.cdata.set("paths", name, os.path.join(root, path)) | |
|
84 | for hook in self.readhooks: | |||
|
85 | hook(self) | |||
81 |
|
86 | |||
82 | def setconfig(self, section, name, val): |
|
87 | def setconfig(self, section, name, val): | |
83 | self.overlay[(section, name)] = val |
|
88 | self.overlay[(section, name)] = val | |
@@ -169,17 +174,6 b' class ui(object):' | |||||
169 | result[key.lower()] = value |
|
174 | result[key.lower()] = value | |
170 | return result |
|
175 | return result | |
171 |
|
176 | |||
172 | def diffopts(self): |
|
|||
173 | if self.diffcache: |
|
|||
174 | return self.diffcache |
|
|||
175 | result = {'showfunc': True, 'ignorews': False, |
|
|||
176 | 'ignorewsamount': False, 'ignoreblanklines': False} |
|
|||
177 | for key, value in self.configitems("diff"): |
|
|||
178 | if value: |
|
|||
179 | result[key.lower()] = (value.lower() == 'true') |
|
|||
180 | self.diffcache = result |
|
|||
181 | return result |
|
|||
182 |
|
||||
183 | def username(self): |
|
177 | def username(self): | |
184 | """Return default username to be used in commits. |
|
178 | """Return default username to be used in commits. | |
185 |
|
179 | |||
@@ -292,62 +286,6 b' class ui(object):' | |||||
292 |
|
286 | |||
293 | return t |
|
287 | return t | |
294 |
|
288 | |||
295 | def sendmail(self): |
|
|||
296 | '''send mail message. object returned has one method, sendmail. |
|
|||
297 | call as sendmail(sender, list-of-recipients, msg).''' |
|
|||
298 |
|
||||
299 | def smtp(): |
|
|||
300 | '''send mail using smtp.''' |
|
|||
301 |
|
||||
302 | local_hostname = self.config('smtp', 'local_hostname') |
|
|||
303 | s = smtplib.SMTP(local_hostname=local_hostname) |
|
|||
304 | mailhost = self.config('smtp', 'host') |
|
|||
305 | if not mailhost: |
|
|||
306 | raise util.Abort(_('no [smtp]host in hgrc - cannot send mail')) |
|
|||
307 | mailport = int(self.config('smtp', 'port', 25)) |
|
|||
308 | self.note(_('sending mail: smtp host %s, port %s\n') % |
|
|||
309 | (mailhost, mailport)) |
|
|||
310 | s.connect(host=mailhost, port=mailport) |
|
|||
311 | if self.configbool('smtp', 'tls'): |
|
|||
312 | self.note(_('(using tls)\n')) |
|
|||
313 | s.ehlo() |
|
|||
314 | s.starttls() |
|
|||
315 | s.ehlo() |
|
|||
316 | username = self.config('smtp', 'username') |
|
|||
317 | password = self.config('smtp', 'password') |
|
|||
318 | if username and password: |
|
|||
319 | self.note(_('(authenticating to mail server as %s)\n') % |
|
|||
320 | (username)) |
|
|||
321 | s.login(username, password) |
|
|||
322 | return s |
|
|||
323 |
|
||||
324 | class sendmail(object): |
|
|||
325 | '''send mail using sendmail.''' |
|
|||
326 |
|
||||
327 | def __init__(self, ui, program): |
|
|||
328 | self.ui = ui |
|
|||
329 | self.program = program |
|
|||
330 |
|
||||
331 | def sendmail(self, sender, recipients, msg): |
|
|||
332 | cmdline = '%s -f %s %s' % ( |
|
|||
333 | self.program, templater.email(sender), |
|
|||
334 | ' '.join(map(templater.email, recipients))) |
|
|||
335 | self.ui.note(_('sending mail: %s\n') % cmdline) |
|
|||
336 | fp = os.popen(cmdline, 'w') |
|
|||
337 | fp.write(msg) |
|
|||
338 | ret = fp.close() |
|
|||
339 | if ret: |
|
|||
340 | raise util.Abort('%s %s' % ( |
|
|||
341 | os.path.basename(self.program.split(None, 1)[0]), |
|
|||
342 | util.explain_exit(ret)[0])) |
|
|||
343 |
|
||||
344 | method = self.config('email', 'method', 'smtp') |
|
|||
345 | if method == 'smtp': |
|
|||
346 | mail = smtp() |
|
|||
347 | else: |
|
|||
348 | mail = sendmail(self, method) |
|
|||
349 | return mail |
|
|||
350 |
|
||||
351 | def print_exc(self): |
|
289 | def print_exc(self): | |
352 | '''print exception traceback if traceback printing enabled. |
|
290 | '''print exception traceback if traceback printing enabled. | |
353 | only to call in exception handler. returns true if traceback |
|
291 | only to call in exception handler. returns true if traceback |
@@ -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]: |
@@ -1,4 +1,4 b'' | |||||
1 | # Copyright (C) 2005 by Intevation GmbH |
|
1 | # Copyright (C) 2005, 2006 by Intevation GmbH | |
2 | # Author(s): |
|
2 | # Author(s): | |
3 | # Thomas Arendsen Hein <thomas@intevation.de> |
|
3 | # Thomas Arendsen Hein <thomas@intevation.de> | |
4 | # |
|
4 | # |
@@ -28,6 +28,68 b' writing tests:' | |||||
28 |
|
28 | |||
29 | - diff will show the current time |
|
29 | - diff will show the current time | |
30 |
|
30 | |||
31 |
use hg diff | sed "s/\( |
|
31 | use hg diff | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ | |
32 | dates |
|
32 | -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" | |
|
33 | to strip dates | |||
|
34 | ||||
|
35 | - You can append your own hgrc settings to the file that the environment | |||
|
36 | variable HGRCPATH points to. This file is cleared before running a test. | |||
|
37 | ||||
|
38 | You also need to be careful that the tests are portable from one platform | |||
|
39 | to another. You're probably working on Linux, where the GNU toolchain has | |||
|
40 | more (or different) functionality than on MacOS, *BSD, Solaris, AIX, etc. | |||
|
41 | While testing on all platforms is the only sure-fire way to make sure that | |||
|
42 | you've written portable code, here's a list of problems that have been | |||
|
43 | found and fixed in the tests. Another, more comprehensive list may be | |||
|
44 | found in the GNU Autoconf manual, online here: | |||
|
45 | ||||
|
46 | http://www.gnu.org/software/autoconf/manual/html_node/Portable-Shell.html | |||
|
47 | ||||
|
48 | sh: | |||
|
49 | ||||
|
50 | The Bourne shell is a very basic shell. /bin/sh on Linux is typically | |||
|
51 | bash, which even in Bourne-shell mode has many features that Bourne shells | |||
|
52 | on other Unix systems don't have (and even on Linux /bin/sh isn't | |||
|
53 | guaranteed to be bash). You'll need to be careful about constructs that | |||
|
54 | seem ubiquitous, but are actually not available in the least common | |||
|
55 | denominator. While using another shell (ksh, bash explicitly, posix shell, | |||
|
56 | etc.) explicitly may seem like another option, these may not exist in a | |||
|
57 | portable location, and so are generally probably not a good idea. You may | |||
|
58 | find that rewriting the test in python will be easier. | |||
|
59 | ||||
|
60 | - don't use pushd/popd; save the output of "pwd" and use "cd" in place of | |||
|
61 | the pushd, and cd back to the saved pwd instead of popd. | |||
33 |
|
62 | |||
|
63 | - don't use math expressions like let, (( ... )), or $(( ... )); use "expr" | |||
|
64 | instead. | |||
|
65 | ||||
|
66 | grep: | |||
|
67 | ||||
|
68 | - don't use the -q option; redirect stdout to /dev/null instead. | |||
|
69 | ||||
|
70 | - don't use extended regular expressions with grep; use egrep instead, and | |||
|
71 | don't escape any regex operators. | |||
|
72 | ||||
|
73 | sed: | |||
|
74 | ||||
|
75 | - make sure that the beginning-of-line matcher ("^") is at the very | |||
|
76 | beginning of the expression -- it may not be supported inside parens. | |||
|
77 | ||||
|
78 | echo: | |||
|
79 | ||||
|
80 | - echo may interpret "\n" and print a newline; use printf instead if you | |||
|
81 | want a literal "\n" (backslash + n). | |||
|
82 | ||||
|
83 | false: | |||
|
84 | ||||
|
85 | - false is guaranteed only to return a non-zero value; you cannot depend on | |||
|
86 | it being 1. On Solaris in particular, /bin/false returns 255. Rewrite | |||
|
87 | your test to not depend on a particular return value, or create a | |||
|
88 | temporary "false" executable, and call that instead. | |||
|
89 | ||||
|
90 | diff: | |||
|
91 | ||||
|
92 | - don't use the -N option. There's no particularly good workaround short | |||
|
93 | of writing a reasonably complicated replacement script, but substituting | |||
|
94 | gdiff for diff if you can't rewrite the test not to need -N will probably | |||
|
95 | do. |
@@ -211,6 +211,10 b' def run_one(test):' | |||||
211 | sys.stdout.write('.') |
|
211 | sys.stdout.write('.') | |
212 | sys.stdout.flush() |
|
212 | sys.stdout.flush() | |
213 |
|
213 | |||
|
214 | # create a fresh hgrc | |||
|
215 | hgrc = file(HGRCPATH, 'w+') | |||
|
216 | hgrc.close() | |||
|
217 | ||||
214 | err = os.path.join(TESTDIR, test+".err") |
|
218 | err = os.path.join(TESTDIR, test+".err") | |
215 | ref = os.path.join(TESTDIR, test+".out") |
|
219 | ref = os.path.join(TESTDIR, test+".out") | |
216 |
|
220 | |||
@@ -319,11 +323,11 b" os.environ['TZ'] = 'GMT'" | |||||
319 | os.environ["HGEDITOR"] = sys.executable + ' -c "import sys; sys.exit(0)"' |
|
323 | os.environ["HGEDITOR"] = sys.executable + ' -c "import sys; sys.exit(0)"' | |
320 | os.environ["HGMERGE"] = sys.executable + ' -c "import sys; sys.exit(0)"' |
|
324 | os.environ["HGMERGE"] = sys.executable + ' -c "import sys; sys.exit(0)"' | |
321 | os.environ["HGUSER"] = "test" |
|
325 | os.environ["HGUSER"] = "test" | |
322 | os.environ["HGRCPATH"] = "" |
|
|||
323 |
|
326 | |||
324 | TESTDIR = os.environ["TESTDIR"] = os.getcwd() |
|
327 | TESTDIR = os.environ["TESTDIR"] = os.getcwd() | |
325 | HGTMP = os.environ["HGTMP"] = tempfile.mkdtemp("", "hgtests.") |
|
328 | HGTMP = os.environ["HGTMP"] = tempfile.mkdtemp("", "hgtests.") | |
326 | DAEMON_PIDS = os.environ["DAEMON_PIDS"] = os.path.join(HGTMP, 'daemon.pids') |
|
329 | DAEMON_PIDS = os.environ["DAEMON_PIDS"] = os.path.join(HGTMP, 'daemon.pids') | |
|
330 | HGRCPATH = os.environ["HGRCPATH"] = os.path.join(HGTMP, '.hgrc') | |||
327 |
|
331 | |||
328 | vlog("# Using TESTDIR", TESTDIR) |
|
332 | vlog("# Using TESTDIR", TESTDIR) | |
329 | vlog("# Using HGTMP", HGTMP) |
|
333 | vlog("# Using HGTMP", HGTMP) |
@@ -1,8 +1,12 b'' | |||||
1 | #!/bin/sh |
|
1 | #!/bin/sh | |
2 |
|
2 | |||
3 | HGRCPATH=$HGTMP/.hgrc; export HGRCPATH |
|
3 | echo "[extensions]" >> $HGRCPATH | |
4 | echo "[extensions]" >> $HGTMP/.hgrc |
|
4 | echo "mq=" >> $HGRCPATH | |
5 | echo "mq=" >> $HGTMP/.hgrc |
|
5 | cat > $HGTMP/false <<EOF | |
|
6 | #!/bin/sh | |||
|
7 | exit 1 | |||
|
8 | EOF | |||
|
9 | chmod +x $HGTMP/false | |||
6 |
|
10 | |||
7 | hg init foo |
|
11 | hg init foo | |
8 | cd foo |
|
12 | cd foo | |
@@ -11,7 +15,7 b' hg add foo' | |||||
11 |
|
15 | |||
12 | # mq may keep a reference to the repository so __del__ will not be called |
|
16 | # mq may keep a reference to the repository so __del__ will not be called | |
13 | # and .hg/journal.dirstate will not be deleted: |
|
17 | # and .hg/journal.dirstate will not be deleted: | |
14 | HGEDITOR=false hg ci |
|
18 | HGEDITOR=$HGTMP/false hg ci | |
15 | HGEDITOR=false hg ci |
|
19 | HGEDITOR=$HGTMP/false hg ci | |
16 |
|
20 | |||
17 | exit 0 |
|
21 | exit 0 |
@@ -10,3 +10,17 b' cd dir/' | |||||
10 | touch ../foo_2 bar_2 |
|
10 | touch ../foo_2 bar_2 | |
11 | hg -v addremove |
|
11 | hg -v addremove | |
12 | hg -v commit -m "add 2" -d "1000000 0" |
|
12 | hg -v commit -m "add 2" -d "1000000 0" | |
|
13 | ||||
|
14 | cd .. | |||
|
15 | hg init sim | |||
|
16 | cd sim | |||
|
17 | echo a > a | |||
|
18 | echo a >> a | |||
|
19 | echo a >> a | |||
|
20 | echo c > c | |||
|
21 | hg commit -Ama | |||
|
22 | mv a b | |||
|
23 | rm c | |||
|
24 | echo d > d | |||
|
25 | hg addremove -s 0.5 | |||
|
26 | hg commit -mb |
@@ -1,10 +1,15 b'' | |||||
1 | (the addremove command is deprecated; use add and remove --after instead) |
|
|||
2 | adding dir/bar |
|
1 | adding dir/bar | |
3 | adding foo |
|
2 | adding foo | |
4 | dir/bar |
|
3 | dir/bar | |
5 | foo |
|
4 | foo | |
6 | (the addremove command is deprecated; use add and remove --after instead) |
|
|||
7 | adding dir/bar_2 |
|
5 | adding dir/bar_2 | |
8 | adding foo_2 |
|
6 | adding foo_2 | |
9 | dir/bar_2 |
|
7 | dir/bar_2 | |
10 | foo_2 |
|
8 | foo_2 | |
|
9 | adding a | |||
|
10 | adding c | |||
|
11 | adding b | |||
|
12 | adding d | |||
|
13 | removing a | |||
|
14 | removing c | |||
|
15 | recording removal of a as rename to b (100% similar) |
@@ -1,8 +1,5 b'' | |||||
1 | (the addremove command is deprecated; use add and remove --after instead) |
|
|||
2 | adding foo |
|
1 | adding foo | |
3 | (the addremove command is deprecated; use add and remove --after instead) |
|
|||
4 | adding bar |
|
2 | adding bar | |
5 | (the addremove command is deprecated; use add and remove --after instead) |
|
|||
6 | adding baz/bletch |
|
3 | adding baz/bletch | |
7 | test-archive-TIP/.hg_archival.txt |
|
4 | test-archive-TIP/.hg_archival.txt | |
8 | test-archive-TIP/bar |
|
5 | test-archive-TIP/bar |
@@ -1,4 +1,20 b'' | |||||
1 | # default style is like normal output |
|
1 | # default style is like normal output | |
|
2 | 1c1 | |||
|
3 | < changeset: 3:10e46f2dcbf4 | |||
|
4 | --- | |||
|
5 | > changeset: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 | |||
|
6 | 10c10 | |||
|
7 | < changeset: 2:97054abb4ab8 | |||
|
8 | --- | |||
|
9 | > changeset: 2:97054abb4ab824450e9164180baf491ae0078465 | |||
|
10 | 18c18 | |||
|
11 | < changeset: 1:b608e9d1a3f0 | |||
|
12 | --- | |||
|
13 | > changeset: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965 | |||
|
14 | 29c29 | |||
|
15 | < changeset: 0:1e4e1b8f71e0 | |||
|
16 | --- | |||
|
17 | > changeset: 0:1e4e1b8f71e05681d422154f5421e385fec3454f | |||
2 | 18a19 |
|
18 | 18a19 | |
3 | > files: |
|
19 | > files: | |
4 | 29a31 |
|
20 | 29a31 |
@@ -13,7 +13,7 b' echo "%%% should show a removed and b ad' | |||||
13 | hg status |
|
13 | hg status | |
14 |
|
14 | |||
15 | echo "reverting..." |
|
15 | echo "reverting..." | |
16 | hg revert |
|
16 | hg revert --all | |
17 |
|
17 | |||
18 | echo "%%% should show b unknown and a back to normal" |
|
18 | echo "%%% should show b unknown and a back to normal" | |
19 | hg status |
|
19 | hg status | |
@@ -42,10 +42,10 b' echo "%%% should show a removed and b ad' | |||||
42 | hg status |
|
42 | hg status | |
43 |
|
43 | |||
44 | echo "%%% revert should fail" |
|
44 | echo "%%% revert should fail" | |
45 | hg revert |
|
45 | hg revert --all | |
46 |
|
46 | |||
47 | echo "%%% revert should be ok now" |
|
47 | echo "%%% revert should be ok now" | |
48 | hg revert -r2 |
|
48 | hg revert -r2 --all | |
49 |
|
49 | |||
50 | echo "%%% should show b unknown and a marked modified (merged)" |
|
50 | echo "%%% should show b unknown and a marked modified (merged)" | |
51 | hg status |
|
51 | hg status |
@@ -2,7 +2,7 b' A b' | |||||
2 | b |
|
2 | b | |
3 | b: copy a:b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3 |
|
3 | b: copy a:b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3 | |
4 | we should see two history entries |
|
4 | we should see two history entries | |
5 |
changeset: 1:386a3cc01532 |
|
5 | changeset: 1:386a3cc01532 | |
6 | tag: tip |
|
6 | tag: tip | |
7 | user: test |
|
7 | user: test | |
8 | date: Mon Jan 12 13:46:40 1970 +0000 |
|
8 | date: Mon Jan 12 13:46:40 1970 +0000 | |
@@ -11,7 +11,7 b' description:' | |||||
11 | 2 |
|
11 | 2 | |
12 |
|
12 | |||
13 |
|
13 | |||
14 |
changeset: 0:33aaa84a386b |
|
14 | changeset: 0:33aaa84a386b | |
15 | user: test |
|
15 | user: test | |
16 | date: Mon Jan 12 13:46:40 1970 +0000 |
|
16 | date: Mon Jan 12 13:46:40 1970 +0000 | |
17 | files: a |
|
17 | files: a |
@@ -1,8 +1,7 b'' | |||||
1 | #!/bin/sh |
|
1 | #!/bin/sh | |
2 |
|
2 | |||
3 | HGRCPATH=$HGTMP/.hgrc; export HGRCPATH |
|
3 | echo "[extensions]" >> $HGRCPATH | |
4 | echo "[extensions]" >> $HGTMP/.hgrc |
|
4 | echo "fetch=" >> $HGRCPATH | |
5 | echo "fetch=" >> $HGTMP/.hgrc |
|
|||
6 |
|
5 | |||
7 | hg init a |
|
6 | hg init a | |
8 | echo a > a/a |
|
7 | echo a > a/a |
@@ -31,10 +31,10 b' main: we should have a merge here' | |||||
31 | 2 150 71 2 2 a6aef98656b7 c36078bec30d 000000000000 |
|
31 | 2 150 71 2 2 a6aef98656b7 c36078bec30d 000000000000 | |
32 | 3 221 72 3 3 0c2cc6fc80e2 182b283965f1 a6aef98656b7 |
|
32 | 3 221 72 3 3 0c2cc6fc80e2 182b283965f1 a6aef98656b7 | |
33 | log should show foo and quux changed |
|
33 | log should show foo and quux changed | |
34 |
changeset: 3:0c2cc6fc80e2 |
|
34 | changeset: 3:0c2cc6fc80e2 | |
35 | tag: tip |
|
35 | tag: tip | |
36 |
parent: 1:182b283965f1 |
|
36 | parent: 1:182b283965f1 | |
37 |
parent: 2:a6aef98656b7 |
|
37 | parent: 2:a6aef98656b7 | |
38 | user: test |
|
38 | user: test | |
39 | date: Mon Jan 12 13:46:40 1970 +0000 |
|
39 | date: Mon Jan 12 13:46:40 1970 +0000 | |
40 | files: foo quux |
|
40 | files: foo quux |
@@ -45,7 +45,7 b' hg --cwd c head -v' | |||||
45 | hg --cwd b tip --verbose |
|
45 | hg --cwd b tip --verbose | |
46 |
|
46 | |||
47 | echo %% --config |
|
47 | echo %% --config | |
48 |
hg --cwd c --config paths.quuxfoo=bar paths | grep |
|
48 | hg --cwd c --config paths.quuxfoo=bar paths | grep quuxfoo > /dev/null && echo quuxfoo | |
49 | hg --cwd c --config '' tip -q |
|
49 | hg --cwd c --config '' tip -q | |
50 | hg --cwd c --config a.b tip -q |
|
50 | hg --cwd c --config a.b tip -q | |
51 | hg --cwd c --config a tip -q |
|
51 | hg --cwd c --config a tip -q |
@@ -47,7 +47,7 b' 0:b6c483daf290' | |||||
47 | 0:8580ff50825a |
|
47 | 0:8580ff50825a | |
48 | 1:b6c483daf290 |
|
48 | 1:b6c483daf290 | |
49 | %% -v/--verbose |
|
49 | %% -v/--verbose | |
50 |
changeset: 1:b6c483daf290 |
|
50 | changeset: 1:b6c483daf290 | |
51 | tag: tip |
|
51 | tag: tip | |
52 | user: test |
|
52 | user: test | |
53 | date: Thu Jan 01 00:00:01 1970 +0000 |
|
53 | date: Thu Jan 01 00:00:01 1970 +0000 | |
@@ -56,7 +56,7 b' description:' | |||||
56 | b |
|
56 | b | |
57 |
|
57 | |||
58 |
|
58 | |||
59 |
changeset: 0:8580ff50825a |
|
59 | changeset: 0:8580ff50825a | |
60 | user: test |
|
60 | user: test | |
61 | date: Thu Jan 01 00:00:01 1970 +0000 |
|
61 | date: Thu Jan 01 00:00:01 1970 +0000 | |
62 | files: a |
|
62 | files: a | |
@@ -64,7 +64,7 b' description:' | |||||
64 | a |
|
64 | a | |
65 |
|
65 | |||
66 |
|
66 | |||
67 |
changeset: 0:b6c483daf290 |
|
67 | changeset: 0:b6c483daf290 | |
68 | tag: tip |
|
68 | tag: tip | |
69 | user: test |
|
69 | user: test | |
70 | date: Thu Jan 01 00:00:01 1970 +0000 |
|
70 | date: Thu Jan 01 00:00:01 1970 +0000 | |
@@ -114,92 +114,94 b' Mercurial Distributed SCM' | |||||
114 |
|
114 | |||
115 | list of commands (use "hg help -v" to show aliases and global options): |
|
115 | list of commands (use "hg help -v" to show aliases and global options): | |
116 |
|
116 | |||
117 | add add the specified files on the next commit |
|
117 | add add the specified files on the next commit | |
118 | annotate show changeset information per file line |
|
118 | addremove add all new files, delete all missing files (DEPRECATED) | |
119 | archive create unversioned archive of a repository revision |
|
119 | annotate show changeset information per file line | |
120 | backout reverse effect of earlier changeset |
|
120 | archive create unversioned archive of a repository revision | |
121 | bundle create a changegroup file |
|
121 | backout reverse effect of earlier changeset | |
122 | cat output the latest or given revisions of files |
|
122 | bundle create a changegroup file | |
123 | clone make a copy of an existing repository |
|
123 | cat output the latest or given revisions of files | |
124 | commit commit the specified files or all outstanding changes |
|
124 | clone make a copy of an existing repository | |
125 | copy mark files as copied for the next commit |
|
125 | commit commit the specified files or all outstanding changes | |
126 | diff diff repository (or selected files) |
|
126 | copy mark files as copied for the next commit | |
127 | export dump the header and diffs for one or more changesets |
|
127 | diff diff repository (or selected files) | |
128 | grep search for a pattern in specified files and revisions |
|
128 | export dump the header and diffs for one or more changesets | |
129 | heads show current repository heads |
|
129 | grep search for a pattern in specified files and revisions | |
130 | help show help for a command, extension, or list of commands |
|
130 | heads show current repository heads | |
131 | identify print information about the working copy |
|
131 | help show help for a command, extension, or list of commands | |
132 | import import an ordered set of patches |
|
132 | identify print information about the working copy | |
133 | incoming show new changesets found in source |
|
133 | import import an ordered set of patches | |
134 | init create a new repository in the given directory |
|
134 | incoming show new changesets found in source | |
135 | locate locate files matching specific patterns |
|
135 | init create a new repository in the given directory | |
136 | log show revision history of entire repository or files |
|
136 | locate locate files matching specific patterns | |
137 | manifest output the latest or given revision of the project manifest |
|
137 | log show revision history of entire repository or files | |
138 | merge Merge working directory with another revision |
|
138 | manifest output the latest or given revision of the project manifest | |
139 | outgoing show changesets not found in destination |
|
139 | merge Merge working directory with another revision | |
140 | parents show the parents of the working dir or revision |
|
140 | outgoing show changesets not found in destination | |
141 | paths show definition of symbolic path names |
|
141 | parents show the parents of the working dir or revision | |
142 | pull pull changes from the specified source |
|
142 | paths show definition of symbolic path names | |
143 |
pu |
|
143 | pull pull changes from the specified source | |
144 | recover roll back an interrupted transaction |
|
144 | push push changes to the specified destination | |
145 | remove remove the specified files on the next commit |
|
145 | recover roll back an interrupted transaction | |
146 | rename rename files; equivalent of copy + remove |
|
146 | remove remove the specified files on the next commit | |
147 | revert revert files or dirs to their states as of some revision |
|
147 | rename rename files; equivalent of copy + remove | |
148 | rollback roll back the last transaction in this repository |
|
148 | revert revert files or dirs to their states as of some revision | |
149 | root print the root (top) of the current working dir |
|
149 | rollback roll back the last transaction in this repository | |
150 | serve export the repository via HTTP |
|
150 | root print the root (top) of the current working dir | |
151 | status show changed files in the working directory |
|
151 | serve export the repository via HTTP | |
152 | tag add a tag for the current tip or a given revision |
|
152 | status show changed files in the working directory | |
153 | tags list repository tags |
|
153 | tag add a tag for the current tip or a given revision | |
154 | tip show the tip revision |
|
154 | tags list repository tags | |
155 | unbundle apply a changegroup file |
|
155 | tip show the tip revision | |
156 | update update or merge working directory |
|
156 | unbundle apply a changegroup file | |
157 | verify verify the integrity of the repository |
|
157 | update update or merge working directory | |
158 | version output version and copyright information |
|
158 | verify verify the integrity of the repository | |
|
159 | version output version and copyright information | |||
159 | Mercurial Distributed SCM |
|
160 | Mercurial Distributed SCM | |
160 |
|
161 | |||
161 | list of commands (use "hg help -v" to show aliases and global options): |
|
162 | list of commands (use "hg help -v" to show aliases and global options): | |
162 |
|
163 | |||
163 | add add the specified files on the next commit |
|
164 | add add the specified files on the next commit | |
164 | annotate show changeset information per file line |
|
165 | addremove add all new files, delete all missing files (DEPRECATED) | |
165 | archive create unversioned archive of a repository revision |
|
166 | annotate show changeset information per file line | |
166 | backout reverse effect of earlier changeset |
|
167 | archive create unversioned archive of a repository revision | |
167 | bundle create a changegroup file |
|
168 | backout reverse effect of earlier changeset | |
168 | cat output the latest or given revisions of files |
|
169 | bundle create a changegroup file | |
169 | clone make a copy of an existing repository |
|
170 | cat output the latest or given revisions of files | |
170 | commit commit the specified files or all outstanding changes |
|
171 | clone make a copy of an existing repository | |
171 | copy mark files as copied for the next commit |
|
172 | commit commit the specified files or all outstanding changes | |
172 | diff diff repository (or selected files) |
|
173 | copy mark files as copied for the next commit | |
173 | export dump the header and diffs for one or more changesets |
|
174 | diff diff repository (or selected files) | |
174 | grep search for a pattern in specified files and revisions |
|
175 | export dump the header and diffs for one or more changesets | |
175 | heads show current repository heads |
|
176 | grep search for a pattern in specified files and revisions | |
176 | help show help for a command, extension, or list of commands |
|
177 | heads show current repository heads | |
177 | identify print information about the working copy |
|
178 | help show help for a command, extension, or list of commands | |
178 | import import an ordered set of patches |
|
179 | identify print information about the working copy | |
179 | incoming show new changesets found in source |
|
180 | import import an ordered set of patches | |
180 | init create a new repository in the given directory |
|
181 | incoming show new changesets found in source | |
181 | locate locate files matching specific patterns |
|
182 | init create a new repository in the given directory | |
182 | log show revision history of entire repository or files |
|
183 | locate locate files matching specific patterns | |
183 | manifest output the latest or given revision of the project manifest |
|
184 | log show revision history of entire repository or files | |
184 | merge Merge working directory with another revision |
|
185 | manifest output the latest or given revision of the project manifest | |
185 | outgoing show changesets not found in destination |
|
186 | merge Merge working directory with another revision | |
186 | parents show the parents of the working dir or revision |
|
187 | outgoing show changesets not found in destination | |
187 | paths show definition of symbolic path names |
|
188 | parents show the parents of the working dir or revision | |
188 | pull pull changes from the specified source |
|
189 | paths show definition of symbolic path names | |
189 |
pu |
|
190 | pull pull changes from the specified source | |
190 | recover roll back an interrupted transaction |
|
191 | push push changes to the specified destination | |
191 | remove remove the specified files on the next commit |
|
192 | recover roll back an interrupted transaction | |
192 | rename rename files; equivalent of copy + remove |
|
193 | remove remove the specified files on the next commit | |
193 | revert revert files or dirs to their states as of some revision |
|
194 | rename rename files; equivalent of copy + remove | |
194 | rollback roll back the last transaction in this repository |
|
195 | revert revert files or dirs to their states as of some revision | |
195 | root print the root (top) of the current working dir |
|
196 | rollback roll back the last transaction in this repository | |
196 | serve export the repository via HTTP |
|
197 | root print the root (top) of the current working dir | |
197 | status show changed files in the working directory |
|
198 | serve export the repository via HTTP | |
198 | tag add a tag for the current tip or a given revision |
|
199 | status show changed files in the working directory | |
199 | tags list repository tags |
|
200 | tag add a tag for the current tip or a given revision | |
200 | tip show the tip revision |
|
201 | tags list repository tags | |
201 | unbundle apply a changegroup file |
|
202 | tip show the tip revision | |
202 | update update or merge working directory |
|
203 | unbundle apply a changegroup file | |
203 | verify verify the integrity of the repository |
|
204 | update update or merge working directory | |
204 | version output version and copyright information |
|
205 | verify verify the integrity of the repository | |
|
206 | version output version and copyright information | |||
205 | %% not tested: --debugger |
|
207 | %% not tested: --debugger |
@@ -18,6 +18,13 b' head -n 3 port > port1' | |||||
18 | mv port1 port |
|
18 | mv port1 port | |
19 | hg commit -m 4 -u spam -d '4 0' |
|
19 | hg commit -m 4 -u spam -d '4 0' | |
20 | hg grep port port |
|
20 | hg grep port port | |
21 | echo 'FIXME: history is wrong here' |
|
|||
22 | hg grep --all -nu port port |
|
21 | hg grep --all -nu port port | |
23 | hg grep import port |
|
22 | hg grep import port | |
|
23 | ||||
|
24 | hg cp port port2 | |||
|
25 | hg commit -m 4 -u spam -d '5 0' | |||
|
26 | echo '% follow' | |||
|
27 | hg grep -f 'import$' port2 | |||
|
28 | echo deport >> port2 | |||
|
29 | hg commit -m 5 -u eggs -d '6 0' | |||
|
30 | hg grep -f --all -nu port port2 |
@@ -1,10 +1,25 b'' | |||||
1 | port:4:export |
|
1 | port:4:export | |
2 | port:4:vaportight |
|
2 | port:4:vaportight | |
3 | port:4:import/export |
|
3 | port:4:import/export | |
4 | FIXME: history is wrong here |
|
4 | port:4:4:-:spam:import/export | |
5 |
port: |
|
5 | port:3:4:+:eggs:import/export | |
6 | port:1:2:+:eggs:vaportight |
|
6 | port:2:1:-:spam:import | |
7 |
port: |
|
7 | port:2:2:-:spam:export | |
8 |
port: |
|
8 | port:2:1:+:spam:export | |
9 |
port: |
|
9 | port:2:2:+:spam:vaportight | |
|
10 | port:2:3:+:spam:import/export | |||
|
11 | port:1:2:+:eggs:export | |||
|
12 | port:0:1:+:eggs:import | |||
10 | port:4:import/export |
|
13 | port:4:import/export | |
|
14 | % follow | |||
|
15 | port:0:import | |||
|
16 | port2:6:4:+:eggs:deport | |||
|
17 | port:4:4:-:spam:import/export | |||
|
18 | port:3:4:+:eggs:import/export | |||
|
19 | port:2:1:-:spam:import | |||
|
20 | port:2:2:-:spam:export | |||
|
21 | port:2:1:+:spam:export | |||
|
22 | port:2:2:+:spam:vaportight | |||
|
23 | port:2:3:+:spam:import/export | |||
|
24 | port:1:2:+:eggs:export | |||
|
25 | port:0:1:+:eggs:import |
@@ -38,90 +38,92 b' Mercurial Distributed SCM' | |||||
38 |
|
38 | |||
39 | list of commands (use "hg help -v" to show aliases and global options): |
|
39 | list of commands (use "hg help -v" to show aliases and global options): | |
40 |
|
40 | |||
41 | add add the specified files on the next commit |
|
41 | add add the specified files on the next commit | |
42 | annotate show changeset information per file line |
|
42 | addremove add all new files, delete all missing files (DEPRECATED) | |
43 | archive create unversioned archive of a repository revision |
|
43 | annotate show changeset information per file line | |
44 | backout reverse effect of earlier changeset |
|
44 | archive create unversioned archive of a repository revision | |
45 | bundle create a changegroup file |
|
45 | backout reverse effect of earlier changeset | |
46 | cat output the latest or given revisions of files |
|
46 | bundle create a changegroup file | |
47 | clone make a copy of an existing repository |
|
47 | cat output the latest or given revisions of files | |
48 | commit commit the specified files or all outstanding changes |
|
48 | clone make a copy of an existing repository | |
49 | copy mark files as copied for the next commit |
|
49 | commit commit the specified files or all outstanding changes | |
50 | diff diff repository (or selected files) |
|
50 | copy mark files as copied for the next commit | |
51 | export dump the header and diffs for one or more changesets |
|
51 | diff diff repository (or selected files) | |
52 | grep search for a pattern in specified files and revisions |
|
52 | export dump the header and diffs for one or more changesets | |
53 | heads show current repository heads |
|
53 | grep search for a pattern in specified files and revisions | |
54 | help show help for a command, extension, or list of commands |
|
54 | heads show current repository heads | |
55 | identify print information about the working copy |
|
55 | help show help for a command, extension, or list of commands | |
56 | import import an ordered set of patches |
|
56 | identify print information about the working copy | |
57 | incoming show new changesets found in source |
|
57 | import import an ordered set of patches | |
58 | init create a new repository in the given directory |
|
58 | incoming show new changesets found in source | |
59 | locate locate files matching specific patterns |
|
59 | init create a new repository in the given directory | |
60 | log show revision history of entire repository or files |
|
60 | locate locate files matching specific patterns | |
61 | manifest output the latest or given revision of the project manifest |
|
61 | log show revision history of entire repository or files | |
62 | merge Merge working directory with another revision |
|
62 | manifest output the latest or given revision of the project manifest | |
63 | outgoing show changesets not found in destination |
|
63 | merge Merge working directory with another revision | |
64 | parents show the parents of the working dir or revision |
|
64 | outgoing show changesets not found in destination | |
65 | paths show definition of symbolic path names |
|
65 | parents show the parents of the working dir or revision | |
66 | pull pull changes from the specified source |
|
66 | paths show definition of symbolic path names | |
67 |
pu |
|
67 | pull pull changes from the specified source | |
68 | recover roll back an interrupted transaction |
|
68 | push push changes to the specified destination | |
69 | remove remove the specified files on the next commit |
|
69 | recover roll back an interrupted transaction | |
70 | rename rename files; equivalent of copy + remove |
|
70 | remove remove the specified files on the next commit | |
71 | revert revert files or dirs to their states as of some revision |
|
71 | rename rename files; equivalent of copy + remove | |
72 | rollback roll back the last transaction in this repository |
|
72 | revert revert files or dirs to their states as of some revision | |
73 | root print the root (top) of the current working dir |
|
73 | rollback roll back the last transaction in this repository | |
74 | serve export the repository via HTTP |
|
74 | root print the root (top) of the current working dir | |
75 | status show changed files in the working directory |
|
75 | serve export the repository via HTTP | |
76 | tag add a tag for the current tip or a given revision |
|
76 | status show changed files in the working directory | |
77 | tags list repository tags |
|
77 | tag add a tag for the current tip or a given revision | |
78 | tip show the tip revision |
|
78 | tags list repository tags | |
79 | unbundle apply a changegroup file |
|
79 | tip show the tip revision | |
80 | update update or merge working directory |
|
80 | unbundle apply a changegroup file | |
81 | verify verify the integrity of the repository |
|
81 | update update or merge working directory | |
82 | version output version and copyright information |
|
82 | verify verify the integrity of the repository | |
83 | add add the specified files on the next commit |
|
83 | version output version and copyright information | |
84 | annotate show changeset information per file line |
|
84 | add add the specified files on the next commit | |
85 | archive create unversioned archive of a repository revision |
|
85 | addremove add all new files, delete all missing files (DEPRECATED) | |
86 | backout reverse effect of earlier changeset |
|
86 | annotate show changeset information per file line | |
87 | bundle create a changegroup file |
|
87 | archive create unversioned archive of a repository revision | |
88 | cat output the latest or given revisions of files |
|
88 | backout reverse effect of earlier changeset | |
89 | clone make a copy of an existing repository |
|
89 | bundle create a changegroup file | |
90 | commit commit the specified files or all outstanding changes |
|
90 | cat output the latest or given revisions of files | |
91 | copy mark files as copied for the next commit |
|
91 | clone make a copy of an existing repository | |
92 | diff diff repository (or selected files) |
|
92 | commit commit the specified files or all outstanding changes | |
93 | export dump the header and diffs for one or more changesets |
|
93 | copy mark files as copied for the next commit | |
94 | grep search for a pattern in specified files and revisions |
|
94 | diff diff repository (or selected files) | |
95 | heads show current repository heads |
|
95 | export dump the header and diffs for one or more changesets | |
96 | help show help for a command, extension, or list of commands |
|
96 | grep search for a pattern in specified files and revisions | |
97 | identify print information about the working copy |
|
97 | heads show current repository heads | |
98 | import import an ordered set of patches |
|
98 | help show help for a command, extension, or list of commands | |
99 | incoming show new changesets found in source |
|
99 | identify print information about the working copy | |
100 | init create a new repository in the given directory |
|
100 | import import an ordered set of patches | |
101 | locate locate files matching specific patterns |
|
101 | incoming show new changesets found in source | |
102 | log show revision history of entire repository or files |
|
102 | init create a new repository in the given directory | |
103 | manifest output the latest or given revision of the project manifest |
|
103 | locate locate files matching specific patterns | |
104 | merge Merge working directory with another revision |
|
104 | log show revision history of entire repository or files | |
105 | outgoing show changesets not found in destination |
|
105 | manifest output the latest or given revision of the project manifest | |
106 | parents show the parents of the working dir or revision |
|
106 | merge Merge working directory with another revision | |
107 | paths show definition of symbolic path names |
|
107 | outgoing show changesets not found in destination | |
108 | pull pull changes from the specified source |
|
108 | parents show the parents of the working dir or revision | |
109 | push push changes to the specified destination |
|
109 | paths show definition of symbolic path names | |
110 | recover roll back an interrupted transaction |
|
110 | pull pull changes from the specified source | |
111 | remove remove the specified files on the next commit |
|
111 | push push changes to the specified destination | |
112 | rename rename files; equivalent of copy + remove |
|
112 | recover roll back an interrupted transaction | |
113 | revert revert files or dirs to their states as of some revision |
|
113 | remove remove the specified files on the next commit | |
114 | rollback roll back the last transaction in this repository |
|
114 | rename rename files; equivalent of copy + remove | |
115 | root print the root (top) of the current working dir |
|
115 | revert revert files or dirs to their states as of some revision | |
116 | serve export the repository via HTTP |
|
116 | rollback roll back the last transaction in this repository | |
117 | status show changed files in the working directory |
|
117 | root print the root (top) of the current working dir | |
118 | tag add a tag for the current tip or a given revision |
|
118 | serve export the repository via HTTP | |
119 | tags list repository tags |
|
119 | status show changed files in the working directory | |
120 | tip show the tip revision |
|
120 | tag add a tag for the current tip or a given revision | |
121 | unbundle apply a changegroup file |
|
121 | tags list repository tags | |
122 | update update or merge working directory |
|
122 | tip show the tip revision | |
123 | verify verify the integrity of the repository |
|
123 | unbundle apply a changegroup file | |
124 | version output version and copyright information |
|
124 | update update or merge working directory | |
|
125 | verify verify the integrity of the repository | |||
|
126 | version output version and copyright information | |||
125 | hg add [OPTION]... [FILE]... |
|
127 | hg add [OPTION]... [FILE]... | |
126 |
|
128 | |||
127 | add the specified files on the next commit |
|
129 | add the specified files on the next commit | |
@@ -176,6 +178,7 b' options:' | |||||
176 | -r --rev revision |
|
178 | -r --rev revision | |
177 | -a --text treat all files as text |
|
179 | -a --text treat all files as text | |
178 | -p --show-function show which function each change is in |
|
180 | -p --show-function show which function each change is in | |
|
181 | -g --git use git extended diff format | |||
179 | -w --ignore-all-space ignore white space when comparing lines |
|
182 | -w --ignore-all-space ignore white space when comparing lines | |
180 | -b --ignore-space-change ignore changes in the amount of white space |
|
183 | -b --ignore-space-change ignore changes in the amount of white space | |
181 | -B --ignore-blank-lines ignore changes whose lines are all blank |
|
184 | -B --ignore-blank-lines ignore changes whose lines are all blank |
@@ -36,43 +36,43 b' added 3 changesets with 2 changes to 2 f' | |||||
36 | (run 'hg update' to get a working copy) |
|
36 | (run 'hg update' to get a working copy) | |
37 | pretag hook: t=a n=4c52fb2e402287dd5dc052090682536c8406c321 l=0 |
|
37 | pretag hook: t=a n=4c52fb2e402287dd5dc052090682536c8406c321 l=0 | |
38 | precommit hook: p1=4c52fb2e402287dd5dc052090682536c8406c321 p2= |
|
38 | precommit hook: p1=4c52fb2e402287dd5dc052090682536c8406c321 p2= | |
39 |
pretxncommit hook: n= |
|
39 | pretxncommit hook: n=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 p1=4c52fb2e402287dd5dc052090682536c8406c321 p2= | |
40 | 4:4f92e785b90a |
|
40 | 4:8ea2ef7ad3e8 | |
41 |
commit hook: n= |
|
41 | commit hook: n=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 p1=4c52fb2e402287dd5dc052090682536c8406c321 p2= | |
42 | commit hook b |
|
42 | commit hook b | |
43 | tag hook: t=a n=4c52fb2e402287dd5dc052090682536c8406c321 l=0 |
|
43 | tag hook: t=a n=4c52fb2e402287dd5dc052090682536c8406c321 l=0 | |
44 | pretag hook: t=la n=4f92e785b90ae8995dfe156e39dd4fbc3b346a24 l=1 |
|
44 | pretag hook: t=la n=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 l=1 | |
45 | tag hook: t=la n=4f92e785b90ae8995dfe156e39dd4fbc3b346a24 l=1 |
|
45 | tag hook: t=la n=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 l=1 | |
46 | pretag hook: t=fa n=4f92e785b90ae8995dfe156e39dd4fbc3b346a24 l=0 |
|
46 | pretag hook: t=fa n=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 l=0 | |
47 | pretag.forbid hook |
|
47 | pretag.forbid hook | |
48 | abort: pretag.forbid hook exited with status 1 |
|
48 | abort: pretag.forbid hook exited with status 1 | |
49 | pretag hook: t=fla n=4f92e785b90ae8995dfe156e39dd4fbc3b346a24 l=1 |
|
49 | pretag hook: t=fla n=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 l=1 | |
50 | pretag.forbid hook |
|
50 | pretag.forbid hook | |
51 | abort: pretag.forbid hook exited with status 1 |
|
51 | abort: pretag.forbid hook exited with status 1 | |
52 | 4:4f92e785b90a |
|
52 | 4:8ea2ef7ad3e8 | |
53 | precommit hook: p1=4f92e785b90ae8995dfe156e39dd4fbc3b346a24 p2= |
|
53 | precommit hook: p1=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 p2= | |
54 | pretxncommit hook: n=7792358308a2026661cea44f9d47c072813004cb p1=4f92e785b90ae8995dfe156e39dd4fbc3b346a24 p2= |
|
54 | pretxncommit hook: n=fad284daf8c032148abaffcd745dafeceefceb61 p1=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 p2= | |
55 | 5:7792358308a2 |
|
55 | 5:fad284daf8c0 | |
56 |
pretxncommit.forbid hook: tip=5: |
|
56 | pretxncommit.forbid hook: tip=5:fad284daf8c0 | |
57 | abort: pretxncommit.forbid hook exited with status 1 |
|
57 | abort: pretxncommit.forbid hook exited with status 1 | |
58 | transaction abort! |
|
58 | transaction abort! | |
59 | rollback completed |
|
59 | rollback completed | |
60 | 4:4f92e785b90a |
|
60 | 4:8ea2ef7ad3e8 | |
61 | precommit hook: p1=4f92e785b90ae8995dfe156e39dd4fbc3b346a24 p2= |
|
61 | precommit hook: p1=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 p2= | |
62 | precommit.forbid hook |
|
62 | precommit.forbid hook | |
63 | abort: precommit.forbid hook exited with status 1 |
|
63 | abort: precommit.forbid hook exited with status 1 | |
64 | 4:4f92e785b90a |
|
64 | 4:8ea2ef7ad3e8 | |
65 | preupdate hook: p1=b702efe9688826e3a91283852b328b84dbf37bc2 p2= |
|
65 | preupdate hook: p1=b702efe9688826e3a91283852b328b84dbf37bc2 p2= | |
66 | 0 files updated, 0 files merged, 2 files removed, 0 files unresolved |
|
66 | 0 files updated, 0 files merged, 2 files removed, 0 files unresolved | |
67 | preupdate hook: p1=4f92e785b90ae8995dfe156e39dd4fbc3b346a24 p2= |
|
67 | preupdate hook: p1=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 p2= | |
68 | update hook: p1=4f92e785b90ae8995dfe156e39dd4fbc3b346a24 p2= err=0 |
|
68 | update hook: p1=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 p2= err=0 | |
69 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
69 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
70 | 3:4c52fb2e4022 |
|
70 | 3:4c52fb2e4022 | |
71 | prechangegroup.forbid hook |
|
71 | prechangegroup.forbid hook | |
72 | pulling from ../a |
|
72 | pulling from ../a | |
73 | searching for changes |
|
73 | searching for changes | |
74 | abort: prechangegroup.forbid hook exited with status 1 |
|
74 | abort: prechangegroup.forbid hook exited with status 1 | |
75 |
pretxnchangegroup.forbid hook: tip=4: |
|
75 | pretxnchangegroup.forbid hook: tip=4:8ea2ef7ad3e8 | |
76 | pulling from ../a |
|
76 | pulling from ../a | |
77 | searching for changes |
|
77 | searching for changes | |
78 | adding changesets |
|
78 | adding changesets | |
@@ -84,7 +84,7 b' transaction abort!' | |||||
84 | rollback completed |
|
84 | rollback completed | |
85 | 3:4c52fb2e4022 |
|
85 | 3:4c52fb2e4022 | |
86 | preoutgoing hook: s=pull |
|
86 | preoutgoing hook: s=pull | |
87 | outgoing hook: n=4f92e785b90ae8995dfe156e39dd4fbc3b346a24 s=pull |
|
87 | outgoing hook: n=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 s=pull | |
88 | pulling from ../a |
|
88 | pulling from ../a | |
89 | searching for changes |
|
89 | searching for changes | |
90 | adding changesets |
|
90 | adding changesets |
@@ -11,7 +11,7 b' cat hg1.pid hg2.pid >> $DAEMON_PIDS' | |||||
11 |
|
11 | |||
12 | echo % clone via stream |
|
12 | echo % clone via stream | |
13 | http_proxy= hg clone --uncompressed http://localhost:20059/ copy 2>&1 | \ |
|
13 | http_proxy= hg clone --uncompressed http://localhost:20059/ copy 2>&1 | \ | |
14 | sed -e 's/[0-9][0-9.]*/XXX/g' |
|
14 | sed -e 's/[0-9][0-9.]*/XXX/g' -e 's/.\(B\/sec\)/X\1/' | |
15 | hg verify -R copy |
|
15 | hg verify -R copy | |
16 |
|
16 | |||
17 | echo % try to clone via stream, should use pull instead |
|
17 | echo % try to clone via stream, should use pull instead |
@@ -2,7 +2,7 b' adding foo' | |||||
2 | % clone via stream |
|
2 | % clone via stream | |
3 | streaming all changes |
|
3 | streaming all changes | |
4 | XXX files to transfer, XXX bytes of data |
|
4 | XXX files to transfer, XXX bytes of data | |
5 |
transferred XXX bytes in XXX seconds (XXX |
|
5 | transferred XXX bytes in XXX seconds (XXX XB/sec) | |
6 | XXX files updated, XXX files merged, XXX files removed, XXX files unresolved |
|
6 | XXX files updated, XXX files merged, XXX files removed, XXX files unresolved | |
7 | checking changesets |
|
7 | checking changesets | |
8 | checking manifests |
|
8 | checking manifests |
@@ -72,7 +72,7 b' rm -rf b' | |||||
72 |
|
72 | |||
73 | echo % plain diff in email, no subject, no message body, should fail |
|
73 | echo % plain diff in email, no subject, no message body, should fail | |
74 | hg clone -r0 a b |
|
74 | hg clone -r0 a b | |
75 |
grep -v '^ |
|
75 | egrep -v '^(Subject|email)' msg.patch | hg --cwd b import - | |
76 | rm -rf b |
|
76 | rm -rf b | |
77 |
|
77 | |||
78 | echo % hg export in email, should use patch header |
|
78 | echo % hg export in email, should use patch header | |
@@ -89,9 +89,10 b" hg --cwd a ci -u someoneelse -d '1 0' -m" | |||||
89 | echo % hg import in a subdirectory |
|
89 | echo % hg import in a subdirectory | |
90 | hg clone -r0 a b |
|
90 | hg clone -r0 a b | |
91 | hg --cwd a export tip | sed -e 's/d1\/d2\///' > tip.patch |
|
91 | hg --cwd a export tip | sed -e 's/d1\/d2\///' > tip.patch | |
92 | pushd b/d1/d2 2>&1 > /dev/null |
|
92 | dir=`pwd` | |
|
93 | cd b/d1/d2 2>&1 > /dev/null | |||
93 | hg import ../../../tip.patch |
|
94 | hg import ../../../tip.patch | |
94 | popd 2>&1 > /dev/null |
|
95 | cd $dir | |
95 | echo "% message should be 'subdir change'" |
|
96 | echo "% message should be 'subdir change'" | |
96 | hg --cwd b tip | grep 'subdir change' |
|
97 | hg --cwd b tip | grep 'subdir change' | |
97 | echo "% committer should be 'someoneelse'" |
|
98 | echo "% committer should be 'someoneelse'" |
@@ -8,7 +8,6 b' adding file changes' | |||||
8 | added 1 changesets with 2 changes to 2 files |
|
8 | added 1 changesets with 2 changes to 2 files | |
9 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
9 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
10 | applying ../tip.patch |
|
10 | applying ../tip.patch | |
11 | patching file a |
|
|||
12 | % message should be same |
|
11 | % message should be same | |
13 | summary: second change |
|
12 | summary: second change | |
14 | % committer should be same |
|
13 | % committer should be same | |
@@ -21,7 +20,6 b' adding file changes' | |||||
21 | added 1 changesets with 2 changes to 2 files |
|
20 | added 1 changesets with 2 changes to 2 files | |
22 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
21 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
23 | applying ../tip.patch |
|
22 | applying ../tip.patch | |
24 | patching file a |
|
|||
25 | transaction abort! |
|
23 | transaction abort! | |
26 | rollback completed |
|
24 | rollback completed | |
27 | % import of plain diff should be ok with message |
|
25 | % import of plain diff should be ok with message | |
@@ -32,7 +30,6 b' adding file changes' | |||||
32 | added 1 changesets with 2 changes to 2 files |
|
30 | added 1 changesets with 2 changes to 2 files | |
33 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
31 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
34 | applying ../tip.patch |
|
32 | applying ../tip.patch | |
35 | patching file a |
|
|||
36 | % import from stdin |
|
33 | % import from stdin | |
37 | requesting all changes |
|
34 | requesting all changes | |
38 | adding changesets |
|
35 | adding changesets | |
@@ -41,7 +38,6 b' adding file changes' | |||||
41 | added 1 changesets with 2 changes to 2 files |
|
38 | added 1 changesets with 2 changes to 2 files | |
42 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
39 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
43 | applying patch from stdin |
|
40 | applying patch from stdin | |
44 | patching file a |
|
|||
45 | % override commit message |
|
41 | % override commit message | |
46 | requesting all changes |
|
42 | requesting all changes | |
47 | adding changesets |
|
43 | adding changesets | |
@@ -50,7 +46,6 b' adding file changes' | |||||
50 | added 1 changesets with 2 changes to 2 files |
|
46 | added 1 changesets with 2 changes to 2 files | |
51 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
47 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
52 | applying patch from stdin |
|
48 | applying patch from stdin | |
53 | patching file a |
|
|||
54 | summary: override |
|
49 | summary: override | |
55 | % plain diff in email, subject, message body |
|
50 | % plain diff in email, subject, message body | |
56 | requesting all changes |
|
51 | requesting all changes | |
@@ -60,7 +55,6 b' adding file changes' | |||||
60 | added 1 changesets with 2 changes to 2 files |
|
55 | added 1 changesets with 2 changes to 2 files | |
61 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
56 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
62 | applying ../msg.patch |
|
57 | applying ../msg.patch | |
63 | patching file a |
|
|||
64 | user: email patcher |
|
58 | user: email patcher | |
65 | summary: email patch |
|
59 | summary: email patch | |
66 | % plain diff in email, no subject, message body |
|
60 | % plain diff in email, no subject, message body | |
@@ -71,7 +65,6 b' adding file changes' | |||||
71 | added 1 changesets with 2 changes to 2 files |
|
65 | added 1 changesets with 2 changes to 2 files | |
72 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
66 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
73 | applying patch from stdin |
|
67 | applying patch from stdin | |
74 | patching file a |
|
|||
75 | % plain diff in email, subject, no message body |
|
68 | % plain diff in email, subject, no message body | |
76 | requesting all changes |
|
69 | requesting all changes | |
77 | adding changesets |
|
70 | adding changesets | |
@@ -80,7 +73,6 b' adding file changes' | |||||
80 | added 1 changesets with 2 changes to 2 files |
|
73 | added 1 changesets with 2 changes to 2 files | |
81 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
74 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
82 | applying patch from stdin |
|
75 | applying patch from stdin | |
83 | patching file a |
|
|||
84 | % plain diff in email, no subject, no message body, should fail |
|
76 | % plain diff in email, no subject, no message body, should fail | |
85 | requesting all changes |
|
77 | requesting all changes | |
86 | adding changesets |
|
78 | adding changesets | |
@@ -89,7 +81,6 b' adding file changes' | |||||
89 | added 1 changesets with 2 changes to 2 files |
|
81 | added 1 changesets with 2 changes to 2 files | |
90 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
82 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
91 | applying patch from stdin |
|
83 | applying patch from stdin | |
92 | patching file a |
|
|||
93 | transaction abort! |
|
84 | transaction abort! | |
94 | rollback completed |
|
85 | rollback completed | |
95 | % hg export in email, should use patch header |
|
86 | % hg export in email, should use patch header | |
@@ -100,7 +91,6 b' adding file changes' | |||||
100 | added 1 changesets with 2 changes to 2 files |
|
91 | added 1 changesets with 2 changes to 2 files | |
101 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
92 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
102 | applying patch from stdin |
|
93 | applying patch from stdin | |
103 | patching file a |
|
|||
104 | summary: second change |
|
94 | summary: second change | |
105 | % hg import in a subdirectory |
|
95 | % hg import in a subdirectory | |
106 | requesting all changes |
|
96 | requesting all changes | |
@@ -110,7 +100,6 b' adding file changes' | |||||
110 | added 1 changesets with 2 changes to 2 files |
|
100 | added 1 changesets with 2 changes to 2 files | |
111 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
101 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
112 | applying ../../../tip.patch |
|
102 | applying ../../../tip.patch | |
113 | patching file a |
|
|||
114 | % message should be 'subdir change' |
|
103 | % message should be 'subdir change' | |
115 | summary: subdir change |
|
104 | summary: subdir change | |
116 | % committer should be 'someoneelse' |
|
105 | % committer should be 'someoneelse' |
@@ -63,3 +63,6 b" hg ci -Amb1.1 -d'1 0'" | |||||
63 |
|
63 | |||
64 | echo % log --follow-first |
|
64 | echo % log --follow-first | |
65 | hg log --follow-first |
|
65 | hg log --follow-first | |
|
66 | ||||
|
67 | echo % log -P 2 | |||
|
68 | hg log -P 2 |
@@ -34,7 +34,7 b' date: Thu Jan 01 00:00:01 1970 +0' | |||||
34 | summary: a |
|
34 | summary: a | |
35 |
|
35 | |||
36 | % one rename |
|
36 | % one rename | |
37 |
changeset: 0:8580ff50825a |
|
37 | changeset: 0:8580ff50825a | |
38 | user: test |
|
38 | user: test | |
39 | date: Thu Jan 01 00:00:01 1970 +0000 |
|
39 | date: Thu Jan 01 00:00:01 1970 +0000 | |
40 | files: a |
|
40 | files: a | |
@@ -43,7 +43,7 b' a' | |||||
43 |
|
43 | |||
44 |
|
44 | |||
45 | % many renames |
|
45 | % many renames | |
46 |
changeset: 4:8c1c8408f737 |
|
46 | changeset: 4:8c1c8408f737 | |
47 | tag: tip |
|
47 | tag: tip | |
48 | user: test |
|
48 | user: test | |
49 | date: Thu Jan 01 00:00:05 1970 +0000 |
|
49 | date: Thu Jan 01 00:00:05 1970 +0000 | |
@@ -52,7 +52,7 b' description:' | |||||
52 | e |
|
52 | e | |
53 |
|
53 | |||
54 |
|
54 | |||
55 |
changeset: 2:21fba396af4c |
|
55 | changeset: 2:21fba396af4c | |
56 | user: test |
|
56 | user: test | |
57 | date: Thu Jan 01 00:00:03 1970 +0000 |
|
57 | date: Thu Jan 01 00:00:03 1970 +0000 | |
58 | files: b dir/b |
|
58 | files: b dir/b | |
@@ -60,7 +60,7 b' description:' | |||||
60 | c |
|
60 | c | |
61 |
|
61 | |||
62 |
|
62 | |||
63 |
changeset: 1:c0296dabce9b |
|
63 | changeset: 1:c0296dabce9b | |
64 | user: test |
|
64 | user: test | |
65 | date: Thu Jan 01 00:00:02 1970 +0000 |
|
65 | date: Thu Jan 01 00:00:02 1970 +0000 | |
66 | files: b |
|
66 | files: b | |
@@ -68,7 +68,7 b' description:' | |||||
68 | b |
|
68 | b | |
69 |
|
69 | |||
70 |
|
70 | |||
71 |
changeset: 0:8580ff50825a |
|
71 | changeset: 0:8580ff50825a | |
72 | user: test |
|
72 | user: test | |
73 | date: Thu Jan 01 00:00:01 1970 +0000 |
|
73 | date: Thu Jan 01 00:00:01 1970 +0000 | |
74 | files: a |
|
74 | files: a | |
@@ -149,3 +149,29 b' user: test' | |||||
149 | date: Thu Jan 01 00:00:01 1970 +0000 |
|
149 | date: Thu Jan 01 00:00:01 1970 +0000 | |
150 | summary: base |
|
150 | summary: base | |
151 |
|
151 | |||
|
152 | % log -P 2 | |||
|
153 | changeset: 6:2404bbcab562 | |||
|
154 | tag: tip | |||
|
155 | user: test | |||
|
156 | date: Thu Jan 01 00:00:01 1970 +0000 | |||
|
157 | summary: b1.1 | |||
|
158 | ||||
|
159 | changeset: 5:302e9dd6890d | |||
|
160 | parent: 3:e62f78d544b4 | |||
|
161 | parent: 4:ddb82e70d1a1 | |||
|
162 | user: test | |||
|
163 | date: Thu Jan 01 00:00:01 1970 +0000 | |||
|
164 | summary: m12 | |||
|
165 | ||||
|
166 | changeset: 4:ddb82e70d1a1 | |||
|
167 | parent: 0:67e992f2c4f3 | |||
|
168 | user: test | |||
|
169 | date: Thu Jan 01 00:00:01 1970 +0000 | |||
|
170 | summary: b2 | |||
|
171 | ||||
|
172 | changeset: 3:e62f78d544b4 | |||
|
173 | parent: 1:3d5bf5654eda | |||
|
174 | user: test | |||
|
175 | date: Thu Jan 01 00:00:01 1970 +0000 | |||
|
176 | summary: b1 | |||
|
177 |
@@ -15,7 +15,7 b' hg update -C 0' | |||||
15 | hg id |
|
15 | hg id | |
16 | echo "changed file1" >> file1 |
|
16 | echo "changed file1" >> file1 | |
17 | hg id |
|
17 | hg id | |
18 | hg revert |
|
18 | hg revert --all | |
19 | hg diff |
|
19 | hg diff | |
20 | hg status |
|
20 | hg status | |
21 | hg id |
|
21 | hg id | |
@@ -29,11 +29,11 b' HGMERGE=merge hg update' | |||||
29 | hg diff |
|
29 | hg diff | |
30 | hg status |
|
30 | hg status | |
31 | hg id |
|
31 | hg id | |
32 | hg revert |
|
32 | hg revert --all | |
33 | hg diff |
|
33 | hg diff | |
34 | hg status |
|
34 | hg status | |
35 | hg id |
|
35 | hg id | |
36 | hg revert -r tip |
|
36 | hg revert -r tip --all | |
37 | hg diff |
|
37 | hg diff | |
38 | hg status |
|
38 | hg status | |
39 | hg id |
|
39 | hg id |
@@ -16,7 +16,7 b' hg update -C 0' | |||||
16 | hg id |
|
16 | hg id | |
17 | echo "changed file1" >> file1 |
|
17 | echo "changed file1" >> file1 | |
18 | hg id |
|
18 | hg id | |
19 | hg revert --no-backup |
|
19 | hg revert --no-backup --all | |
20 | hg diff |
|
20 | hg diff | |
21 | hg status |
|
21 | hg status | |
22 | hg id |
|
22 | hg id | |
@@ -31,11 +31,11 b' hg diff | sed -e "s/\\(+++ [a-zA-Z0-9_/.-' | |||||
31 | -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" -e "s/\(>>>>>>>\) .*/\1/" |
|
31 | -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" -e "s/\(>>>>>>>\) .*/\1/" | |
32 | hg status |
|
32 | hg status | |
33 | hg id |
|
33 | hg id | |
34 | hg revert --no-backup |
|
34 | hg revert --no-backup --all | |
35 | hg diff |
|
35 | hg diff | |
36 | hg status |
|
36 | hg status | |
37 | hg id |
|
37 | hg id | |
38 | hg revert -r tip --no-backup |
|
38 | hg revert -r tip --no-backup --all | |
39 | hg diff |
|
39 | hg diff | |
40 | hg status |
|
40 | hg status | |
41 | hg id |
|
41 | hg id |
@@ -1,8 +1,7 b'' | |||||
1 | #!/bin/sh |
|
1 | #!/bin/sh | |
2 |
|
2 | |||
3 | HGRCPATH=$HGTMP/.hgrc; export HGRCPATH |
|
3 | echo "[extensions]" >> $HGRCPATH | |
4 | echo "[extensions]" >> $HGTMP/.hgrc |
|
4 | echo "mq=" >> $HGRCPATH | |
5 | echo "mq=" >> $HGTMP/.hgrc |
|
|||
6 |
|
5 | |||
7 | echo % help |
|
6 | echo % help | |
8 | hg help mq |
|
7 | hg help mq | |
@@ -10,6 +9,10 b' hg help mq' | |||||
10 | hg init a |
|
9 | hg init a | |
11 | cd a |
|
10 | cd a | |
12 | echo a > a |
|
11 | echo a > a | |
|
12 | hg ci -Ama | |||
|
13 | ||||
|
14 | hg clone . ../k | |||
|
15 | ||||
13 | mkdir b |
|
16 | mkdir b | |
14 | echo z > b/z |
|
17 | echo z > b/z | |
15 | hg ci -Ama |
|
18 | hg ci -Ama | |
@@ -48,7 +51,7 b' echo % qrefresh' | |||||
48 |
|
51 | |||
49 | echo a >> a |
|
52 | echo a >> a | |
50 | hg qrefresh |
|
53 | hg qrefresh | |
51 |
sed -e "s/\( |
|
54 | sed -e "s/^\(diff -r \)\([a-f0-9]* \)/\1 x/" \ | |
52 | -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ |
|
55 | -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ | |
53 | -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" .hg/patches/test.patch |
|
56 | -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" .hg/patches/test.patch | |
54 |
|
57 | |||
@@ -103,12 +106,49 b' hg qnext' | |||||
103 | hg qprev |
|
106 | hg qprev | |
104 | hg qapplied |
|
107 | hg qapplied | |
105 |
|
108 | |||
|
109 | echo % commit should fail | |||
|
110 | hg commit | |||
|
111 | ||||
|
112 | echo % push should fail | |||
|
113 | hg push ../../k | |||
|
114 | ||||
106 | echo % qunapplied |
|
115 | echo % qunapplied | |
107 | hg qunapplied |
|
116 | hg qunapplied | |
108 |
|
117 | |||
|
118 | echo % push should succeed | |||
|
119 | hg qpop -a | |||
|
120 | hg push ../../k | |||
|
121 | ||||
109 | echo % strip |
|
122 | echo % strip | |
110 | cd ../../b |
|
123 | cd ../../b | |
111 | echo x>x |
|
124 | echo x>x | |
112 | hg ci -Ama |
|
125 | hg ci -Ama | |
113 | hg strip tip 2>&1 | sed 's/\(saving bundle to \).*/\1/' |
|
126 | hg strip tip 2>&1 | sed 's/\(saving bundle to \).*/\1/' | |
114 | hg unbundle .hg/strip-backup/* |
|
127 | hg unbundle .hg/strip-backup/* | |
|
128 | ||||
|
129 | cat >>$HGRCPATH <<EOF | |||
|
130 | [diff] | |||
|
131 | git = True | |||
|
132 | EOF | |||
|
133 | cd .. | |||
|
134 | hg init git | |||
|
135 | cd git | |||
|
136 | hg qinit | |||
|
137 | ||||
|
138 | hg qnew -m'new file' new | |||
|
139 | echo foo > new | |||
|
140 | chmod +x new | |||
|
141 | hg add new | |||
|
142 | hg qrefresh | |||
|
143 | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ | |||
|
144 | -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" .hg/patches/new | |||
|
145 | ||||
|
146 | hg qnew -m'copy file' copy | |||
|
147 | hg cp new copy | |||
|
148 | hg qrefresh | |||
|
149 | sed -e "s/\(+++ [a-zA-Z0-9_/.-]*\).*/\1/" \ | |||
|
150 | -e "s/\(--- [a-zA-Z0-9_/.-]*\).*/\1/" .hg/patches/copy | |||
|
151 | ||||
|
152 | hg qpop | |||
|
153 | hg qpush | |||
|
154 | hg qdiff |
@@ -1,8 +1,7 b'' | |||||
1 | #!/bin/sh |
|
1 | #!/bin/sh | |
2 |
|
2 | |||
3 | HGRCPATH=$HGTMP/.hgrc; export HGRCPATH |
|
3 | echo "[extensions]" >> $HGRCPATH | |
4 | echo "[extensions]" >> $HGTMP/.hgrc |
|
4 | echo "mq=" >> $HGRCPATH | |
5 | echo "mq=" >> $HGTMP/.hgrc |
|
|||
6 |
|
5 | |||
7 | hg init |
|
6 | hg init | |
8 | hg qinit |
|
7 | hg qinit | |
@@ -63,22 +62,39 b' echo % should push all' | |||||
63 | hg qpush -a |
|
62 | hg qpush -a | |
64 |
|
63 | |||
65 | hg qpop -a |
|
64 | hg qpop -a | |
66 |
hg qguard a.patch +1 |
|
65 | hg qguard a.patch +1 | |
|
66 | hg qguard b.patch +2 | |||
67 | hg qselect 1 |
|
67 | hg qselect 1 | |
|
68 | echo % should push a.patch, not b.patch | |||
|
69 | hg qpush | |||
|
70 | hg qpush | |||
|
71 | hg qpop -a | |||
|
72 | ||||
|
73 | hg qselect 2 | |||
68 | echo % should push b.patch |
|
74 | echo % should push b.patch | |
69 | hg qpush |
|
75 | hg qpush | |
70 | hg qpop -a |
|
76 | hg qpop -a | |
71 |
|
77 | |||
72 | hg qselect 2 |
|
78 | hg qselect 1 2 | |
|
79 | echo % should push a.patch, b.patch | |||
73 | hg qpush |
|
80 | hg qpush | |
74 | hg qpop -a |
|
|||
75 |
|
||||
76 | hg qselect 1 2 |
|
|||
77 | echo % should push a.patch |
|
|||
78 | hg qpush |
|
81 | hg qpush | |
79 | hg qpop -a |
|
82 | hg qpop -a | |
80 |
|
83 | |||
81 | hg qguard a.patch +1 +2 -3 |
|
84 | hg qguard a.patch +1 +2 -3 | |
82 | hg qselect 1 2 3 |
|
85 | hg qselect 1 2 3 | |
|
86 | echo % list patches and guards | |||
|
87 | hg qguard -l | |||
|
88 | echo % list series | |||
|
89 | hg qseries -v | |||
|
90 | echo % list guards | |||
|
91 | hg qselect | |||
83 | echo % should push b.patch |
|
92 | echo % should push b.patch | |
84 | hg qpush |
|
93 | hg qpush | |
|
94 | ||||
|
95 | hg qpush -a | |||
|
96 | hg qselect -n --reapply | |||
|
97 | echo % guards in series file: +1 +2 -3 | |||
|
98 | hg qselect -s | |||
|
99 | echo % should show c.patch | |||
|
100 | hg qapplied |
@@ -13,7 +13,7 b' a.patch: +a' | |||||
13 | applying b.patch |
|
13 | applying b.patch | |
14 | Now at: b.patch |
|
14 | Now at: b.patch | |
15 | Patch queue now empty |
|
15 | Patch queue now empty | |
16 | 3 of 3 unapplied patches active |
|
16 | number of unguarded, unapplied patches has changed from 2 to 3 | |
17 | % should push a.patch |
|
17 | % should push a.patch | |
18 | applying a.patch |
|
18 | applying a.patch | |
19 | Now at: a.patch |
|
19 | Now at: a.patch | |
@@ -28,27 +28,57 b' applying c.patch' | |||||
28 | Now at: c.patch |
|
28 | Now at: c.patch | |
29 | Patch queue now empty |
|
29 | Patch queue now empty | |
30 | guards deactivated |
|
30 | guards deactivated | |
31 | 2 of 3 unapplied patches active |
|
31 | number of unguarded, unapplied patches has changed from 3 to 2 | |
32 | % should push all |
|
32 | % should push all | |
33 | applying b.patch |
|
33 | applying b.patch | |
34 | applying c.patch |
|
34 | applying c.patch | |
35 | Now at: c.patch |
|
35 | Now at: c.patch | |
36 | Patch queue now empty |
|
36 | Patch queue now empty | |
37 | 2 of 3 unapplied patches active |
|
37 | number of unguarded, unapplied patches has changed from 1 to 2 | |
|
38 | % should push a.patch, not b.patch | |||
|
39 | applying a.patch | |||
|
40 | Now at: a.patch | |||
|
41 | applying c.patch | |||
|
42 | Now at: c.patch | |||
|
43 | Patch queue now empty | |||
38 | % should push b.patch |
|
44 | % should push b.patch | |
39 | applying b.patch |
|
45 | applying b.patch | |
40 | Now at: b.patch |
|
46 | Now at: b.patch | |
41 | Patch queue now empty |
|
47 | Patch queue now empty | |
42 | 2 of 3 unapplied patches active |
|
48 | number of unguarded, unapplied patches has changed from 2 to 3 | |
|
49 | % should push a.patch, b.patch | |||
|
50 | applying a.patch | |||
|
51 | Now at: a.patch | |||
43 | applying b.patch |
|
52 | applying b.patch | |
44 | Now at: b.patch |
|
53 | Now at: b.patch | |
45 | Patch queue now empty |
|
54 | Patch queue now empty | |
46 | 3 of 3 unapplied patches active |
|
55 | number of unguarded, unapplied patches has changed from 3 to 2 | |
47 | % should push a.patch |
|
56 | % list patches and guards | |
48 | applying a.patch |
|
57 | a.patch: +1 +2 -3 | |
49 | Now at: a.patch |
|
58 | b.patch: +2 | |
50 | Patch queue now empty |
|
59 | c.patch: unguarded | |
51 | 2 of 3 unapplied patches active |
|
60 | % list series | |
|
61 | 0 G a.patch | |||
|
62 | 1 U b.patch | |||
|
63 | 2 U c.patch | |||
|
64 | % list guards | |||
|
65 | 1 | |||
|
66 | 2 | |||
|
67 | 3 | |||
52 | % should push b.patch |
|
68 | % should push b.patch | |
53 | applying b.patch |
|
69 | applying b.patch | |
54 | Now at: b.patch |
|
70 | Now at: b.patch | |
|
71 | applying c.patch | |||
|
72 | Now at: c.patch | |||
|
73 | guards deactivated | |||
|
74 | popping guarded patches | |||
|
75 | Patch queue now empty | |||
|
76 | reapplying unguarded patches | |||
|
77 | applying c.patch | |||
|
78 | Now at: c.patch | |||
|
79 | % guards in series file: +1 +2 -3 | |||
|
80 | +1 | |||
|
81 | +2 | |||
|
82 | -3 | |||
|
83 | % should show c.patch | |||
|
84 | c.patch |
@@ -1,8 +1,7 b'' | |||||
1 | #!/bin/sh |
|
1 | #!/bin/sh | |
2 |
|
2 | |||
3 | HGRCPATH=$HGTMP/.hgrc; export HGRCPATH |
|
3 | echo "[extensions]" >> $HGRCPATH | |
4 | echo "[extensions]" >> $HGTMP/.hgrc |
|
4 | echo "mq=" >> $HGRCPATH | |
5 | echo "mq=" >> $HGTMP/.hgrc |
|
|||
6 |
|
5 | |||
7 | hg init a |
|
6 | hg init a | |
8 | cd a |
|
7 | cd a |
@@ -1,9 +1,8 b'' | |||||
1 | #!/bin/sh |
|
1 | #!/bin/sh | |
2 |
|
2 | |||
3 | # Environement setup for MQ |
|
3 | # Environement setup for MQ | |
4 | HGRCPATH=$HGTMP/.hgrc; export HGRCPATH |
|
4 | echo "[extensions]" >> $HGRCPATH | |
5 | echo "[extensions]" >> $HGTMP/.hgrc |
|
5 | echo "mq=" >> $HGRCPATH | |
6 | echo "mq=" >> $HGTMP/.hgrc |
|
|||
7 |
|
6 | |||
8 | #Repo init |
|
7 | #Repo init | |
9 | hg init |
|
8 | hg init | |
@@ -33,7 +32,7 b' echo " This is the 3rd log message" >> l' | |||||
33 | echo bbbb > file |
|
32 | echo bbbb > file | |
34 | hg qrefresh -l logfile |
|
33 | hg qrefresh -l logfile | |
35 | echo ======================= |
|
34 | echo ======================= | |
36 |
|
|
35 | printf "Should display 'Third commit message\\\n This is the 3rd log message'\n" | |
37 | hg log -l1 -v | sed -n '/description/,$p' |
|
36 | hg log -l1 -v | sed -n '/description/,$p' | |
38 | echo |
|
37 | echo | |
39 |
|
38 | |||
@@ -46,6 +45,6 b' echo bbbb > file2' | |||||
46 | echo " This is the 5th log message" >> logfile) |\ |
|
45 | echo " This is the 5th log message" >> logfile) |\ | |
47 | hg qrefresh -l- |
|
46 | hg qrefresh -l- | |
48 | echo ======================= |
|
47 | echo ======================= | |
49 |
|
|
48 | printf "Should display 'Fifth commit message\\\n This is the 5th log message'\n" | |
50 | hg log -l1 -v | sed -n '/description/,$p' |
|
49 | hg log -l1 -v | sed -n '/description/,$p' | |
51 | echo |
|
50 | echo |
@@ -1,8 +1,7 b'' | |||||
1 | #!/bin/sh |
|
1 | #!/bin/sh | |
2 |
|
2 | |||
3 | HGRCPATH=$HGTMP/.hgrc; export HGRCPATH |
|
3 | echo "[extensions]" >> $HGRCPATH | |
4 | echo "[extensions]" >> $HGTMP/.hgrc |
|
4 | echo "mq=" >> $HGRCPATH | |
5 | echo "mq=" >> $HGTMP/.hgrc |
|
|||
6 |
|
5 | |||
7 | hg init a |
|
6 | hg init a | |
8 | cd a |
|
7 | cd a |
@@ -27,7 +27,7 b' list of commands (use "hg help -v mq" to' | |||||
27 | qapplied print the patches already applied |
|
27 | qapplied print the patches already applied | |
28 | qclone clone main and patch repository at same time |
|
28 | qclone clone main and patch repository at same time | |
29 | qcommit commit changes in the queue repository |
|
29 | qcommit commit changes in the queue repository | |
30 |
qdelete remove |
|
30 | qdelete remove patches from queue | |
31 | qdiff diff of the current patch |
|
31 | qdiff diff of the current patch | |
32 | qfold fold the named patches into the current patch |
|
32 | qfold fold the named patches into the current patch | |
33 | qguard set or print guards for a patch |
|
33 | qguard set or print guards for a patch | |
@@ -49,6 +49,7 b' list of commands (use "hg help -v mq" to' | |||||
49 | qunapplied print the patches not yet applied |
|
49 | qunapplied print the patches not yet applied | |
50 | strip strip a revision and all later revs on the same branch |
|
50 | strip strip a revision and all later revs on the same branch | |
51 | adding a |
|
51 | adding a | |
|
52 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
52 | adding b/z |
|
53 | adding b/z | |
53 | % qinit |
|
54 | % qinit | |
54 | % -R qinit |
|
55 | % -R qinit | |
@@ -102,8 +103,21 b' Now at: test.patch' | |||||
102 | test2.patch |
|
103 | test2.patch | |
103 | Only one patch applied |
|
104 | Only one patch applied | |
104 | test.patch |
|
105 | test.patch | |
|
106 | % commit should fail | |||
|
107 | abort: cannot commit over an applied mq patch | |||
|
108 | % push should fail | |||
|
109 | pushing to ../../k | |||
|
110 | abort: source has mq patches applied | |||
105 | % qunapplied |
|
111 | % qunapplied | |
106 | test2.patch |
|
112 | test2.patch | |
|
113 | % push should succeed | |||
|
114 | Patch queue now empty | |||
|
115 | pushing to ../../k | |||
|
116 | searching for changes | |||
|
117 | adding changesets | |||
|
118 | adding manifests | |||
|
119 | adding file changes | |||
|
120 | added 1 changesets with 1 changes to 1 files | |||
107 | % strip |
|
121 | % strip | |
108 | adding x |
|
122 | adding x | |
109 | 0 files updated, 0 files merged, 1 files removed, 0 files unresolved |
|
123 | 0 files updated, 0 files merged, 1 files removed, 0 files unresolved | |
@@ -113,3 +127,22 b' adding manifests' | |||||
113 | adding file changes |
|
127 | adding file changes | |
114 | added 1 changesets with 1 changes to 1 files |
|
128 | added 1 changesets with 1 changes to 1 files | |
115 | (run 'hg update' to get a working copy) |
|
129 | (run 'hg update' to get a working copy) | |
|
130 | new file | |||
|
131 | ||||
|
132 | diff --git a/new b/new | |||
|
133 | new file mode 100755 | |||
|
134 | --- /dev/null | |||
|
135 | +++ b/new | |||
|
136 | @@ -0,0 +1,1 @@ | |||
|
137 | +foo | |||
|
138 | copy file | |||
|
139 | ||||
|
140 | diff --git a/new b/copy | |||
|
141 | copy from new | |||
|
142 | copy to copy | |||
|
143 | Now at: new | |||
|
144 | applying copy | |||
|
145 | Now at: copy | |||
|
146 | diff --git a/new b/copy | |||
|
147 | copy from new | |||
|
148 | copy to copy |
@@ -14,6 +14,6 b' hg add b/x' | |||||
14 | echo '# should print A b/x' |
|
14 | echo '# should print A b/x' | |
15 | hg st |
|
15 | hg st | |
16 | echo '# should forget b/x' |
|
16 | echo '# should forget b/x' | |
17 | hg revert |
|
17 | hg revert --all | |
18 | echo '# should print nothing' |
|
18 | echo '# should print nothing' | |
19 | hg st b |
|
19 | hg st b |
@@ -1,6 +1,6 b'' | |||||
1 | reverting a |
|
1 | reverting a | |
2 | changeset 3:107ce1ee2b43 backs out changeset 1:25a1420a55f8 |
|
2 | changeset 3:107ce1ee2b43 backs out changeset 1:25a1420a55f8 | |
3 |
merging with changeset 2: |
|
3 | merging with changeset 2:e6c3abc120e7 | |
4 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
4 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
5 | (branch merge, don't forget to commit) |
|
5 | (branch merge, don't forget to commit) | |
6 | abort: invalid date: 'should fail' |
|
6 | abort: invalid date: 'should fail' |
@@ -1,4 +1,3 b'' | |||||
1 | (the addremove command is deprecated; use add and remove --after instead) |
|
|||
2 | adding foo |
|
1 | adding foo | |
3 | checking changesets |
|
2 | checking changesets | |
4 | checking manifests |
|
3 | checking manifests |
@@ -9,7 +9,7 b' hg commit -m 1 -d "1000000 0"' | |||||
9 | hg remove |
|
9 | hg remove | |
10 | rm foo |
|
10 | rm foo | |
11 | hg remove foo |
|
11 | hg remove foo | |
12 | hg revert |
|
12 | hg revert --all | |
13 | rm foo |
|
13 | rm foo | |
14 | hg remove --after |
|
14 | hg remove --after | |
15 | hg commit -m 2 -d "1000000 0" |
|
15 | hg commit -m 2 -d "1000000 0" |
@@ -31,7 +31,7 b' echo %% should show a b c e' | |||||
31 | ls |
|
31 | ls | |
32 | echo %% should verbosely save backup to e.orig |
|
32 | echo %% should verbosely save backup to e.orig | |
33 | echo z > e |
|
33 | echo z > e | |
34 | hg revert -v |
|
34 | hg revert --all -v | |
35 | echo %% should say no changes needed |
|
35 | echo %% should say no changes needed | |
36 | hg revert a |
|
36 | hg revert a | |
37 | echo %% should say file not managed |
|
37 | echo %% should say file not managed | |
@@ -46,9 +46,9 b' echo z > z' | |||||
46 | hg add z |
|
46 | hg add z | |
47 | hg st |
|
47 | hg st | |
48 | echo %% should add a, forget z |
|
48 | echo %% should add a, forget z | |
49 | hg revert -r0 |
|
49 | hg revert --all -r0 | |
50 | echo %% should forget a |
|
50 | echo %% should forget a | |
51 | hg revert -rtip |
|
51 | hg revert --all -rtip | |
52 | rm -f a *.orig |
|
52 | rm -f a *.orig | |
53 | echo %% should silently add a |
|
53 | echo %% should silently add a | |
54 | hg revert -r0 a |
|
54 | hg revert -r0 a | |
@@ -56,7 +56,7 b' hg st a' | |||||
56 |
|
56 | |||
57 | hg update -C |
|
57 | hg update -C | |
58 | chmod +x c |
|
58 | chmod +x c | |
59 | hg revert |
|
59 | hg revert --all | |
60 | echo %% should print non-executable |
|
60 | echo %% should print non-executable | |
61 | test -x c || echo non-executable |
|
61 | test -x c || echo non-executable | |
62 |
|
62 | |||
@@ -64,7 +64,7 b' chmod +x c' | |||||
64 | hg commit -d '1000001 0' -m exe |
|
64 | hg commit -d '1000001 0' -m exe | |
65 |
|
65 | |||
66 | chmod -x c |
|
66 | chmod -x c | |
67 | hg revert |
|
67 | hg revert --all | |
68 | echo %% should print executable |
|
68 | echo %% should print executable | |
69 | test -x c && echo executable |
|
69 | test -x c && echo executable | |
70 |
|
70 | |||
@@ -78,6 +78,11 b" hg commit -d '2 0' -m a" | |||||
78 | hg update 0 |
|
78 | hg update 0 | |
79 | mkdir b |
|
79 | mkdir b | |
80 | echo b > b/b |
|
80 | echo b > b/b | |
|
81 | ||||
|
82 | echo % should fail - no arguments | |||
81 | hg revert -rtip |
|
83 | hg revert -rtip | |
82 |
|
84 | |||
|
85 | echo % should succeed | |||
|
86 | hg revert --all -rtip | |||
|
87 | ||||
83 | true |
|
88 | true |
@@ -13,7 +13,7 b' hg ci -m "2" -d "1000000 0"' | |||||
13 |
|
13 | |||
14 | echo %% Should show unknown |
|
14 | echo %% Should show unknown | |
15 | hg status |
|
15 | hg status | |
16 | hg revert -r 0 |
|
16 | hg revert -r 0 --all | |
17 | echo %% Should show unknown and b removed |
|
17 | echo %% Should show unknown and b removed | |
18 | hg status |
|
18 | hg status | |
19 | echo %% Should show a and unknown |
|
19 | echo %% Should show a and unknown |
@@ -54,4 +54,7 b' executable' | |||||
54 | %% issue 241 |
|
54 | %% issue 241 | |
55 | adding a |
|
55 | adding a | |
56 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
56 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
|
57 | % should fail - no arguments | |||
|
58 | abort: no files or directories specified | |||
|
59 | % should succeed | |||
57 | reverting a |
|
60 | reverting a |
@@ -1,4 +1,3 b'' | |||||
1 | (the addremove command is deprecated; use add and remove --after instead) |
|
|||
2 | adding foo |
|
1 | adding foo | |
3 | checking changesets |
|
2 | checking changesets | |
4 | checking manifests |
|
3 | checking manifests |
@@ -1,6 +1,4 b'' | |||||
1 | (the addremove command is deprecated; use add and remove --after instead) |
|
|||
2 | adding foo |
|
1 | adding foo | |
3 | (the addremove command is deprecated; use add and remove --after instead) |
|
|||
4 | adding bomb |
|
2 | adding bomb | |
5 | adding a.c |
|
3 | adding a.c | |
6 | adding dir/a.o |
|
4 | adding dir/a.o |
@@ -4,11 +4,11 b' user: test' | |||||
4 | date: Mon Jan 12 13:46:40 1970 +0000 |
|
4 | date: Mon Jan 12 13:46:40 1970 +0000 | |
5 | summary: test |
|
5 | summary: test | |
6 |
|
6 | |||
7 |
changeset: 1: |
|
7 | changeset: 1:3ecf002a1c57 | |
8 | tag: tip |
|
8 | tag: tip | |
9 | user: test |
|
9 | user: test | |
10 | date: Mon Jan 12 13:46:40 1970 +0000 |
|
10 | date: Mon Jan 12 13:46:40 1970 +0000 | |
11 |
summary: Added tag bleah for changeset 0acdaf898367 |
|
11 | summary: Added tag bleah for changeset 0acdaf898367 | |
12 |
|
12 | |||
13 | changeset: 0:0acdaf898367 |
|
13 | changeset: 0:0acdaf898367 | |
14 | tag: bleah |
|
14 | tag: bleah | |
@@ -24,9 +24,9 b' failed' | |||||
24 | use of 'hg tag NAME [REV]' is deprecated, please use 'hg tag [-r REV] NAME' instead |
|
24 | use of 'hg tag NAME [REV]' is deprecated, please use 'hg tag [-r REV] NAME' instead | |
25 | 0acdaf8983679e0aac16e811534eb49d7ee1f2b4 bleah |
|
25 | 0acdaf8983679e0aac16e811534eb49d7ee1f2b4 bleah | |
26 | 0acdaf8983679e0aac16e811534eb49d7ee1f2b4 bleah0 |
|
26 | 0acdaf8983679e0aac16e811534eb49d7ee1f2b4 bleah0 | |
27 | c5c60883086f5526bd3e36814b94a73a4e75e172 bleah1 |
|
27 | 3ecf002a1c572a2f3bb4e665417e60fca65bbd42 bleah1 | |
28 | 0 files updated, 0 files merged, 1 files removed, 0 files unresolved |
|
28 | 0 files updated, 0 files merged, 1 files removed, 0 files unresolved | |
29 | 0acdaf8983679e0aac16e811534eb49d7ee1f2b4 foobar |
|
29 | 0acdaf8983679e0aac16e811534eb49d7ee1f2b4 foobar | |
30 | c5c60883086f5526bd3e36814b94a73a4e75e172 bleah1 |
|
30 | 3ecf002a1c572a2f3bb4e665417e60fca65bbd42 bleah1 | |
31 | abort: '\n' cannot be used in a tag name |
|
31 | abort: '\n' cannot be used in a tag name | |
32 | abort: ':' cannot be used in a tag name |
|
32 | abort: ':' cannot be used in a tag name |
@@ -9,7 +9,7 b' hg add a' | |||||
9 | hg commit -m "test" -d "1000000 0" |
|
9 | hg commit -m "test" -d "1000000 0" | |
10 | hg co |
|
10 | hg co | |
11 | hg identify |
|
11 | hg identify | |
12 |
T=`hg tip - |
|
12 | T=`hg tip --debug | head -n 1 | cut -d : -f 3` | |
13 | echo "$T first" > .hgtags |
|
13 | echo "$T first" > .hgtags | |
14 | cat .hgtags |
|
14 | cat .hgtags | |
15 | hg add .hgtags |
|
15 | hg add .hgtags |
@@ -2,35 +2,35 b' unknown' | |||||
2 | 0 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
2 | 0 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
3 | 0acdaf898367 tip |
|
3 | 0acdaf898367 tip | |
4 | 0acdaf8983679e0aac16e811534eb49d7ee1f2b4 first |
|
4 | 0acdaf8983679e0aac16e811534eb49d7ee1f2b4 first | |
5 |
tip 1:8a3ca90d111d |
|
5 | tip 1:8a3ca90d111d | |
6 |
first 0:0acdaf898367 |
|
6 | first 0:0acdaf898367 | |
7 | 8a3ca90d111d tip |
|
7 | 8a3ca90d111d tip | |
8 | M a |
|
8 | M a | |
9 | 8a3ca90d111d+ tip |
|
9 | 8a3ca90d111d+ tip | |
10 | 0 files updated, 0 files merged, 1 files removed, 0 files unresolved |
|
10 | 0 files updated, 0 files merged, 1 files removed, 0 files unresolved | |
11 | 0acdaf898367+ first |
|
11 | 0acdaf898367+ first | |
12 | 0acdaf8983679e0aac16e811534eb49d7ee1f2b4+ first |
|
12 | 0acdaf898367+ first | |
13 | M a |
|
13 | M a | |
14 | 8216907a933d tip |
|
14 | 8216907a933d tip | |
15 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
15 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
16 | (branch merge, don't forget to commit) |
|
16 | (branch merge, don't forget to commit) | |
17 | 8216907a933d+8a3ca90d111d+ tip |
|
17 | 8216907a933d+8a3ca90d111d+ tip | |
18 | M .hgtags |
|
18 | M .hgtags | |
19 |
tip 6: |
|
19 | tip 6:e2174d339386 | |
20 |
first 0:0acdaf898367 |
|
20 | first 0:0acdaf898367 | |
21 |
.hgtags (rev 7: |
|
21 | .hgtags (rev 7:c071f74ab5eb), line 2: cannot parse entry | |
22 |
.hgtags (rev 7: |
|
22 | .hgtags (rev 7:c071f74ab5eb), line 4: node 'foo' is not well formed | |
23 | localtags, line 1: tag 'invalid' refers to unknown node |
|
23 | localtags, line 1: tag 'invalid' refers to unknown node | |
24 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
24 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
25 |
.hgtags (rev 7: |
|
25 | .hgtags (rev 7:c071f74ab5eb), line 2: cannot parse entry | |
26 |
.hgtags (rev 7: |
|
26 | .hgtags (rev 7:c071f74ab5eb), line 4: node 'foo' is not well formed | |
27 | .hgtags (rev 8:4ca6f1b1a68c), line 2: node 'x' is not well formed |
|
27 | .hgtags (rev 8:4ca6f1b1a68c), line 2: node 'x' is not well formed | |
28 | localtags, line 1: tag 'invalid' refers to unknown node |
|
28 | localtags, line 1: tag 'invalid' refers to unknown node | |
29 |
tip 8:4ca6f1b1a68c |
|
29 | tip 8:4ca6f1b1a68c | |
30 |
first 0:0acdaf898367 |
|
30 | first 0:0acdaf898367 | |
31 | changeset: 8:4ca6f1b1a68c |
|
31 | changeset: 8:4ca6f1b1a68c | |
32 |
.hgtags (rev 7: |
|
32 | .hgtags (rev 7:c071f74ab5eb), line 2: cannot parse entry | |
33 |
.hgtags (rev 7: |
|
33 | .hgtags (rev 7:c071f74ab5eb), line 4: node 'foo' is not well formed | |
34 | .hgtags (rev 8:4ca6f1b1a68c), line 2: node 'x' is not well formed |
|
34 | .hgtags (rev 8:4ca6f1b1a68c), line 2: node 'x' is not well formed | |
35 | localtags, line 1: tag 'invalid' refers to unknown node |
|
35 | localtags, line 1: tag 'invalid' refers to unknown node | |
36 | tag: tip |
|
36 | tag: tip |
@@ -1,4 +1,3 b'' | |||||
1 | (the addremove command is deprecated; use add and remove --after instead) |
|
|||
2 | adding a |
|
1 | adding a | |
3 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
2 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
4 | 0 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
3 | 0 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
@@ -8,7 +7,6 b' diff -r 33aaa84a386b a' | |||||
8 | @@ -1,1 +1,1 @@ a |
|
7 | @@ -1,1 +1,1 @@ a | |
9 | -a |
|
8 | -a | |
10 | +abc |
|
9 | +abc | |
11 | (the addremove command is deprecated; use add and remove --after instead) |
|
|||
12 | adding b |
|
10 | adding b | |
13 | M a |
|
11 | M a | |
14 | changeset: 0:33aaa84a386b |
|
12 | changeset: 0:33aaa84a386b | |
@@ -43,7 +41,7 b' user: test' | |||||
43 | date: Mon Jan 12 13:46:40 1970 +0000 |
|
41 | date: Mon Jan 12 13:46:40 1970 +0000 | |
44 | summary: 1 |
|
42 | summary: 1 | |
45 |
|
43 | |||
46 |
abort: there is nothing to merge |
|
44 | abort: there is nothing to merge - use "hg update" instead | |
47 | failed |
|
45 | failed | |
48 | changeset: 0:33aaa84a386b |
|
46 | changeset: 0:33aaa84a386b | |
49 | user: test |
|
47 | user: test | |
@@ -66,7 +64,7 b' user: test' | |||||
66 | date: Mon Jan 12 13:46:40 1970 +0000 |
|
64 | date: Mon Jan 12 13:46:40 1970 +0000 | |
67 | summary: 2 |
|
65 | summary: 2 | |
68 |
|
66 | |||
69 |
changeset: 1:802f095af299 |
|
67 | changeset: 1:802f095af299 | |
70 | tag: tip |
|
68 | tag: tip | |
71 | user: test |
|
69 | user: test | |
72 | date: Mon Jan 12 13:46:40 1970 +0000 |
|
70 | date: Mon Jan 12 13:46:40 1970 +0000 | |
@@ -75,7 +73,7 b' description:' | |||||
75 | 2 |
|
73 | 2 | |
76 |
|
74 | |||
77 |
|
75 | |||
78 |
changeset: 0:33aaa84a386b |
|
76 | changeset: 0:33aaa84a386b | |
79 | user: test |
|
77 | user: test | |
80 | date: Mon Jan 12 13:46:40 1970 +0000 |
|
78 | date: Mon Jan 12 13:46:40 1970 +0000 | |
81 | files: a |
|
79 | files: a | |
@@ -90,7 +88,6 b' diff -r 802f095af299 a' | |||||
90 | -a2 |
|
88 | -a2 | |
91 | +abc |
|
89 | +abc | |
92 | 1 files updated, 0 files merged, 1 files removed, 0 files unresolved |
|
90 | 1 files updated, 0 files merged, 1 files removed, 0 files unresolved | |
93 | (the addremove command is deprecated; use add and remove --after instead) |
|
|||
94 | adding b |
|
91 | adding b | |
95 | M a |
|
92 | M a | |
96 | changeset: 1:802f095af299 |
|
93 | changeset: 1:802f095af299 |
General Comments 0
You need to be logged in to leave comments.
Login now