##// END OF EJS Templates
mq: only read files when needed...
Simon Heimberg -
r8524:21c87b29 default
parent child Browse files
Show More
@@ -1,2612 +1,2628 b''
1 # mq.py - patch queues for mercurial
1 # mq.py - patch queues for mercurial
2 #
2 #
3 # Copyright 2005, 2006 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 of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2, incorporated herein by reference.
6 # GNU General Public License version 2, incorporated herein by reference.
7
7
8 '''patch management and development
8 '''patch management and development
9
9
10 This extension lets you work with a stack of patches in a Mercurial
10 This extension lets you work with a stack of patches in a Mercurial
11 repository. It manages two stacks of patches - all known patches, and
11 repository. It manages two stacks of patches - all known patches, and
12 applied patches (subset of known patches).
12 applied patches (subset of known patches).
13
13
14 Known patches are represented as patch files in the .hg/patches
14 Known patches are represented as patch files in the .hg/patches
15 directory. Applied patches are both patch files and changesets.
15 directory. Applied patches are both patch files and changesets.
16
16
17 Common tasks (use "hg help command" for more details):
17 Common tasks (use "hg help command" for more details):
18
18
19 prepare repository to work with patches qinit
19 prepare repository to work with patches qinit
20 create new patch qnew
20 create new patch qnew
21 import existing patch qimport
21 import existing patch qimport
22
22
23 print patch series qseries
23 print patch series qseries
24 print applied patches qapplied
24 print applied patches qapplied
25 print name of top applied patch qtop
25 print name of top applied patch qtop
26
26
27 add known patch to applied stack qpush
27 add known patch to applied stack qpush
28 remove patch from applied stack qpop
28 remove patch from applied stack qpop
29 refresh contents of top applied patch qrefresh
29 refresh contents of top applied patch qrefresh
30 '''
30 '''
31
31
32 from mercurial.i18n import _
32 from mercurial.i18n import _
33 from mercurial.node import bin, hex, short, nullid, nullrev
33 from mercurial.node import bin, hex, short, nullid, nullrev
34 from mercurial.lock import release
34 from mercurial.lock import release
35 from mercurial import commands, cmdutil, hg, patch, util
35 from mercurial import commands, cmdutil, hg, patch, util
36 from mercurial import repair, extensions, url, error
36 from mercurial import repair, extensions, url, error
37 import os, sys, re, errno
37 import os, sys, re, errno
38
38
39 commands.norepo += " qclone"
39 commands.norepo += " qclone"
40
40
41 # Patch names looks like unix-file names.
41 # Patch names looks like unix-file names.
42 # They must be joinable with queue directory and result in the patch path.
42 # They must be joinable with queue directory and result in the patch path.
43 normname = util.normpath
43 normname = util.normpath
44
44
45 class statusentry:
45 class statusentry:
46 def __init__(self, rev, name=None):
46 def __init__(self, rev, name=None):
47 if not name:
47 if not name:
48 fields = rev.split(':', 1)
48 fields = rev.split(':', 1)
49 if len(fields) == 2:
49 if len(fields) == 2:
50 self.rev, self.name = fields
50 self.rev, self.name = fields
51 else:
51 else:
52 self.rev, self.name = None, None
52 self.rev, self.name = None, None
53 else:
53 else:
54 self.rev, self.name = rev, name
54 self.rev, self.name = rev, name
55
55
56 def __str__(self):
56 def __str__(self):
57 return self.rev + ':' + self.name
57 return self.rev + ':' + self.name
58
58
59 class patchheader(object):
59 class patchheader(object):
60 def __init__(self, message, comments, user, date, haspatch):
60 def __init__(self, message, comments, user, date, haspatch):
61 self.message = message
61 self.message = message
62 self.comments = comments
62 self.comments = comments
63 self.user = user
63 self.user = user
64 self.date = date
64 self.date = date
65 self.haspatch = haspatch
65 self.haspatch = haspatch
66
66
67 def setuser(self, user):
67 def setuser(self, user):
68 if not self.setheader(['From: ', '# User '], user):
68 if not self.setheader(['From: ', '# User '], user):
69 try:
69 try:
70 patchheaderat = self.comments.index('# HG changeset patch')
70 patchheaderat = self.comments.index('# HG changeset patch')
71 self.comments.insert(patchheaderat + 1,'# User ' + user)
71 self.comments.insert(patchheaderat + 1,'# User ' + user)
72 except ValueError:
72 except ValueError:
73 self.comments = ['From: ' + user, ''] + self.comments
73 self.comments = ['From: ' + user, ''] + self.comments
74 self.user = user
74 self.user = user
75
75
76 def setdate(self, date):
76 def setdate(self, date):
77 if self.setheader(['# Date '], date):
77 if self.setheader(['# Date '], date):
78 self.date = date
78 self.date = date
79
79
80 def setmessage(self, message):
80 def setmessage(self, message):
81 if self.comments:
81 if self.comments:
82 self._delmsg()
82 self._delmsg()
83 self.message = [message]
83 self.message = [message]
84 self.comments += self.message
84 self.comments += self.message
85
85
86 def setheader(self, prefixes, new):
86 def setheader(self, prefixes, new):
87 '''Update all references to a field in the patch header.
87 '''Update all references to a field in the patch header.
88 If none found, add it email style.'''
88 If none found, add it email style.'''
89 res = False
89 res = False
90 for prefix in prefixes:
90 for prefix in prefixes:
91 for i in xrange(len(self.comments)):
91 for i in xrange(len(self.comments)):
92 if self.comments[i].startswith(prefix):
92 if self.comments[i].startswith(prefix):
93 self.comments[i] = prefix + new
93 self.comments[i] = prefix + new
94 res = True
94 res = True
95 break
95 break
96 return res
96 return res
97
97
98 def __str__(self):
98 def __str__(self):
99 if not self.comments:
99 if not self.comments:
100 return ''
100 return ''
101 return '\n'.join(self.comments) + '\n\n'
101 return '\n'.join(self.comments) + '\n\n'
102
102
103 def _delmsg(self):
103 def _delmsg(self):
104 '''Remove existing message, keeping the rest of the comments fields.
104 '''Remove existing message, keeping the rest of the comments fields.
105 If comments contains 'subject: ', message will prepend
105 If comments contains 'subject: ', message will prepend
106 the field and a blank line.'''
106 the field and a blank line.'''
107 if self.message:
107 if self.message:
108 subj = 'subject: ' + self.message[0].lower()
108 subj = 'subject: ' + self.message[0].lower()
109 for i in xrange(len(self.comments)):
109 for i in xrange(len(self.comments)):
110 if subj == self.comments[i].lower():
110 if subj == self.comments[i].lower():
111 del self.comments[i]
111 del self.comments[i]
112 self.message = self.message[2:]
112 self.message = self.message[2:]
113 break
113 break
114 ci = 0
114 ci = 0
115 for mi in xrange(len(self.message)):
115 for mi in xrange(len(self.message)):
116 while self.message[mi] != self.comments[ci]:
116 while self.message[mi] != self.comments[ci]:
117 ci += 1
117 ci += 1
118 del self.comments[ci]
118 del self.comments[ci]
119
119
120 class queue:
120 class queue:
121 def __init__(self, ui, path, patchdir=None):
121 def __init__(self, ui, path, patchdir=None):
122 self.basepath = path
122 self.basepath = path
123 self.path = patchdir or os.path.join(path, "patches")
123 self.path = patchdir or os.path.join(path, "patches")
124 self.opener = util.opener(self.path)
124 self.opener = util.opener(self.path)
125 self.ui = ui
125 self.ui = ui
126 self.applied = []
127 self.full_series = []
128 self.applied_dirty = 0
126 self.applied_dirty = 0
129 self.series_dirty = 0
127 self.series_dirty = 0
130 self.series_path = "series"
128 self.series_path = "series"
131 self.status_path = "status"
129 self.status_path = "status"
132 self.guards_path = "guards"
130 self.guards_path = "guards"
133 self.active_guards = None
131 self.active_guards = None
134 self.guards_dirty = False
132 self.guards_dirty = False
135 self._diffopts = None
133 self._diffopts = None
136
134
137 if os.path.exists(self.join(self.series_path)):
135 @util.propertycache
138 self.full_series = self.opener(self.series_path).read().splitlines()
136 def applied(self):
139 self.parse_series()
140
141 if os.path.exists(self.join(self.status_path)):
137 if os.path.exists(self.join(self.status_path)):
142 lines = self.opener(self.status_path).read().splitlines()
138 lines = self.opener(self.status_path).read().splitlines()
143 self.applied = [statusentry(l) for l in lines]
139 return [statusentry(l) for l in lines]
140 return []
141
142 @util.propertycache
143 def full_series(self):
144 if os.path.exists(self.join(self.series_path)):
145 return self.opener(self.series_path).read().splitlines()
146 return []
147
148 @util.propertycache
149 def series(self):
150 self.parse_series()
151 return self.series
152
153 @util.propertycache
154 def series_guards(self):
155 self.parse_series()
156 return self.series_guards
144
157
145 def diffopts(self):
158 def diffopts(self):
146 if self._diffopts is None:
159 if self._diffopts is None:
147 self._diffopts = patch.diffopts(self.ui)
160 self._diffopts = patch.diffopts(self.ui)
148 return self._diffopts
161 return self._diffopts
149
162
150 def join(self, *p):
163 def join(self, *p):
151 return os.path.join(self.path, *p)
164 return os.path.join(self.path, *p)
152
165
153 def find_series(self, patch):
166 def find_series(self, patch):
154 pre = re.compile("(\s*)([^#]+)")
167 pre = re.compile("(\s*)([^#]+)")
155 index = 0
168 index = 0
156 for l in self.full_series:
169 for l in self.full_series:
157 m = pre.match(l)
170 m = pre.match(l)
158 if m:
171 if m:
159 s = m.group(2)
172 s = m.group(2)
160 s = s.rstrip()
173 s = s.rstrip()
161 if s == patch:
174 if s == patch:
162 return index
175 return index
163 index += 1
176 index += 1
164 return None
177 return None
165
178
166 guard_re = re.compile(r'\s?#([-+][^-+# \t\r\n\f][^# \t\r\n\f]*)')
179 guard_re = re.compile(r'\s?#([-+][^-+# \t\r\n\f][^# \t\r\n\f]*)')
167
180
168 def parse_series(self):
181 def parse_series(self):
169 self.series = []
182 self.series = []
170 self.series_guards = []
183 self.series_guards = []
171 for l in self.full_series:
184 for l in self.full_series:
172 h = l.find('#')
185 h = l.find('#')
173 if h == -1:
186 if h == -1:
174 patch = l
187 patch = l
175 comment = ''
188 comment = ''
176 elif h == 0:
189 elif h == 0:
177 continue
190 continue
178 else:
191 else:
179 patch = l[:h]
192 patch = l[:h]
180 comment = l[h:]
193 comment = l[h:]
181 patch = patch.strip()
194 patch = patch.strip()
182 if patch:
195 if patch:
183 if patch in self.series:
196 if patch in self.series:
184 raise util.Abort(_('%s appears more than once in %s') %
197 raise util.Abort(_('%s appears more than once in %s') %
185 (patch, self.join(self.series_path)))
198 (patch, self.join(self.series_path)))
186 self.series.append(patch)
199 self.series.append(patch)
187 self.series_guards.append(self.guard_re.findall(comment))
200 self.series_guards.append(self.guard_re.findall(comment))
188
201
189 def check_guard(self, guard):
202 def check_guard(self, guard):
190 if not guard:
203 if not guard:
191 return _('guard cannot be an empty string')
204 return _('guard cannot be an empty string')
192 bad_chars = '# \t\r\n\f'
205 bad_chars = '# \t\r\n\f'
193 first = guard[0]
206 first = guard[0]
194 if first in '-+':
207 if first in '-+':
195 return (_('guard %r starts with invalid character: %r') %
208 return (_('guard %r starts with invalid character: %r') %
196 (guard, first))
209 (guard, first))
197 for c in bad_chars:
210 for c in bad_chars:
198 if c in guard:
211 if c in guard:
199 return _('invalid character in guard %r: %r') % (guard, c)
212 return _('invalid character in guard %r: %r') % (guard, c)
200
213
201 def set_active(self, guards):
214 def set_active(self, guards):
202 for guard in guards:
215 for guard in guards:
203 bad = self.check_guard(guard)
216 bad = self.check_guard(guard)
204 if bad:
217 if bad:
205 raise util.Abort(bad)
218 raise util.Abort(bad)
206 guards = sorted(set(guards))
219 guards = sorted(set(guards))
207 self.ui.debug(_('active guards: %s\n') % ' '.join(guards))
220 self.ui.debug(_('active guards: %s\n') % ' '.join(guards))
208 self.active_guards = guards
221 self.active_guards = guards
209 self.guards_dirty = True
222 self.guards_dirty = True
210
223
211 def active(self):
224 def active(self):
212 if self.active_guards is None:
225 if self.active_guards is None:
213 self.active_guards = []
226 self.active_guards = []
214 try:
227 try:
215 guards = self.opener(self.guards_path).read().split()
228 guards = self.opener(self.guards_path).read().split()
216 except IOError, err:
229 except IOError, err:
217 if err.errno != errno.ENOENT: raise
230 if err.errno != errno.ENOENT: raise
218 guards = []
231 guards = []
219 for i, guard in enumerate(guards):
232 for i, guard in enumerate(guards):
220 bad = self.check_guard(guard)
233 bad = self.check_guard(guard)
221 if bad:
234 if bad:
222 self.ui.warn('%s:%d: %s\n' %
235 self.ui.warn('%s:%d: %s\n' %
223 (self.join(self.guards_path), i + 1, bad))
236 (self.join(self.guards_path), i + 1, bad))
224 else:
237 else:
225 self.active_guards.append(guard)
238 self.active_guards.append(guard)
226 return self.active_guards
239 return self.active_guards
227
240
228 def set_guards(self, idx, guards):
241 def set_guards(self, idx, guards):
229 for g in guards:
242 for g in guards:
230 if len(g) < 2:
243 if len(g) < 2:
231 raise util.Abort(_('guard %r too short') % g)
244 raise util.Abort(_('guard %r too short') % g)
232 if g[0] not in '-+':
245 if g[0] not in '-+':
233 raise util.Abort(_('guard %r starts with invalid char') % g)
246 raise util.Abort(_('guard %r starts with invalid char') % g)
234 bad = self.check_guard(g[1:])
247 bad = self.check_guard(g[1:])
235 if bad:
248 if bad:
236 raise util.Abort(bad)
249 raise util.Abort(bad)
237 drop = self.guard_re.sub('', self.full_series[idx])
250 drop = self.guard_re.sub('', self.full_series[idx])
238 self.full_series[idx] = drop + ''.join([' #' + g for g in guards])
251 self.full_series[idx] = drop + ''.join([' #' + g for g in guards])
239 self.parse_series()
252 self.parse_series()
240 self.series_dirty = True
253 self.series_dirty = True
241
254
242 def pushable(self, idx):
255 def pushable(self, idx):
243 if isinstance(idx, str):
256 if isinstance(idx, str):
244 idx = self.series.index(idx)
257 idx = self.series.index(idx)
245 patchguards = self.series_guards[idx]
258 patchguards = self.series_guards[idx]
246 if not patchguards:
259 if not patchguards:
247 return True, None
260 return True, None
248 guards = self.active()
261 guards = self.active()
249 exactneg = [g for g in patchguards if g[0] == '-' and g[1:] in guards]
262 exactneg = [g for g in patchguards if g[0] == '-' and g[1:] in guards]
250 if exactneg:
263 if exactneg:
251 return False, exactneg[0]
264 return False, exactneg[0]
252 pos = [g for g in patchguards if g[0] == '+']
265 pos = [g for g in patchguards if g[0] == '+']
253 exactpos = [g for g in pos if g[1:] in guards]
266 exactpos = [g for g in pos if g[1:] in guards]
254 if pos:
267 if pos:
255 if exactpos:
268 if exactpos:
256 return True, exactpos[0]
269 return True, exactpos[0]
257 return False, pos
270 return False, pos
258 return True, ''
271 return True, ''
259
272
260 def explain_pushable(self, idx, all_patches=False):
273 def explain_pushable(self, idx, all_patches=False):
261 write = all_patches and self.ui.write or self.ui.warn
274 write = all_patches and self.ui.write or self.ui.warn
262 if all_patches or self.ui.verbose:
275 if all_patches or self.ui.verbose:
263 if isinstance(idx, str):
276 if isinstance(idx, str):
264 idx = self.series.index(idx)
277 idx = self.series.index(idx)
265 pushable, why = self.pushable(idx)
278 pushable, why = self.pushable(idx)
266 if all_patches and pushable:
279 if all_patches and pushable:
267 if why is None:
280 if why is None:
268 write(_('allowing %s - no guards in effect\n') %
281 write(_('allowing %s - no guards in effect\n') %
269 self.series[idx])
282 self.series[idx])
270 else:
283 else:
271 if not why:
284 if not why:
272 write(_('allowing %s - no matching negative guards\n') %
285 write(_('allowing %s - no matching negative guards\n') %
273 self.series[idx])
286 self.series[idx])
274 else:
287 else:
275 write(_('allowing %s - guarded by %r\n') %
288 write(_('allowing %s - guarded by %r\n') %
276 (self.series[idx], why))
289 (self.series[idx], why))
277 if not pushable:
290 if not pushable:
278 if why:
291 if why:
279 write(_('skipping %s - guarded by %r\n') %
292 write(_('skipping %s - guarded by %r\n') %
280 (self.series[idx], why))
293 (self.series[idx], why))
281 else:
294 else:
282 write(_('skipping %s - no matching guards\n') %
295 write(_('skipping %s - no matching guards\n') %
283 self.series[idx])
296 self.series[idx])
284
297
285 def save_dirty(self):
298 def save_dirty(self):
286 def write_list(items, path):
299 def write_list(items, path):
287 fp = self.opener(path, 'w')
300 fp = self.opener(path, 'w')
288 for i in items:
301 for i in items:
289 fp.write("%s\n" % i)
302 fp.write("%s\n" % i)
290 fp.close()
303 fp.close()
291 if self.applied_dirty: write_list(map(str, self.applied), self.status_path)
304 if self.applied_dirty: write_list(map(str, self.applied), self.status_path)
292 if self.series_dirty: write_list(self.full_series, self.series_path)
305 if self.series_dirty: write_list(self.full_series, self.series_path)
293 if self.guards_dirty: write_list(self.active_guards, self.guards_path)
306 if self.guards_dirty: write_list(self.active_guards, self.guards_path)
294
307
295 def readheaders(self, patch):
308 def readheaders(self, patch):
296 def eatdiff(lines):
309 def eatdiff(lines):
297 while lines:
310 while lines:
298 l = lines[-1]
311 l = lines[-1]
299 if (l.startswith("diff -") or
312 if (l.startswith("diff -") or
300 l.startswith("Index:") or
313 l.startswith("Index:") or
301 l.startswith("===========")):
314 l.startswith("===========")):
302 del lines[-1]
315 del lines[-1]
303 else:
316 else:
304 break
317 break
305 def eatempty(lines):
318 def eatempty(lines):
306 while lines:
319 while lines:
307 l = lines[-1]
320 l = lines[-1]
308 if re.match('\s*$', l):
321 if re.match('\s*$', l):
309 del lines[-1]
322 del lines[-1]
310 else:
323 else:
311 break
324 break
312
325
313 pf = self.join(patch)
326 pf = self.join(patch)
314 message = []
327 message = []
315 comments = []
328 comments = []
316 user = None
329 user = None
317 date = None
330 date = None
318 format = None
331 format = None
319 subject = None
332 subject = None
320 diffstart = 0
333 diffstart = 0
321
334
322 for line in file(pf):
335 for line in file(pf):
323 line = line.rstrip()
336 line = line.rstrip()
324 if line.startswith('diff --git'):
337 if line.startswith('diff --git'):
325 diffstart = 2
338 diffstart = 2
326 break
339 break
327 if diffstart:
340 if diffstart:
328 if line.startswith('+++ '):
341 if line.startswith('+++ '):
329 diffstart = 2
342 diffstart = 2
330 break
343 break
331 if line.startswith("--- "):
344 if line.startswith("--- "):
332 diffstart = 1
345 diffstart = 1
333 continue
346 continue
334 elif format == "hgpatch":
347 elif format == "hgpatch":
335 # parse values when importing the result of an hg export
348 # parse values when importing the result of an hg export
336 if line.startswith("# User "):
349 if line.startswith("# User "):
337 user = line[7:]
350 user = line[7:]
338 elif line.startswith("# Date "):
351 elif line.startswith("# Date "):
339 date = line[7:]
352 date = line[7:]
340 elif not line.startswith("# ") and line:
353 elif not line.startswith("# ") and line:
341 message.append(line)
354 message.append(line)
342 format = None
355 format = None
343 elif line == '# HG changeset patch':
356 elif line == '# HG changeset patch':
344 format = "hgpatch"
357 format = "hgpatch"
345 elif (format != "tagdone" and (line.startswith("Subject: ") or
358 elif (format != "tagdone" and (line.startswith("Subject: ") or
346 line.startswith("subject: "))):
359 line.startswith("subject: "))):
347 subject = line[9:]
360 subject = line[9:]
348 format = "tag"
361 format = "tag"
349 elif (format != "tagdone" and (line.startswith("From: ") or
362 elif (format != "tagdone" and (line.startswith("From: ") or
350 line.startswith("from: "))):
363 line.startswith("from: "))):
351 user = line[6:]
364 user = line[6:]
352 format = "tag"
365 format = "tag"
353 elif format == "tag" and line == "":
366 elif format == "tag" and line == "":
354 # when looking for tags (subject: from: etc) they
367 # when looking for tags (subject: from: etc) they
355 # end once you find a blank line in the source
368 # end once you find a blank line in the source
356 format = "tagdone"
369 format = "tagdone"
357 elif message or line:
370 elif message or line:
358 message.append(line)
371 message.append(line)
359 comments.append(line)
372 comments.append(line)
360
373
361 eatdiff(message)
374 eatdiff(message)
362 eatdiff(comments)
375 eatdiff(comments)
363 eatempty(message)
376 eatempty(message)
364 eatempty(comments)
377 eatempty(comments)
365
378
366 # make sure message isn't empty
379 # make sure message isn't empty
367 if format and format.startswith("tag") and subject:
380 if format and format.startswith("tag") and subject:
368 message.insert(0, "")
381 message.insert(0, "")
369 message.insert(0, subject)
382 message.insert(0, subject)
370 return patchheader(message, comments, user, date, diffstart > 1)
383 return patchheader(message, comments, user, date, diffstart > 1)
371
384
372 def removeundo(self, repo):
385 def removeundo(self, repo):
373 undo = repo.sjoin('undo')
386 undo = repo.sjoin('undo')
374 if not os.path.exists(undo):
387 if not os.path.exists(undo):
375 return
388 return
376 try:
389 try:
377 os.unlink(undo)
390 os.unlink(undo)
378 except OSError, inst:
391 except OSError, inst:
379 self.ui.warn(_('error removing undo: %s\n') % str(inst))
392 self.ui.warn(_('error removing undo: %s\n') % str(inst))
380
393
381 def printdiff(self, repo, node1, node2=None, files=None,
394 def printdiff(self, repo, node1, node2=None, files=None,
382 fp=None, changes=None, opts={}):
395 fp=None, changes=None, opts={}):
383 m = cmdutil.match(repo, files, opts)
396 m = cmdutil.match(repo, files, opts)
384 chunks = patch.diff(repo, node1, node2, m, changes, self.diffopts())
397 chunks = patch.diff(repo, node1, node2, m, changes, self.diffopts())
385 write = fp is None and repo.ui.write or fp.write
398 write = fp is None and repo.ui.write or fp.write
386 for chunk in chunks:
399 for chunk in chunks:
387 write(chunk)
400 write(chunk)
388
401
389 def mergeone(self, repo, mergeq, head, patch, rev):
402 def mergeone(self, repo, mergeq, head, patch, rev):
390 # first try just applying the patch
403 # first try just applying the patch
391 (err, n) = self.apply(repo, [ patch ], update_status=False,
404 (err, n) = self.apply(repo, [ patch ], update_status=False,
392 strict=True, merge=rev)
405 strict=True, merge=rev)
393
406
394 if err == 0:
407 if err == 0:
395 return (err, n)
408 return (err, n)
396
409
397 if n is None:
410 if n is None:
398 raise util.Abort(_("apply failed for patch %s") % patch)
411 raise util.Abort(_("apply failed for patch %s") % patch)
399
412
400 self.ui.warn(_("patch didn't work out, merging %s\n") % patch)
413 self.ui.warn(_("patch didn't work out, merging %s\n") % patch)
401
414
402 # apply failed, strip away that rev and merge.
415 # apply failed, strip away that rev and merge.
403 hg.clean(repo, head)
416 hg.clean(repo, head)
404 self.strip(repo, n, update=False, backup='strip')
417 self.strip(repo, n, update=False, backup='strip')
405
418
406 ctx = repo[rev]
419 ctx = repo[rev]
407 ret = hg.merge(repo, rev)
420 ret = hg.merge(repo, rev)
408 if ret:
421 if ret:
409 raise util.Abort(_("update returned %d") % ret)
422 raise util.Abort(_("update returned %d") % ret)
410 n = repo.commit(None, ctx.description(), ctx.user(), force=1)
423 n = repo.commit(None, ctx.description(), ctx.user(), force=1)
411 if n == None:
424 if n == None:
412 raise util.Abort(_("repo commit failed"))
425 raise util.Abort(_("repo commit failed"))
413 try:
426 try:
414 ph = mergeq.readheaders(patch)
427 ph = mergeq.readheaders(patch)
415 except:
428 except:
416 raise util.Abort(_("unable to read %s") % patch)
429 raise util.Abort(_("unable to read %s") % patch)
417
430
418 patchf = self.opener(patch, "w")
431 patchf = self.opener(patch, "w")
419 comments = str(ph)
432 comments = str(ph)
420 if comments:
433 if comments:
421 patchf.write(comments)
434 patchf.write(comments)
422 self.printdiff(repo, head, n, fp=patchf)
435 self.printdiff(repo, head, n, fp=patchf)
423 patchf.close()
436 patchf.close()
424 self.removeundo(repo)
437 self.removeundo(repo)
425 return (0, n)
438 return (0, n)
426
439
427 def qparents(self, repo, rev=None):
440 def qparents(self, repo, rev=None):
428 if rev is None:
441 if rev is None:
429 (p1, p2) = repo.dirstate.parents()
442 (p1, p2) = repo.dirstate.parents()
430 if p2 == nullid:
443 if p2 == nullid:
431 return p1
444 return p1
432 if len(self.applied) == 0:
445 if len(self.applied) == 0:
433 return None
446 return None
434 return bin(self.applied[-1].rev)
447 return bin(self.applied[-1].rev)
435 pp = repo.changelog.parents(rev)
448 pp = repo.changelog.parents(rev)
436 if pp[1] != nullid:
449 if pp[1] != nullid:
437 arevs = [ x.rev for x in self.applied ]
450 arevs = [ x.rev for x in self.applied ]
438 p0 = hex(pp[0])
451 p0 = hex(pp[0])
439 p1 = hex(pp[1])
452 p1 = hex(pp[1])
440 if p0 in arevs:
453 if p0 in arevs:
441 return pp[0]
454 return pp[0]
442 if p1 in arevs:
455 if p1 in arevs:
443 return pp[1]
456 return pp[1]
444 return pp[0]
457 return pp[0]
445
458
446 def mergepatch(self, repo, mergeq, series):
459 def mergepatch(self, repo, mergeq, series):
447 if len(self.applied) == 0:
460 if len(self.applied) == 0:
448 # each of the patches merged in will have two parents. This
461 # each of the patches merged in will have two parents. This
449 # can confuse the qrefresh, qdiff, and strip code because it
462 # can confuse the qrefresh, qdiff, and strip code because it
450 # needs to know which parent is actually in the patch queue.
463 # needs to know which parent is actually in the patch queue.
451 # so, we insert a merge marker with only one parent. This way
464 # so, we insert a merge marker with only one parent. This way
452 # the first patch in the queue is never a merge patch
465 # the first patch in the queue is never a merge patch
453 #
466 #
454 pname = ".hg.patches.merge.marker"
467 pname = ".hg.patches.merge.marker"
455 n = repo.commit(None, '[mq]: merge marker', user=None, force=1)
468 n = repo.commit(None, '[mq]: merge marker', user=None, force=1)
456 self.removeundo(repo)
469 self.removeundo(repo)
457 self.applied.append(statusentry(hex(n), pname))
470 self.applied.append(statusentry(hex(n), pname))
458 self.applied_dirty = 1
471 self.applied_dirty = 1
459
472
460 head = self.qparents(repo)
473 head = self.qparents(repo)
461
474
462 for patch in series:
475 for patch in series:
463 patch = mergeq.lookup(patch, strict=True)
476 patch = mergeq.lookup(patch, strict=True)
464 if not patch:
477 if not patch:
465 self.ui.warn(_("patch %s does not exist\n") % patch)
478 self.ui.warn(_("patch %s does not exist\n") % patch)
466 return (1, None)
479 return (1, None)
467 pushable, reason = self.pushable(patch)
480 pushable, reason = self.pushable(patch)
468 if not pushable:
481 if not pushable:
469 self.explain_pushable(patch, all_patches=True)
482 self.explain_pushable(patch, all_patches=True)
470 continue
483 continue
471 info = mergeq.isapplied(patch)
484 info = mergeq.isapplied(patch)
472 if not info:
485 if not info:
473 self.ui.warn(_("patch %s is not applied\n") % patch)
486 self.ui.warn(_("patch %s is not applied\n") % patch)
474 return (1, None)
487 return (1, None)
475 rev = bin(info[1])
488 rev = bin(info[1])
476 (err, head) = self.mergeone(repo, mergeq, head, patch, rev)
489 (err, head) = self.mergeone(repo, mergeq, head, patch, rev)
477 if head:
490 if head:
478 self.applied.append(statusentry(hex(head), patch))
491 self.applied.append(statusentry(hex(head), patch))
479 self.applied_dirty = 1
492 self.applied_dirty = 1
480 if err:
493 if err:
481 return (err, head)
494 return (err, head)
482 self.save_dirty()
495 self.save_dirty()
483 return (0, head)
496 return (0, head)
484
497
485 def patch(self, repo, patchfile):
498 def patch(self, repo, patchfile):
486 '''Apply patchfile to the working directory.
499 '''Apply patchfile to the working directory.
487 patchfile: file name of patch'''
500 patchfile: file name of patch'''
488 files = {}
501 files = {}
489 try:
502 try:
490 fuzz = patch.patch(patchfile, self.ui, strip=1, cwd=repo.root,
503 fuzz = patch.patch(patchfile, self.ui, strip=1, cwd=repo.root,
491 files=files)
504 files=files)
492 except Exception, inst:
505 except Exception, inst:
493 self.ui.note(str(inst) + '\n')
506 self.ui.note(str(inst) + '\n')
494 if not self.ui.verbose:
507 if not self.ui.verbose:
495 self.ui.warn(_("patch failed, unable to continue (try -v)\n"))
508 self.ui.warn(_("patch failed, unable to continue (try -v)\n"))
496 return (False, files, False)
509 return (False, files, False)
497
510
498 return (True, files, fuzz)
511 return (True, files, fuzz)
499
512
500 def apply(self, repo, series, list=False, update_status=True,
513 def apply(self, repo, series, list=False, update_status=True,
501 strict=False, patchdir=None, merge=None, all_files={}):
514 strict=False, patchdir=None, merge=None, all_files={}):
502 wlock = lock = tr = None
515 wlock = lock = tr = None
503 try:
516 try:
504 wlock = repo.wlock()
517 wlock = repo.wlock()
505 lock = repo.lock()
518 lock = repo.lock()
506 tr = repo.transaction()
519 tr = repo.transaction()
507 try:
520 try:
508 ret = self._apply(repo, series, list, update_status,
521 ret = self._apply(repo, series, list, update_status,
509 strict, patchdir, merge, all_files=all_files)
522 strict, patchdir, merge, all_files=all_files)
510 tr.close()
523 tr.close()
511 self.save_dirty()
524 self.save_dirty()
512 return ret
525 return ret
513 except:
526 except:
514 try:
527 try:
515 tr.abort()
528 tr.abort()
516 finally:
529 finally:
517 repo.invalidate()
530 repo.invalidate()
518 repo.dirstate.invalidate()
531 repo.dirstate.invalidate()
519 raise
532 raise
520 finally:
533 finally:
521 del tr
534 del tr
522 release(lock, wlock)
535 release(lock, wlock)
523 self.removeundo(repo)
536 self.removeundo(repo)
524
537
525 def _apply(self, repo, series, list=False, update_status=True,
538 def _apply(self, repo, series, list=False, update_status=True,
526 strict=False, patchdir=None, merge=None, all_files={}):
539 strict=False, patchdir=None, merge=None, all_files={}):
527 # TODO unify with commands.py
540 # TODO unify with commands.py
528 if not patchdir:
541 if not patchdir:
529 patchdir = self.path
542 patchdir = self.path
530 err = 0
543 err = 0
531 n = None
544 n = None
532 for patchname in series:
545 for patchname in series:
533 pushable, reason = self.pushable(patchname)
546 pushable, reason = self.pushable(patchname)
534 if not pushable:
547 if not pushable:
535 self.explain_pushable(patchname, all_patches=True)
548 self.explain_pushable(patchname, all_patches=True)
536 continue
549 continue
537 self.ui.warn(_("applying %s\n") % patchname)
550 self.ui.warn(_("applying %s\n") % patchname)
538 pf = os.path.join(patchdir, patchname)
551 pf = os.path.join(patchdir, patchname)
539
552
540 try:
553 try:
541 ph = self.readheaders(patchname)
554 ph = self.readheaders(patchname)
542 except:
555 except:
543 self.ui.warn(_("Unable to read %s\n") % patchname)
556 self.ui.warn(_("Unable to read %s\n") % patchname)
544 err = 1
557 err = 1
545 break
558 break
546
559
547 message = ph.message
560 message = ph.message
548 if not message:
561 if not message:
549 message = _("imported patch %s\n") % patchname
562 message = _("imported patch %s\n") % patchname
550 else:
563 else:
551 if list:
564 if list:
552 message.append(_("\nimported patch %s") % patchname)
565 message.append(_("\nimported patch %s") % patchname)
553 message = '\n'.join(message)
566 message = '\n'.join(message)
554
567
555 if ph.haspatch:
568 if ph.haspatch:
556 (patcherr, files, fuzz) = self.patch(repo, pf)
569 (patcherr, files, fuzz) = self.patch(repo, pf)
557 all_files.update(files)
570 all_files.update(files)
558 patcherr = not patcherr
571 patcherr = not patcherr
559 else:
572 else:
560 self.ui.warn(_("patch %s is empty\n") % patchname)
573 self.ui.warn(_("patch %s is empty\n") % patchname)
561 patcherr, files, fuzz = 0, [], 0
574 patcherr, files, fuzz = 0, [], 0
562
575
563 if merge and files:
576 if merge and files:
564 # Mark as removed/merged and update dirstate parent info
577 # Mark as removed/merged and update dirstate parent info
565 removed = []
578 removed = []
566 merged = []
579 merged = []
567 for f in files:
580 for f in files:
568 if os.path.exists(repo.wjoin(f)):
581 if os.path.exists(repo.wjoin(f)):
569 merged.append(f)
582 merged.append(f)
570 else:
583 else:
571 removed.append(f)
584 removed.append(f)
572 for f in removed:
585 for f in removed:
573 repo.dirstate.remove(f)
586 repo.dirstate.remove(f)
574 for f in merged:
587 for f in merged:
575 repo.dirstate.merge(f)
588 repo.dirstate.merge(f)
576 p1, p2 = repo.dirstate.parents()
589 p1, p2 = repo.dirstate.parents()
577 repo.dirstate.setparents(p1, merge)
590 repo.dirstate.setparents(p1, merge)
578
591
579 files = patch.updatedir(self.ui, repo, files)
592 files = patch.updatedir(self.ui, repo, files)
580 match = cmdutil.matchfiles(repo, files or [])
593 match = cmdutil.matchfiles(repo, files or [])
581 n = repo.commit(files, message, ph.user, ph.date, match=match,
594 n = repo.commit(files, message, ph.user, ph.date, match=match,
582 force=True)
595 force=True)
583
596
584 if n == None:
597 if n == None:
585 raise util.Abort(_("repo commit failed"))
598 raise util.Abort(_("repo commit failed"))
586
599
587 if update_status:
600 if update_status:
588 self.applied.append(statusentry(hex(n), patchname))
601 self.applied.append(statusentry(hex(n), patchname))
589
602
590 if patcherr:
603 if patcherr:
591 self.ui.warn(_("patch failed, rejects left in working dir\n"))
604 self.ui.warn(_("patch failed, rejects left in working dir\n"))
592 err = 1
605 err = 1
593 break
606 break
594
607
595 if fuzz and strict:
608 if fuzz and strict:
596 self.ui.warn(_("fuzz found when applying patch, stopping\n"))
609 self.ui.warn(_("fuzz found when applying patch, stopping\n"))
597 err = 1
610 err = 1
598 break
611 break
599 return (err, n)
612 return (err, n)
600
613
601 def _clean_series(self, patches):
614 def _clean_series(self, patches):
602 for i in sorted([self.find_series(p) for p in patches], reverse=True):
615 for i in sorted([self.find_series(p) for p in patches], reverse=True):
603 del self.full_series[i]
616 del self.full_series[i]
604 self.parse_series()
617 self.parse_series()
605 self.series_dirty = 1
618 self.series_dirty = 1
606
619
607 def finish(self, repo, revs):
620 def finish(self, repo, revs):
608 firstrev = repo[self.applied[0].rev].rev()
621 firstrev = repo[self.applied[0].rev].rev()
609 appliedbase = 0
622 appliedbase = 0
610 patches = []
623 patches = []
611 for rev in sorted(revs):
624 for rev in sorted(revs):
612 if rev < firstrev:
625 if rev < firstrev:
613 raise util.Abort(_('revision %d is not managed') % rev)
626 raise util.Abort(_('revision %d is not managed') % rev)
614 base = bin(self.applied[appliedbase].rev)
627 base = bin(self.applied[appliedbase].rev)
615 node = repo.changelog.node(rev)
628 node = repo.changelog.node(rev)
616 if node != base:
629 if node != base:
617 raise util.Abort(_('cannot delete revision %d above '
630 raise util.Abort(_('cannot delete revision %d above '
618 'applied patches') % rev)
631 'applied patches') % rev)
619 patches.append(self.applied[appliedbase].name)
632 patches.append(self.applied[appliedbase].name)
620 appliedbase += 1
633 appliedbase += 1
621
634
622 r = self.qrepo()
635 r = self.qrepo()
623 if r:
636 if r:
624 r.remove(patches, True)
637 r.remove(patches, True)
625 else:
638 else:
626 for p in patches:
639 for p in patches:
627 os.unlink(self.join(p))
640 os.unlink(self.join(p))
628
641
629 del self.applied[:appliedbase]
642 del self.applied[:appliedbase]
630 self.applied_dirty = 1
643 self.applied_dirty = 1
631 self._clean_series(patches)
644 self._clean_series(patches)
632
645
633 def delete(self, repo, patches, opts):
646 def delete(self, repo, patches, opts):
634 if not patches and not opts.get('rev'):
647 if not patches and not opts.get('rev'):
635 raise util.Abort(_('qdelete requires at least one revision or '
648 raise util.Abort(_('qdelete requires at least one revision or '
636 'patch name'))
649 'patch name'))
637
650
638 realpatches = []
651 realpatches = []
639 for patch in patches:
652 for patch in patches:
640 patch = self.lookup(patch, strict=True)
653 patch = self.lookup(patch, strict=True)
641 info = self.isapplied(patch)
654 info = self.isapplied(patch)
642 if info:
655 if info:
643 raise util.Abort(_("cannot delete applied patch %s") % patch)
656 raise util.Abort(_("cannot delete applied patch %s") % patch)
644 if patch not in self.series:
657 if patch not in self.series:
645 raise util.Abort(_("patch %s not in series file") % patch)
658 raise util.Abort(_("patch %s not in series file") % patch)
646 realpatches.append(patch)
659 realpatches.append(patch)
647
660
648 appliedbase = 0
661 appliedbase = 0
649 if opts.get('rev'):
662 if opts.get('rev'):
650 if not self.applied:
663 if not self.applied:
651 raise util.Abort(_('no patches applied'))
664 raise util.Abort(_('no patches applied'))
652 revs = cmdutil.revrange(repo, opts['rev'])
665 revs = cmdutil.revrange(repo, opts['rev'])
653 if len(revs) > 1 and revs[0] > revs[1]:
666 if len(revs) > 1 and revs[0] > revs[1]:
654 revs.reverse()
667 revs.reverse()
655 for rev in revs:
668 for rev in revs:
656 if appliedbase >= len(self.applied):
669 if appliedbase >= len(self.applied):
657 raise util.Abort(_("revision %d is not managed") % rev)
670 raise util.Abort(_("revision %d is not managed") % rev)
658
671
659 base = bin(self.applied[appliedbase].rev)
672 base = bin(self.applied[appliedbase].rev)
660 node = repo.changelog.node(rev)
673 node = repo.changelog.node(rev)
661 if node != base:
674 if node != base:
662 raise util.Abort(_("cannot delete revision %d above "
675 raise util.Abort(_("cannot delete revision %d above "
663 "applied patches") % rev)
676 "applied patches") % rev)
664 realpatches.append(self.applied[appliedbase].name)
677 realpatches.append(self.applied[appliedbase].name)
665 appliedbase += 1
678 appliedbase += 1
666
679
667 if not opts.get('keep'):
680 if not opts.get('keep'):
668 r = self.qrepo()
681 r = self.qrepo()
669 if r:
682 if r:
670 r.remove(realpatches, True)
683 r.remove(realpatches, True)
671 else:
684 else:
672 for p in realpatches:
685 for p in realpatches:
673 os.unlink(self.join(p))
686 os.unlink(self.join(p))
674
687
675 if appliedbase:
688 if appliedbase:
676 del self.applied[:appliedbase]
689 del self.applied[:appliedbase]
677 self.applied_dirty = 1
690 self.applied_dirty = 1
678 self._clean_series(realpatches)
691 self._clean_series(realpatches)
679
692
680 def check_toppatch(self, repo):
693 def check_toppatch(self, repo):
681 if len(self.applied) > 0:
694 if len(self.applied) > 0:
682 top = bin(self.applied[-1].rev)
695 top = bin(self.applied[-1].rev)
683 pp = repo.dirstate.parents()
696 pp = repo.dirstate.parents()
684 if top not in pp:
697 if top not in pp:
685 raise util.Abort(_("working directory revision is not qtip"))
698 raise util.Abort(_("working directory revision is not qtip"))
686 return top
699 return top
687 return None
700 return None
688 def check_localchanges(self, repo, force=False, refresh=True):
701 def check_localchanges(self, repo, force=False, refresh=True):
689 m, a, r, d = repo.status()[:4]
702 m, a, r, d = repo.status()[:4]
690 if m or a or r or d:
703 if m or a or r or d:
691 if not force:
704 if not force:
692 if refresh:
705 if refresh:
693 raise util.Abort(_("local changes found, refresh first"))
706 raise util.Abort(_("local changes found, refresh first"))
694 else:
707 else:
695 raise util.Abort(_("local changes found"))
708 raise util.Abort(_("local changes found"))
696 return m, a, r, d
709 return m, a, r, d
697
710
698 _reserved = ('series', 'status', 'guards')
711 _reserved = ('series', 'status', 'guards')
699 def check_reserved_name(self, name):
712 def check_reserved_name(self, name):
700 if (name in self._reserved or name.startswith('.hg')
713 if (name in self._reserved or name.startswith('.hg')
701 or name.startswith('.mq')):
714 or name.startswith('.mq')):
702 raise util.Abort(_('"%s" cannot be used as the name of a patch')
715 raise util.Abort(_('"%s" cannot be used as the name of a patch')
703 % name)
716 % name)
704
717
705 def new(self, repo, patchfn, *pats, **opts):
718 def new(self, repo, patchfn, *pats, **opts):
706 """options:
719 """options:
707 msg: a string or a no-argument function returning a string
720 msg: a string or a no-argument function returning a string
708 """
721 """
709 msg = opts.get('msg')
722 msg = opts.get('msg')
710 force = opts.get('force')
723 force = opts.get('force')
711 user = opts.get('user')
724 user = opts.get('user')
712 date = opts.get('date')
725 date = opts.get('date')
713 if date:
726 if date:
714 date = util.parsedate(date)
727 date = util.parsedate(date)
715 self.check_reserved_name(patchfn)
728 self.check_reserved_name(patchfn)
716 if os.path.exists(self.join(patchfn)):
729 if os.path.exists(self.join(patchfn)):
717 raise util.Abort(_('patch "%s" already exists') % patchfn)
730 raise util.Abort(_('patch "%s" already exists') % patchfn)
718 if opts.get('include') or opts.get('exclude') or pats:
731 if opts.get('include') or opts.get('exclude') or pats:
719 match = cmdutil.match(repo, pats, opts)
732 match = cmdutil.match(repo, pats, opts)
720 # detect missing files in pats
733 # detect missing files in pats
721 def badfn(f, msg):
734 def badfn(f, msg):
722 raise util.Abort('%s: %s' % (f, msg))
735 raise util.Abort('%s: %s' % (f, msg))
723 match.bad = badfn
736 match.bad = badfn
724 m, a, r, d = repo.status(match=match)[:4]
737 m, a, r, d = repo.status(match=match)[:4]
725 else:
738 else:
726 m, a, r, d = self.check_localchanges(repo, force)
739 m, a, r, d = self.check_localchanges(repo, force)
727 match = cmdutil.matchfiles(repo, m + a + r)
740 match = cmdutil.matchfiles(repo, m + a + r)
728 commitfiles = m + a + r
741 commitfiles = m + a + r
729 self.check_toppatch(repo)
742 self.check_toppatch(repo)
730 insert = self.full_series_end()
743 insert = self.full_series_end()
731 wlock = repo.wlock()
744 wlock = repo.wlock()
732 try:
745 try:
733 # if patch file write fails, abort early
746 # if patch file write fails, abort early
734 p = self.opener(patchfn, "w")
747 p = self.opener(patchfn, "w")
735 try:
748 try:
736 if date:
749 if date:
737 p.write("# HG changeset patch\n")
750 p.write("# HG changeset patch\n")
738 if user:
751 if user:
739 p.write("# User " + user + "\n")
752 p.write("# User " + user + "\n")
740 p.write("# Date %d %d\n\n" % date)
753 p.write("# Date %d %d\n\n" % date)
741 elif user:
754 elif user:
742 p.write("From: " + user + "\n\n")
755 p.write("From: " + user + "\n\n")
743
756
744 if hasattr(msg, '__call__'):
757 if hasattr(msg, '__call__'):
745 msg = msg()
758 msg = msg()
746 commitmsg = msg and msg or ("[mq]: %s" % patchfn)
759 commitmsg = msg and msg or ("[mq]: %s" % patchfn)
747 n = repo.commit(commitfiles, commitmsg, user, date, match=match, force=True)
760 n = repo.commit(commitfiles, commitmsg, user, date, match=match, force=True)
748 if n == None:
761 if n == None:
749 raise util.Abort(_("repo commit failed"))
762 raise util.Abort(_("repo commit failed"))
750 try:
763 try:
751 self.full_series[insert:insert] = [patchfn]
764 self.full_series[insert:insert] = [patchfn]
752 self.applied.append(statusentry(hex(n), patchfn))
765 self.applied.append(statusentry(hex(n), patchfn))
753 self.parse_series()
766 self.parse_series()
754 self.series_dirty = 1
767 self.series_dirty = 1
755 self.applied_dirty = 1
768 self.applied_dirty = 1
756 if msg:
769 if msg:
757 msg = msg + "\n\n"
770 msg = msg + "\n\n"
758 p.write(msg)
771 p.write(msg)
759 if commitfiles:
772 if commitfiles:
760 diffopts = self.diffopts()
773 diffopts = self.diffopts()
761 if opts.get('git'): diffopts.git = True
774 if opts.get('git'): diffopts.git = True
762 parent = self.qparents(repo, n)
775 parent = self.qparents(repo, n)
763 chunks = patch.diff(repo, node1=parent, node2=n,
776 chunks = patch.diff(repo, node1=parent, node2=n,
764 match=match, opts=diffopts)
777 match=match, opts=diffopts)
765 for chunk in chunks:
778 for chunk in chunks:
766 p.write(chunk)
779 p.write(chunk)
767 p.close()
780 p.close()
768 wlock.release()
781 wlock.release()
769 wlock = None
782 wlock = None
770 r = self.qrepo()
783 r = self.qrepo()
771 if r: r.add([patchfn])
784 if r: r.add([patchfn])
772 except:
785 except:
773 repo.rollback()
786 repo.rollback()
774 raise
787 raise
775 except Exception:
788 except Exception:
776 patchpath = self.join(patchfn)
789 patchpath = self.join(patchfn)
777 try:
790 try:
778 os.unlink(patchpath)
791 os.unlink(patchpath)
779 except:
792 except:
780 self.ui.warn(_('error unlinking %s\n') % patchpath)
793 self.ui.warn(_('error unlinking %s\n') % patchpath)
781 raise
794 raise
782 self.removeundo(repo)
795 self.removeundo(repo)
783 finally:
796 finally:
784 release(wlock)
797 release(wlock)
785
798
786 def strip(self, repo, rev, update=True, backup="all", force=None):
799 def strip(self, repo, rev, update=True, backup="all", force=None):
787 wlock = lock = None
800 wlock = lock = None
788 try:
801 try:
789 wlock = repo.wlock()
802 wlock = repo.wlock()
790 lock = repo.lock()
803 lock = repo.lock()
791
804
792 if update:
805 if update:
793 self.check_localchanges(repo, force=force, refresh=False)
806 self.check_localchanges(repo, force=force, refresh=False)
794 urev = self.qparents(repo, rev)
807 urev = self.qparents(repo, rev)
795 hg.clean(repo, urev)
808 hg.clean(repo, urev)
796 repo.dirstate.write()
809 repo.dirstate.write()
797
810
798 self.removeundo(repo)
811 self.removeundo(repo)
799 repair.strip(self.ui, repo, rev, backup)
812 repair.strip(self.ui, repo, rev, backup)
800 # strip may have unbundled a set of backed up revisions after
813 # strip may have unbundled a set of backed up revisions after
801 # the actual strip
814 # the actual strip
802 self.removeundo(repo)
815 self.removeundo(repo)
803 finally:
816 finally:
804 release(lock, wlock)
817 release(lock, wlock)
805
818
806 def isapplied(self, patch):
819 def isapplied(self, patch):
807 """returns (index, rev, patch)"""
820 """returns (index, rev, patch)"""
808 for i in xrange(len(self.applied)):
821 for i in xrange(len(self.applied)):
809 a = self.applied[i]
822 a = self.applied[i]
810 if a.name == patch:
823 if a.name == patch:
811 return (i, a.rev, a.name)
824 return (i, a.rev, a.name)
812 return None
825 return None
813
826
814 # if the exact patch name does not exist, we try a few
827 # if the exact patch name does not exist, we try a few
815 # variations. If strict is passed, we try only #1
828 # variations. If strict is passed, we try only #1
816 #
829 #
817 # 1) a number to indicate an offset in the series file
830 # 1) a number to indicate an offset in the series file
818 # 2) a unique substring of the patch name was given
831 # 2) a unique substring of the patch name was given
819 # 3) patchname[-+]num to indicate an offset in the series file
832 # 3) patchname[-+]num to indicate an offset in the series file
820 def lookup(self, patch, strict=False):
833 def lookup(self, patch, strict=False):
821 patch = patch and str(patch)
834 patch = patch and str(patch)
822
835
823 def partial_name(s):
836 def partial_name(s):
824 if s in self.series:
837 if s in self.series:
825 return s
838 return s
826 matches = [x for x in self.series if s in x]
839 matches = [x for x in self.series if s in x]
827 if len(matches) > 1:
840 if len(matches) > 1:
828 self.ui.warn(_('patch name "%s" is ambiguous:\n') % s)
841 self.ui.warn(_('patch name "%s" is ambiguous:\n') % s)
829 for m in matches:
842 for m in matches:
830 self.ui.warn(' %s\n' % m)
843 self.ui.warn(' %s\n' % m)
831 return None
844 return None
832 if matches:
845 if matches:
833 return matches[0]
846 return matches[0]
834 if len(self.series) > 0 and len(self.applied) > 0:
847 if len(self.series) > 0 and len(self.applied) > 0:
835 if s == 'qtip':
848 if s == 'qtip':
836 return self.series[self.series_end(True)-1]
849 return self.series[self.series_end(True)-1]
837 if s == 'qbase':
850 if s == 'qbase':
838 return self.series[0]
851 return self.series[0]
839 return None
852 return None
840
853
841 if patch == None:
854 if patch == None:
842 return None
855 return None
843 if patch in self.series:
856 if patch in self.series:
844 return patch
857 return patch
845
858
846 if not os.path.isfile(self.join(patch)):
859 if not os.path.isfile(self.join(patch)):
847 try:
860 try:
848 sno = int(patch)
861 sno = int(patch)
849 except(ValueError, OverflowError):
862 except(ValueError, OverflowError):
850 pass
863 pass
851 else:
864 else:
852 if -len(self.series) <= sno < len(self.series):
865 if -len(self.series) <= sno < len(self.series):
853 return self.series[sno]
866 return self.series[sno]
854
867
855 if not strict:
868 if not strict:
856 res = partial_name(patch)
869 res = partial_name(patch)
857 if res:
870 if res:
858 return res
871 return res
859 minus = patch.rfind('-')
872 minus = patch.rfind('-')
860 if minus >= 0:
873 if minus >= 0:
861 res = partial_name(patch[:minus])
874 res = partial_name(patch[:minus])
862 if res:
875 if res:
863 i = self.series.index(res)
876 i = self.series.index(res)
864 try:
877 try:
865 off = int(patch[minus+1:] or 1)
878 off = int(patch[minus+1:] or 1)
866 except(ValueError, OverflowError):
879 except(ValueError, OverflowError):
867 pass
880 pass
868 else:
881 else:
869 if i - off >= 0:
882 if i - off >= 0:
870 return self.series[i - off]
883 return self.series[i - off]
871 plus = patch.rfind('+')
884 plus = patch.rfind('+')
872 if plus >= 0:
885 if plus >= 0:
873 res = partial_name(patch[:plus])
886 res = partial_name(patch[:plus])
874 if res:
887 if res:
875 i = self.series.index(res)
888 i = self.series.index(res)
876 try:
889 try:
877 off = int(patch[plus+1:] or 1)
890 off = int(patch[plus+1:] or 1)
878 except(ValueError, OverflowError):
891 except(ValueError, OverflowError):
879 pass
892 pass
880 else:
893 else:
881 if i + off < len(self.series):
894 if i + off < len(self.series):
882 return self.series[i + off]
895 return self.series[i + off]
883 raise util.Abort(_("patch %s not in series") % patch)
896 raise util.Abort(_("patch %s not in series") % patch)
884
897
885 def push(self, repo, patch=None, force=False, list=False,
898 def push(self, repo, patch=None, force=False, list=False,
886 mergeq=None, all=False):
899 mergeq=None, all=False):
887 wlock = repo.wlock()
900 wlock = repo.wlock()
888 if repo.dirstate.parents()[0] not in repo.heads():
901 if repo.dirstate.parents()[0] not in repo.heads():
889 self.ui.status(_("(working directory not at a head)\n"))
902 self.ui.status(_("(working directory not at a head)\n"))
890
903
891 if not self.series:
904 if not self.series:
892 self.ui.warn(_('no patches in series\n'))
905 self.ui.warn(_('no patches in series\n'))
893 return 0
906 return 0
894
907
895 try:
908 try:
896 patch = self.lookup(patch)
909 patch = self.lookup(patch)
897 # Suppose our series file is: A B C and the current 'top'
910 # Suppose our series file is: A B C and the current 'top'
898 # patch is B. qpush C should be performed (moving forward)
911 # patch is B. qpush C should be performed (moving forward)
899 # qpush B is a NOP (no change) qpush A is an error (can't
912 # qpush B is a NOP (no change) qpush A is an error (can't
900 # go backwards with qpush)
913 # go backwards with qpush)
901 if patch:
914 if patch:
902 info = self.isapplied(patch)
915 info = self.isapplied(patch)
903 if info:
916 if info:
904 if info[0] < len(self.applied) - 1:
917 if info[0] < len(self.applied) - 1:
905 raise util.Abort(
918 raise util.Abort(
906 _("cannot push to a previous patch: %s") % patch)
919 _("cannot push to a previous patch: %s") % patch)
907 self.ui.warn(
920 self.ui.warn(
908 _('qpush: %s is already at the top\n') % patch)
921 _('qpush: %s is already at the top\n') % patch)
909 return
922 return
910 pushable, reason = self.pushable(patch)
923 pushable, reason = self.pushable(patch)
911 if not pushable:
924 if not pushable:
912 if reason:
925 if reason:
913 reason = _('guarded by %r') % reason
926 reason = _('guarded by %r') % reason
914 else:
927 else:
915 reason = _('no matching guards')
928 reason = _('no matching guards')
916 self.ui.warn(_("cannot push '%s' - %s\n") % (patch, reason))
929 self.ui.warn(_("cannot push '%s' - %s\n") % (patch, reason))
917 return 1
930 return 1
918 elif all:
931 elif all:
919 patch = self.series[-1]
932 patch = self.series[-1]
920 if self.isapplied(patch):
933 if self.isapplied(patch):
921 self.ui.warn(_('all patches are currently applied\n'))
934 self.ui.warn(_('all patches are currently applied\n'))
922 return 0
935 return 0
923
936
924 # Following the above example, starting at 'top' of B:
937 # Following the above example, starting at 'top' of B:
925 # qpush should be performed (pushes C), but a subsequent
938 # qpush should be performed (pushes C), but a subsequent
926 # qpush without an argument is an error (nothing to
939 # qpush without an argument is an error (nothing to
927 # apply). This allows a loop of "...while hg qpush..." to
940 # apply). This allows a loop of "...while hg qpush..." to
928 # work as it detects an error when done
941 # work as it detects an error when done
929 start = self.series_end()
942 start = self.series_end()
930 if start == len(self.series):
943 if start == len(self.series):
931 self.ui.warn(_('patch series already fully applied\n'))
944 self.ui.warn(_('patch series already fully applied\n'))
932 return 1
945 return 1
933 if not force:
946 if not force:
934 self.check_localchanges(repo)
947 self.check_localchanges(repo)
935
948
936 self.applied_dirty = 1
949 self.applied_dirty = 1
937 if start > 0:
950 if start > 0:
938 self.check_toppatch(repo)
951 self.check_toppatch(repo)
939 if not patch:
952 if not patch:
940 patch = self.series[start]
953 patch = self.series[start]
941 end = start + 1
954 end = start + 1
942 else:
955 else:
943 end = self.series.index(patch, start) + 1
956 end = self.series.index(patch, start) + 1
944 s = self.series[start:end]
957 s = self.series[start:end]
945 all_files = {}
958 all_files = {}
946 try:
959 try:
947 if mergeq:
960 if mergeq:
948 ret = self.mergepatch(repo, mergeq, s)
961 ret = self.mergepatch(repo, mergeq, s)
949 else:
962 else:
950 ret = self.apply(repo, s, list, all_files=all_files)
963 ret = self.apply(repo, s, list, all_files=all_files)
951 except:
964 except:
952 self.ui.warn(_('cleaning up working directory...'))
965 self.ui.warn(_('cleaning up working directory...'))
953 node = repo.dirstate.parents()[0]
966 node = repo.dirstate.parents()[0]
954 hg.revert(repo, node, None)
967 hg.revert(repo, node, None)
955 unknown = repo.status(unknown=True)[4]
968 unknown = repo.status(unknown=True)[4]
956 # only remove unknown files that we know we touched or
969 # only remove unknown files that we know we touched or
957 # created while patching
970 # created while patching
958 for f in unknown:
971 for f in unknown:
959 if f in all_files:
972 if f in all_files:
960 util.unlink(repo.wjoin(f))
973 util.unlink(repo.wjoin(f))
961 self.ui.warn(_('done\n'))
974 self.ui.warn(_('done\n'))
962 raise
975 raise
963 top = self.applied[-1].name
976 top = self.applied[-1].name
964 if ret[0]:
977 if ret[0]:
965 self.ui.write(_("errors during apply, please fix and "
978 self.ui.write(_("errors during apply, please fix and "
966 "refresh %s\n") % top)
979 "refresh %s\n") % top)
967 else:
980 else:
968 self.ui.write(_("now at: %s\n") % top)
981 self.ui.write(_("now at: %s\n") % top)
969 return ret[0]
982 return ret[0]
970 finally:
983 finally:
971 wlock.release()
984 wlock.release()
972
985
973 def pop(self, repo, patch=None, force=False, update=True, all=False):
986 def pop(self, repo, patch=None, force=False, update=True, all=False):
974 def getfile(f, rev, flags):
987 def getfile(f, rev, flags):
975 t = repo.file(f).read(rev)
988 t = repo.file(f).read(rev)
976 repo.wwrite(f, t, flags)
989 repo.wwrite(f, t, flags)
977
990
978 wlock = repo.wlock()
991 wlock = repo.wlock()
979 try:
992 try:
980 if patch:
993 if patch:
981 # index, rev, patch
994 # index, rev, patch
982 info = self.isapplied(patch)
995 info = self.isapplied(patch)
983 if not info:
996 if not info:
984 patch = self.lookup(patch)
997 patch = self.lookup(patch)
985 info = self.isapplied(patch)
998 info = self.isapplied(patch)
986 if not info:
999 if not info:
987 raise util.Abort(_("patch %s is not applied") % patch)
1000 raise util.Abort(_("patch %s is not applied") % patch)
988
1001
989 if len(self.applied) == 0:
1002 if len(self.applied) == 0:
990 # Allow qpop -a to work repeatedly,
1003 # Allow qpop -a to work repeatedly,
991 # but not qpop without an argument
1004 # but not qpop without an argument
992 self.ui.warn(_("no patches applied\n"))
1005 self.ui.warn(_("no patches applied\n"))
993 return not all
1006 return not all
994
1007
995 if all:
1008 if all:
996 start = 0
1009 start = 0
997 elif patch:
1010 elif patch:
998 start = info[0] + 1
1011 start = info[0] + 1
999 else:
1012 else:
1000 start = len(self.applied) - 1
1013 start = len(self.applied) - 1
1001
1014
1002 if start >= len(self.applied):
1015 if start >= len(self.applied):
1003 self.ui.warn(_("qpop: %s is already at the top\n") % patch)
1016 self.ui.warn(_("qpop: %s is already at the top\n") % patch)
1004 return
1017 return
1005
1018
1006 if not update:
1019 if not update:
1007 parents = repo.dirstate.parents()
1020 parents = repo.dirstate.parents()
1008 rr = [ bin(x.rev) for x in self.applied ]
1021 rr = [ bin(x.rev) for x in self.applied ]
1009 for p in parents:
1022 for p in parents:
1010 if p in rr:
1023 if p in rr:
1011 self.ui.warn(_("qpop: forcing dirstate update\n"))
1024 self.ui.warn(_("qpop: forcing dirstate update\n"))
1012 update = True
1025 update = True
1013 else:
1026 else:
1014 parents = [p.hex() for p in repo[None].parents()]
1027 parents = [p.hex() for p in repo[None].parents()]
1015 needupdate = False
1028 needupdate = False
1016 for entry in self.applied[start:]:
1029 for entry in self.applied[start:]:
1017 if entry.rev in parents:
1030 if entry.rev in parents:
1018 needupdate = True
1031 needupdate = True
1019 break
1032 break
1020 update = needupdate
1033 update = needupdate
1021
1034
1022 if not force and update:
1035 if not force and update:
1023 self.check_localchanges(repo)
1036 self.check_localchanges(repo)
1024
1037
1025 self.applied_dirty = 1
1038 self.applied_dirty = 1
1026 end = len(self.applied)
1039 end = len(self.applied)
1027 rev = bin(self.applied[start].rev)
1040 rev = bin(self.applied[start].rev)
1028 if update:
1041 if update:
1029 top = self.check_toppatch(repo)
1042 top = self.check_toppatch(repo)
1030
1043
1031 try:
1044 try:
1032 heads = repo.changelog.heads(rev)
1045 heads = repo.changelog.heads(rev)
1033 except error.LookupError:
1046 except error.LookupError:
1034 node = short(rev)
1047 node = short(rev)
1035 raise util.Abort(_('trying to pop unknown node %s') % node)
1048 raise util.Abort(_('trying to pop unknown node %s') % node)
1036
1049
1037 if heads != [bin(self.applied[-1].rev)]:
1050 if heads != [bin(self.applied[-1].rev)]:
1038 raise util.Abort(_("popping would remove a revision not "
1051 raise util.Abort(_("popping would remove a revision not "
1039 "managed by this patch queue"))
1052 "managed by this patch queue"))
1040
1053
1041 # we know there are no local changes, so we can make a simplified
1054 # we know there are no local changes, so we can make a simplified
1042 # form of hg.update.
1055 # form of hg.update.
1043 if update:
1056 if update:
1044 qp = self.qparents(repo, rev)
1057 qp = self.qparents(repo, rev)
1045 changes = repo.changelog.read(qp)
1058 changes = repo.changelog.read(qp)
1046 mmap = repo.manifest.read(changes[0])
1059 mmap = repo.manifest.read(changes[0])
1047 m, a, r, d = repo.status(qp, top)[:4]
1060 m, a, r, d = repo.status(qp, top)[:4]
1048 if d:
1061 if d:
1049 raise util.Abort(_("deletions found between repo revs"))
1062 raise util.Abort(_("deletions found between repo revs"))
1050 for f in m:
1063 for f in m:
1051 getfile(f, mmap[f], mmap.flags(f))
1064 getfile(f, mmap[f], mmap.flags(f))
1052 for f in r:
1065 for f in r:
1053 getfile(f, mmap[f], mmap.flags(f))
1066 getfile(f, mmap[f], mmap.flags(f))
1054 for f in m + r:
1067 for f in m + r:
1055 repo.dirstate.normal(f)
1068 repo.dirstate.normal(f)
1056 for f in a:
1069 for f in a:
1057 try:
1070 try:
1058 os.unlink(repo.wjoin(f))
1071 os.unlink(repo.wjoin(f))
1059 except OSError, e:
1072 except OSError, e:
1060 if e.errno != errno.ENOENT:
1073 if e.errno != errno.ENOENT:
1061 raise
1074 raise
1062 try: os.removedirs(os.path.dirname(repo.wjoin(f)))
1075 try: os.removedirs(os.path.dirname(repo.wjoin(f)))
1063 except: pass
1076 except: pass
1064 repo.dirstate.forget(f)
1077 repo.dirstate.forget(f)
1065 repo.dirstate.setparents(qp, nullid)
1078 repo.dirstate.setparents(qp, nullid)
1066 del self.applied[start:end]
1079 del self.applied[start:end]
1067 self.strip(repo, rev, update=False, backup='strip')
1080 self.strip(repo, rev, update=False, backup='strip')
1068 if len(self.applied):
1081 if len(self.applied):
1069 self.ui.write(_("now at: %s\n") % self.applied[-1].name)
1082 self.ui.write(_("now at: %s\n") % self.applied[-1].name)
1070 else:
1083 else:
1071 self.ui.write(_("patch queue now empty\n"))
1084 self.ui.write(_("patch queue now empty\n"))
1072 finally:
1085 finally:
1073 wlock.release()
1086 wlock.release()
1074
1087
1075 def diff(self, repo, pats, opts):
1088 def diff(self, repo, pats, opts):
1076 top = self.check_toppatch(repo)
1089 top = self.check_toppatch(repo)
1077 if not top:
1090 if not top:
1078 self.ui.write(_("no patches applied\n"))
1091 self.ui.write(_("no patches applied\n"))
1079 return
1092 return
1080 qp = self.qparents(repo, top)
1093 qp = self.qparents(repo, top)
1081 self._diffopts = patch.diffopts(self.ui, opts)
1094 self._diffopts = patch.diffopts(self.ui, opts)
1082 self.printdiff(repo, qp, files=pats, opts=opts)
1095 self.printdiff(repo, qp, files=pats, opts=opts)
1083
1096
1084 def refresh(self, repo, pats=None, **opts):
1097 def refresh(self, repo, pats=None, **opts):
1085 if len(self.applied) == 0:
1098 if len(self.applied) == 0:
1086 self.ui.write(_("no patches applied\n"))
1099 self.ui.write(_("no patches applied\n"))
1087 return 1
1100 return 1
1088 msg = opts.get('msg', '').rstrip()
1101 msg = opts.get('msg', '').rstrip()
1089 newuser = opts.get('user')
1102 newuser = opts.get('user')
1090 newdate = opts.get('date')
1103 newdate = opts.get('date')
1091 if newdate:
1104 if newdate:
1092 newdate = '%d %d' % util.parsedate(newdate)
1105 newdate = '%d %d' % util.parsedate(newdate)
1093 wlock = repo.wlock()
1106 wlock = repo.wlock()
1094 try:
1107 try:
1095 self.check_toppatch(repo)
1108 self.check_toppatch(repo)
1096 (top, patchfn) = (self.applied[-1].rev, self.applied[-1].name)
1109 (top, patchfn) = (self.applied[-1].rev, self.applied[-1].name)
1097 top = bin(top)
1110 top = bin(top)
1098 if repo.changelog.heads(top) != [top]:
1111 if repo.changelog.heads(top) != [top]:
1099 raise util.Abort(_("cannot refresh a revision with children"))
1112 raise util.Abort(_("cannot refresh a revision with children"))
1100 cparents = repo.changelog.parents(top)
1113 cparents = repo.changelog.parents(top)
1101 patchparent = self.qparents(repo, top)
1114 patchparent = self.qparents(repo, top)
1102 ph = self.readheaders(patchfn)
1115 ph = self.readheaders(patchfn)
1103
1116
1104 patchf = self.opener(patchfn, 'r')
1117 patchf = self.opener(patchfn, 'r')
1105
1118
1106 # if the patch was a git patch, refresh it as a git patch
1119 # if the patch was a git patch, refresh it as a git patch
1107 for line in patchf:
1120 for line in patchf:
1108 if line.startswith('diff --git'):
1121 if line.startswith('diff --git'):
1109 self.diffopts().git = True
1122 self.diffopts().git = True
1110 break
1123 break
1111
1124
1112 if msg:
1125 if msg:
1113 ph.setmessage(msg)
1126 ph.setmessage(msg)
1114 if newuser:
1127 if newuser:
1115 ph.setuser(newuser)
1128 ph.setuser(newuser)
1116 if newdate:
1129 if newdate:
1117 ph.setdate(newdate)
1130 ph.setdate(newdate)
1118
1131
1119 # only commit new patch when write is complete
1132 # only commit new patch when write is complete
1120 patchf = self.opener(patchfn, 'w', atomictemp=True)
1133 patchf = self.opener(patchfn, 'w', atomictemp=True)
1121
1134
1122 patchf.seek(0)
1135 patchf.seek(0)
1123 patchf.truncate()
1136 patchf.truncate()
1124
1137
1125 comments = str(ph)
1138 comments = str(ph)
1126 if comments:
1139 if comments:
1127 patchf.write(comments)
1140 patchf.write(comments)
1128
1141
1129 if opts.get('git'):
1142 if opts.get('git'):
1130 self.diffopts().git = True
1143 self.diffopts().git = True
1131 tip = repo.changelog.tip()
1144 tip = repo.changelog.tip()
1132 if top == tip:
1145 if top == tip:
1133 # if the top of our patch queue is also the tip, there is an
1146 # if the top of our patch queue is also the tip, there is an
1134 # optimization here. We update the dirstate in place and strip
1147 # optimization here. We update the dirstate in place and strip
1135 # off the tip commit. Then just commit the current directory
1148 # off the tip commit. Then just commit the current directory
1136 # tree. We can also send repo.commit the list of files
1149 # tree. We can also send repo.commit the list of files
1137 # changed to speed up the diff
1150 # changed to speed up the diff
1138 #
1151 #
1139 # in short mode, we only diff the files included in the
1152 # in short mode, we only diff the files included in the
1140 # patch already plus specified files
1153 # patch already plus specified files
1141 #
1154 #
1142 # this should really read:
1155 # this should really read:
1143 # mm, dd, aa, aa2 = repo.status(tip, patchparent)[:4]
1156 # mm, dd, aa, aa2 = repo.status(tip, patchparent)[:4]
1144 # but we do it backwards to take advantage of manifest/chlog
1157 # but we do it backwards to take advantage of manifest/chlog
1145 # caching against the next repo.status call
1158 # caching against the next repo.status call
1146 #
1159 #
1147 mm, aa, dd, aa2 = repo.status(patchparent, tip)[:4]
1160 mm, aa, dd, aa2 = repo.status(patchparent, tip)[:4]
1148 changes = repo.changelog.read(tip)
1161 changes = repo.changelog.read(tip)
1149 man = repo.manifest.read(changes[0])
1162 man = repo.manifest.read(changes[0])
1150 aaa = aa[:]
1163 aaa = aa[:]
1151 matchfn = cmdutil.match(repo, pats, opts)
1164 matchfn = cmdutil.match(repo, pats, opts)
1152 if opts.get('short'):
1165 if opts.get('short'):
1153 # if amending a patch, we start with existing
1166 # if amending a patch, we start with existing
1154 # files plus specified files - unfiltered
1167 # files plus specified files - unfiltered
1155 match = cmdutil.matchfiles(repo, mm + aa + dd + matchfn.files())
1168 match = cmdutil.matchfiles(repo, mm + aa + dd + matchfn.files())
1156 # filter with inc/exl options
1169 # filter with inc/exl options
1157 matchfn = cmdutil.match(repo, opts=opts)
1170 matchfn = cmdutil.match(repo, opts=opts)
1158 else:
1171 else:
1159 match = cmdutil.matchall(repo)
1172 match = cmdutil.matchall(repo)
1160 m, a, r, d = repo.status(match=match)[:4]
1173 m, a, r, d = repo.status(match=match)[:4]
1161
1174
1162 # we might end up with files that were added between
1175 # we might end up with files that were added between
1163 # tip and the dirstate parent, but then changed in the
1176 # tip and the dirstate parent, but then changed in the
1164 # local dirstate. in this case, we want them to only
1177 # local dirstate. in this case, we want them to only
1165 # show up in the added section
1178 # show up in the added section
1166 for x in m:
1179 for x in m:
1167 if x not in aa:
1180 if x not in aa:
1168 mm.append(x)
1181 mm.append(x)
1169 # we might end up with files added by the local dirstate that
1182 # we might end up with files added by the local dirstate that
1170 # were deleted by the patch. In this case, they should only
1183 # were deleted by the patch. In this case, they should only
1171 # show up in the changed section.
1184 # show up in the changed section.
1172 for x in a:
1185 for x in a:
1173 if x in dd:
1186 if x in dd:
1174 del dd[dd.index(x)]
1187 del dd[dd.index(x)]
1175 mm.append(x)
1188 mm.append(x)
1176 else:
1189 else:
1177 aa.append(x)
1190 aa.append(x)
1178 # make sure any files deleted in the local dirstate
1191 # make sure any files deleted in the local dirstate
1179 # are not in the add or change column of the patch
1192 # are not in the add or change column of the patch
1180 forget = []
1193 forget = []
1181 for x in d + r:
1194 for x in d + r:
1182 if x in aa:
1195 if x in aa:
1183 del aa[aa.index(x)]
1196 del aa[aa.index(x)]
1184 forget.append(x)
1197 forget.append(x)
1185 continue
1198 continue
1186 elif x in mm:
1199 elif x in mm:
1187 del mm[mm.index(x)]
1200 del mm[mm.index(x)]
1188 dd.append(x)
1201 dd.append(x)
1189
1202
1190 m = list(set(mm))
1203 m = list(set(mm))
1191 r = list(set(dd))
1204 r = list(set(dd))
1192 a = list(set(aa))
1205 a = list(set(aa))
1193 c = [filter(matchfn, l) for l in (m, a, r)]
1206 c = [filter(matchfn, l) for l in (m, a, r)]
1194 match = cmdutil.matchfiles(repo, set(c[0] + c[1] + c[2]))
1207 match = cmdutil.matchfiles(repo, set(c[0] + c[1] + c[2]))
1195 chunks = patch.diff(repo, patchparent, match=match,
1208 chunks = patch.diff(repo, patchparent, match=match,
1196 changes=c, opts=self.diffopts())
1209 changes=c, opts=self.diffopts())
1197 for chunk in chunks:
1210 for chunk in chunks:
1198 patchf.write(chunk)
1211 patchf.write(chunk)
1199
1212
1200 try:
1213 try:
1201 if self.diffopts().git:
1214 if self.diffopts().git:
1202 copies = {}
1215 copies = {}
1203 for dst in a:
1216 for dst in a:
1204 src = repo.dirstate.copied(dst)
1217 src = repo.dirstate.copied(dst)
1205 # during qfold, the source file for copies may
1218 # during qfold, the source file for copies may
1206 # be removed. Treat this as a simple add.
1219 # be removed. Treat this as a simple add.
1207 if src is not None and src in repo.dirstate:
1220 if src is not None and src in repo.dirstate:
1208 copies.setdefault(src, []).append(dst)
1221 copies.setdefault(src, []).append(dst)
1209 repo.dirstate.add(dst)
1222 repo.dirstate.add(dst)
1210 # remember the copies between patchparent and tip
1223 # remember the copies between patchparent and tip
1211 for dst in aaa:
1224 for dst in aaa:
1212 f = repo.file(dst)
1225 f = repo.file(dst)
1213 src = f.renamed(man[dst])
1226 src = f.renamed(man[dst])
1214 if src:
1227 if src:
1215 copies.setdefault(src[0], []).extend(copies.get(dst, []))
1228 copies.setdefault(src[0], []).extend(copies.get(dst, []))
1216 if dst in a:
1229 if dst in a:
1217 copies[src[0]].append(dst)
1230 copies[src[0]].append(dst)
1218 # we can't copy a file created by the patch itself
1231 # we can't copy a file created by the patch itself
1219 if dst in copies:
1232 if dst in copies:
1220 del copies[dst]
1233 del copies[dst]
1221 for src, dsts in copies.iteritems():
1234 for src, dsts in copies.iteritems():
1222 for dst in dsts:
1235 for dst in dsts:
1223 repo.dirstate.copy(src, dst)
1236 repo.dirstate.copy(src, dst)
1224 else:
1237 else:
1225 for dst in a:
1238 for dst in a:
1226 repo.dirstate.add(dst)
1239 repo.dirstate.add(dst)
1227 # Drop useless copy information
1240 # Drop useless copy information
1228 for f in list(repo.dirstate.copies()):
1241 for f in list(repo.dirstate.copies()):
1229 repo.dirstate.copy(None, f)
1242 repo.dirstate.copy(None, f)
1230 for f in r:
1243 for f in r:
1231 repo.dirstate.remove(f)
1244 repo.dirstate.remove(f)
1232 # if the patch excludes a modified file, mark that
1245 # if the patch excludes a modified file, mark that
1233 # file with mtime=0 so status can see it.
1246 # file with mtime=0 so status can see it.
1234 mm = []
1247 mm = []
1235 for i in xrange(len(m)-1, -1, -1):
1248 for i in xrange(len(m)-1, -1, -1):
1236 if not matchfn(m[i]):
1249 if not matchfn(m[i]):
1237 mm.append(m[i])
1250 mm.append(m[i])
1238 del m[i]
1251 del m[i]
1239 for f in m:
1252 for f in m:
1240 repo.dirstate.normal(f)
1253 repo.dirstate.normal(f)
1241 for f in mm:
1254 for f in mm:
1242 repo.dirstate.normallookup(f)
1255 repo.dirstate.normallookup(f)
1243 for f in forget:
1256 for f in forget:
1244 repo.dirstate.forget(f)
1257 repo.dirstate.forget(f)
1245
1258
1246 if not msg:
1259 if not msg:
1247 if not ph.message:
1260 if not ph.message:
1248 message = "[mq]: %s\n" % patchfn
1261 message = "[mq]: %s\n" % patchfn
1249 else:
1262 else:
1250 message = "\n".join(ph.message)
1263 message = "\n".join(ph.message)
1251 else:
1264 else:
1252 message = msg
1265 message = msg
1253
1266
1254 user = ph.user or changes[1]
1267 user = ph.user or changes[1]
1255
1268
1256 # assumes strip can roll itself back if interrupted
1269 # assumes strip can roll itself back if interrupted
1257 repo.dirstate.setparents(*cparents)
1270 repo.dirstate.setparents(*cparents)
1258 self.applied.pop()
1271 self.applied.pop()
1259 self.applied_dirty = 1
1272 self.applied_dirty = 1
1260 self.strip(repo, top, update=False,
1273 self.strip(repo, top, update=False,
1261 backup='strip')
1274 backup='strip')
1262 except:
1275 except:
1263 repo.dirstate.invalidate()
1276 repo.dirstate.invalidate()
1264 raise
1277 raise
1265
1278
1266 try:
1279 try:
1267 # might be nice to attempt to roll back strip after this
1280 # might be nice to attempt to roll back strip after this
1268 patchf.rename()
1281 patchf.rename()
1269 n = repo.commit(match.files(), message, user, ph.date,
1282 n = repo.commit(match.files(), message, user, ph.date,
1270 match=match, force=1)
1283 match=match, force=1)
1271 self.applied.append(statusentry(hex(n), patchfn))
1284 self.applied.append(statusentry(hex(n), patchfn))
1272 except:
1285 except:
1273 ctx = repo[cparents[0]]
1286 ctx = repo[cparents[0]]
1274 repo.dirstate.rebuild(ctx.node(), ctx.manifest())
1287 repo.dirstate.rebuild(ctx.node(), ctx.manifest())
1275 self.save_dirty()
1288 self.save_dirty()
1276 self.ui.warn(_('refresh interrupted while patch was popped! '
1289 self.ui.warn(_('refresh interrupted while patch was popped! '
1277 '(revert --all, qpush to recover)\n'))
1290 '(revert --all, qpush to recover)\n'))
1278 raise
1291 raise
1279 else:
1292 else:
1280 self.printdiff(repo, patchparent, fp=patchf)
1293 self.printdiff(repo, patchparent, fp=patchf)
1281 patchf.rename()
1294 patchf.rename()
1282 added = repo.status()[1]
1295 added = repo.status()[1]
1283 for a in added:
1296 for a in added:
1284 f = repo.wjoin(a)
1297 f = repo.wjoin(a)
1285 try:
1298 try:
1286 os.unlink(f)
1299 os.unlink(f)
1287 except OSError, e:
1300 except OSError, e:
1288 if e.errno != errno.ENOENT:
1301 if e.errno != errno.ENOENT:
1289 raise
1302 raise
1290 try: os.removedirs(os.path.dirname(f))
1303 try: os.removedirs(os.path.dirname(f))
1291 except: pass
1304 except: pass
1292 # forget the file copies in the dirstate
1305 # forget the file copies in the dirstate
1293 # push should readd the files later on
1306 # push should readd the files later on
1294 repo.dirstate.forget(a)
1307 repo.dirstate.forget(a)
1295 self.pop(repo, force=True)
1308 self.pop(repo, force=True)
1296 self.push(repo, force=True)
1309 self.push(repo, force=True)
1297 finally:
1310 finally:
1298 wlock.release()
1311 wlock.release()
1299 self.removeundo(repo)
1312 self.removeundo(repo)
1300
1313
1301 def init(self, repo, create=False):
1314 def init(self, repo, create=False):
1302 if not create and os.path.isdir(self.path):
1315 if not create and os.path.isdir(self.path):
1303 raise util.Abort(_("patch queue directory already exists"))
1316 raise util.Abort(_("patch queue directory already exists"))
1304 try:
1317 try:
1305 os.mkdir(self.path)
1318 os.mkdir(self.path)
1306 except OSError, inst:
1319 except OSError, inst:
1307 if inst.errno != errno.EEXIST or not create:
1320 if inst.errno != errno.EEXIST or not create:
1308 raise
1321 raise
1309 if create:
1322 if create:
1310 return self.qrepo(create=True)
1323 return self.qrepo(create=True)
1311
1324
1312 def unapplied(self, repo, patch=None):
1325 def unapplied(self, repo, patch=None):
1313 if patch and patch not in self.series:
1326 if patch and patch not in self.series:
1314 raise util.Abort(_("patch %s is not in series file") % patch)
1327 raise util.Abort(_("patch %s is not in series file") % patch)
1315 if not patch:
1328 if not patch:
1316 start = self.series_end()
1329 start = self.series_end()
1317 else:
1330 else:
1318 start = self.series.index(patch) + 1
1331 start = self.series.index(patch) + 1
1319 unapplied = []
1332 unapplied = []
1320 for i in xrange(start, len(self.series)):
1333 for i in xrange(start, len(self.series)):
1321 pushable, reason = self.pushable(i)
1334 pushable, reason = self.pushable(i)
1322 if pushable:
1335 if pushable:
1323 unapplied.append((i, self.series[i]))
1336 unapplied.append((i, self.series[i]))
1324 self.explain_pushable(i)
1337 self.explain_pushable(i)
1325 return unapplied
1338 return unapplied
1326
1339
1327 def qseries(self, repo, missing=None, start=0, length=None, status=None,
1340 def qseries(self, repo, missing=None, start=0, length=None, status=None,
1328 summary=False):
1341 summary=False):
1329 def displayname(patchname):
1342 def displayname(patchname):
1330 if summary:
1343 if summary:
1331 ph = self.readheaders(patchname)
1344 ph = self.readheaders(patchname)
1332 msg = ph.message
1345 msg = ph.message
1333 msg = msg and ': ' + msg[0] or ': '
1346 msg = msg and ': ' + msg[0] or ': '
1334 else:
1347 else:
1335 msg = ''
1348 msg = ''
1336 return '%s%s' % (patchname, msg)
1349 return '%s%s' % (patchname, msg)
1337
1350
1338 applied = set([p.name for p in self.applied])
1351 applied = set([p.name for p in self.applied])
1339 if length is None:
1352 if length is None:
1340 length = len(self.series) - start
1353 length = len(self.series) - start
1341 if not missing:
1354 if not missing:
1342 for i in xrange(start, start+length):
1355 for i in xrange(start, start+length):
1343 patch = self.series[i]
1356 patch = self.series[i]
1344 if patch in applied:
1357 if patch in applied:
1345 stat = 'A'
1358 stat = 'A'
1346 elif self.pushable(i)[0]:
1359 elif self.pushable(i)[0]:
1347 stat = 'U'
1360 stat = 'U'
1348 else:
1361 else:
1349 stat = 'G'
1362 stat = 'G'
1350 pfx = ''
1363 pfx = ''
1351 if self.ui.verbose:
1364 if self.ui.verbose:
1352 pfx = '%d %s ' % (i, stat)
1365 pfx = '%d %s ' % (i, stat)
1353 elif status and status != stat:
1366 elif status and status != stat:
1354 continue
1367 continue
1355 self.ui.write('%s%s\n' % (pfx, displayname(patch)))
1368 self.ui.write('%s%s\n' % (pfx, displayname(patch)))
1356 else:
1369 else:
1357 msng_list = []
1370 msng_list = []
1358 for root, dirs, files in os.walk(self.path):
1371 for root, dirs, files in os.walk(self.path):
1359 d = root[len(self.path) + 1:]
1372 d = root[len(self.path) + 1:]
1360 for f in files:
1373 for f in files:
1361 fl = os.path.join(d, f)
1374 fl = os.path.join(d, f)
1362 if (fl not in self.series and
1375 if (fl not in self.series and
1363 fl not in (self.status_path, self.series_path,
1376 fl not in (self.status_path, self.series_path,
1364 self.guards_path)
1377 self.guards_path)
1365 and not fl.startswith('.')):
1378 and not fl.startswith('.')):
1366 msng_list.append(fl)
1379 msng_list.append(fl)
1367 for x in sorted(msng_list):
1380 for x in sorted(msng_list):
1368 pfx = self.ui.verbose and ('D ') or ''
1381 pfx = self.ui.verbose and ('D ') or ''
1369 self.ui.write("%s%s\n" % (pfx, displayname(x)))
1382 self.ui.write("%s%s\n" % (pfx, displayname(x)))
1370
1383
1371 def issaveline(self, l):
1384 def issaveline(self, l):
1372 if l.name == '.hg.patches.save.line':
1385 if l.name == '.hg.patches.save.line':
1373 return True
1386 return True
1374
1387
1375 def qrepo(self, create=False):
1388 def qrepo(self, create=False):
1376 if create or os.path.isdir(self.join(".hg")):
1389 if create or os.path.isdir(self.join(".hg")):
1377 return hg.repository(self.ui, path=self.path, create=create)
1390 return hg.repository(self.ui, path=self.path, create=create)
1378
1391
1379 def restore(self, repo, rev, delete=None, qupdate=None):
1392 def restore(self, repo, rev, delete=None, qupdate=None):
1380 c = repo.changelog.read(rev)
1393 c = repo.changelog.read(rev)
1381 desc = c[4].strip()
1394 desc = c[4].strip()
1382 lines = desc.splitlines()
1395 lines = desc.splitlines()
1383 i = 0
1396 i = 0
1384 datastart = None
1397 datastart = None
1385 series = []
1398 series = []
1386 applied = []
1399 applied = []
1387 qpp = None
1400 qpp = None
1388 for i in xrange(0, len(lines)):
1401 for i in xrange(0, len(lines)):
1389 if lines[i] == 'Patch Data:':
1402 if lines[i] == 'Patch Data:':
1390 datastart = i + 1
1403 datastart = i + 1
1391 elif lines[i].startswith('Dirstate:'):
1404 elif lines[i].startswith('Dirstate:'):
1392 l = lines[i].rstrip()
1405 l = lines[i].rstrip()
1393 l = l[10:].split(' ')
1406 l = l[10:].split(' ')
1394 qpp = [ bin(x) for x in l ]
1407 qpp = [ bin(x) for x in l ]
1395 elif datastart != None:
1408 elif datastart != None:
1396 l = lines[i].rstrip()
1409 l = lines[i].rstrip()
1397 se = statusentry(l)
1410 se = statusentry(l)
1398 file_ = se.name
1411 file_ = se.name
1399 if se.rev:
1412 if se.rev:
1400 applied.append(se)
1413 applied.append(se)
1401 else:
1414 else:
1402 series.append(file_)
1415 series.append(file_)
1403 if datastart == None:
1416 if datastart == None:
1404 self.ui.warn(_("No saved patch data found\n"))
1417 self.ui.warn(_("No saved patch data found\n"))
1405 return 1
1418 return 1
1406 self.ui.warn(_("restoring status: %s\n") % lines[0])
1419 self.ui.warn(_("restoring status: %s\n") % lines[0])
1407 self.full_series = series
1420 self.full_series = series
1408 self.applied = applied
1421 self.applied = applied
1409 self.parse_series()
1422 self.parse_series()
1410 self.series_dirty = 1
1423 self.series_dirty = 1
1411 self.applied_dirty = 1
1424 self.applied_dirty = 1
1412 heads = repo.changelog.heads()
1425 heads = repo.changelog.heads()
1413 if delete:
1426 if delete:
1414 if rev not in heads:
1427 if rev not in heads:
1415 self.ui.warn(_("save entry has children, leaving it alone\n"))
1428 self.ui.warn(_("save entry has children, leaving it alone\n"))
1416 else:
1429 else:
1417 self.ui.warn(_("removing save entry %s\n") % short(rev))
1430 self.ui.warn(_("removing save entry %s\n") % short(rev))
1418 pp = repo.dirstate.parents()
1431 pp = repo.dirstate.parents()
1419 if rev in pp:
1432 if rev in pp:
1420 update = True
1433 update = True
1421 else:
1434 else:
1422 update = False
1435 update = False
1423 self.strip(repo, rev, update=update, backup='strip')
1436 self.strip(repo, rev, update=update, backup='strip')
1424 if qpp:
1437 if qpp:
1425 self.ui.warn(_("saved queue repository parents: %s %s\n") %
1438 self.ui.warn(_("saved queue repository parents: %s %s\n") %
1426 (short(qpp[0]), short(qpp[1])))
1439 (short(qpp[0]), short(qpp[1])))
1427 if qupdate:
1440 if qupdate:
1428 self.ui.status(_("queue directory updating\n"))
1441 self.ui.status(_("queue directory updating\n"))
1429 r = self.qrepo()
1442 r = self.qrepo()
1430 if not r:
1443 if not r:
1431 self.ui.warn(_("Unable to load queue repository\n"))
1444 self.ui.warn(_("Unable to load queue repository\n"))
1432 return 1
1445 return 1
1433 hg.clean(r, qpp[0])
1446 hg.clean(r, qpp[0])
1434
1447
1435 def save(self, repo, msg=None):
1448 def save(self, repo, msg=None):
1436 if len(self.applied) == 0:
1449 if len(self.applied) == 0:
1437 self.ui.warn(_("save: no patches applied, exiting\n"))
1450 self.ui.warn(_("save: no patches applied, exiting\n"))
1438 return 1
1451 return 1
1439 if self.issaveline(self.applied[-1]):
1452 if self.issaveline(self.applied[-1]):
1440 self.ui.warn(_("status is already saved\n"))
1453 self.ui.warn(_("status is already saved\n"))
1441 return 1
1454 return 1
1442
1455
1443 ar = [ ':' + x for x in self.full_series ]
1456 ar = [ ':' + x for x in self.full_series ]
1444 if not msg:
1457 if not msg:
1445 msg = _("hg patches saved state")
1458 msg = _("hg patches saved state")
1446 else:
1459 else:
1447 msg = "hg patches: " + msg.rstrip('\r\n')
1460 msg = "hg patches: " + msg.rstrip('\r\n')
1448 r = self.qrepo()
1461 r = self.qrepo()
1449 if r:
1462 if r:
1450 pp = r.dirstate.parents()
1463 pp = r.dirstate.parents()
1451 msg += "\nDirstate: %s %s" % (hex(pp[0]), hex(pp[1]))
1464 msg += "\nDirstate: %s %s" % (hex(pp[0]), hex(pp[1]))
1452 msg += "\n\nPatch Data:\n"
1465 msg += "\n\nPatch Data:\n"
1453 text = msg + "\n".join([str(x) for x in self.applied]) + '\n' + (ar and
1466 text = msg + "\n".join([str(x) for x in self.applied]) + '\n' + (ar and
1454 "\n".join(ar) + '\n' or "")
1467 "\n".join(ar) + '\n' or "")
1455 n = repo.commit(None, text, user=None, force=1)
1468 n = repo.commit(None, text, user=None, force=1)
1456 if not n:
1469 if not n:
1457 self.ui.warn(_("repo commit failed\n"))
1470 self.ui.warn(_("repo commit failed\n"))
1458 return 1
1471 return 1
1459 self.applied.append(statusentry(hex(n),'.hg.patches.save.line'))
1472 self.applied.append(statusentry(hex(n),'.hg.patches.save.line'))
1460 self.applied_dirty = 1
1473 self.applied_dirty = 1
1461 self.removeundo(repo)
1474 self.removeundo(repo)
1462
1475
1463 def full_series_end(self):
1476 def full_series_end(self):
1464 if len(self.applied) > 0:
1477 if len(self.applied) > 0:
1465 p = self.applied[-1].name
1478 p = self.applied[-1].name
1466 end = self.find_series(p)
1479 end = self.find_series(p)
1467 if end == None:
1480 if end == None:
1468 return len(self.full_series)
1481 return len(self.full_series)
1469 return end + 1
1482 return end + 1
1470 return 0
1483 return 0
1471
1484
1472 def series_end(self, all_patches=False):
1485 def series_end(self, all_patches=False):
1473 """If all_patches is False, return the index of the next pushable patch
1486 """If all_patches is False, return the index of the next pushable patch
1474 in the series, or the series length. If all_patches is True, return the
1487 in the series, or the series length. If all_patches is True, return the
1475 index of the first patch past the last applied one.
1488 index of the first patch past the last applied one.
1476 """
1489 """
1477 end = 0
1490 end = 0
1478 def next(start):
1491 def next(start):
1479 if all_patches:
1492 if all_patches:
1480 return start
1493 return start
1481 i = start
1494 i = start
1482 while i < len(self.series):
1495 while i < len(self.series):
1483 p, reason = self.pushable(i)
1496 p, reason = self.pushable(i)
1484 if p:
1497 if p:
1485 break
1498 break
1486 self.explain_pushable(i)
1499 self.explain_pushable(i)
1487 i += 1
1500 i += 1
1488 return i
1501 return i
1489 if len(self.applied) > 0:
1502 if len(self.applied) > 0:
1490 p = self.applied[-1].name
1503 p = self.applied[-1].name
1491 try:
1504 try:
1492 end = self.series.index(p)
1505 end = self.series.index(p)
1493 except ValueError:
1506 except ValueError:
1494 return 0
1507 return 0
1495 return next(end + 1)
1508 return next(end + 1)
1496 return next(end)
1509 return next(end)
1497
1510
1498 def appliedname(self, index):
1511 def appliedname(self, index):
1499 pname = self.applied[index].name
1512 pname = self.applied[index].name
1500 if not self.ui.verbose:
1513 if not self.ui.verbose:
1501 p = pname
1514 p = pname
1502 else:
1515 else:
1503 p = str(self.series.index(pname)) + " " + pname
1516 p = str(self.series.index(pname)) + " " + pname
1504 return p
1517 return p
1505
1518
1506 def qimport(self, repo, files, patchname=None, rev=None, existing=None,
1519 def qimport(self, repo, files, patchname=None, rev=None, existing=None,
1507 force=None, git=False):
1520 force=None, git=False):
1508 def checkseries(patchname):
1521 def checkseries(patchname):
1509 if patchname in self.series:
1522 if patchname in self.series:
1510 raise util.Abort(_('patch %s is already in the series file')
1523 raise util.Abort(_('patch %s is already in the series file')
1511 % patchname)
1524 % patchname)
1512 def checkfile(patchname):
1525 def checkfile(patchname):
1513 if not force and os.path.exists(self.join(patchname)):
1526 if not force and os.path.exists(self.join(patchname)):
1514 raise util.Abort(_('patch "%s" already exists')
1527 raise util.Abort(_('patch "%s" already exists')
1515 % patchname)
1528 % patchname)
1516
1529
1517 if rev:
1530 if rev:
1518 if files:
1531 if files:
1519 raise util.Abort(_('option "-r" not valid when importing '
1532 raise util.Abort(_('option "-r" not valid when importing '
1520 'files'))
1533 'files'))
1521 rev = cmdutil.revrange(repo, rev)
1534 rev = cmdutil.revrange(repo, rev)
1522 rev.sort(lambda x, y: cmp(y, x))
1535 rev.sort(lambda x, y: cmp(y, x))
1523 if (len(files) > 1 or len(rev) > 1) and patchname:
1536 if (len(files) > 1 or len(rev) > 1) and patchname:
1524 raise util.Abort(_('option "-n" not valid when importing multiple '
1537 raise util.Abort(_('option "-n" not valid when importing multiple '
1525 'patches'))
1538 'patches'))
1526 i = 0
1539 i = 0
1527 added = []
1540 added = []
1528 if rev:
1541 if rev:
1529 # If mq patches are applied, we can only import revisions
1542 # If mq patches are applied, we can only import revisions
1530 # that form a linear path to qbase.
1543 # that form a linear path to qbase.
1531 # Otherwise, they should form a linear path to a head.
1544 # Otherwise, they should form a linear path to a head.
1532 heads = repo.changelog.heads(repo.changelog.node(rev[-1]))
1545 heads = repo.changelog.heads(repo.changelog.node(rev[-1]))
1533 if len(heads) > 1:
1546 if len(heads) > 1:
1534 raise util.Abort(_('revision %d is the root of more than one '
1547 raise util.Abort(_('revision %d is the root of more than one '
1535 'branch') % rev[-1])
1548 'branch') % rev[-1])
1536 if self.applied:
1549 if self.applied:
1537 base = hex(repo.changelog.node(rev[0]))
1550 base = hex(repo.changelog.node(rev[0]))
1538 if base in [n.rev for n in self.applied]:
1551 if base in [n.rev for n in self.applied]:
1539 raise util.Abort(_('revision %d is already managed')
1552 raise util.Abort(_('revision %d is already managed')
1540 % rev[0])
1553 % rev[0])
1541 if heads != [bin(self.applied[-1].rev)]:
1554 if heads != [bin(self.applied[-1].rev)]:
1542 raise util.Abort(_('revision %d is not the parent of '
1555 raise util.Abort(_('revision %d is not the parent of '
1543 'the queue') % rev[0])
1556 'the queue') % rev[0])
1544 base = repo.changelog.rev(bin(self.applied[0].rev))
1557 base = repo.changelog.rev(bin(self.applied[0].rev))
1545 lastparent = repo.changelog.parentrevs(base)[0]
1558 lastparent = repo.changelog.parentrevs(base)[0]
1546 else:
1559 else:
1547 if heads != [repo.changelog.node(rev[0])]:
1560 if heads != [repo.changelog.node(rev[0])]:
1548 raise util.Abort(_('revision %d has unmanaged children')
1561 raise util.Abort(_('revision %d has unmanaged children')
1549 % rev[0])
1562 % rev[0])
1550 lastparent = None
1563 lastparent = None
1551
1564
1552 if git:
1565 if git:
1553 self.diffopts().git = True
1566 self.diffopts().git = True
1554
1567
1555 for r in rev:
1568 for r in rev:
1556 p1, p2 = repo.changelog.parentrevs(r)
1569 p1, p2 = repo.changelog.parentrevs(r)
1557 n = repo.changelog.node(r)
1570 n = repo.changelog.node(r)
1558 if p2 != nullrev:
1571 if p2 != nullrev:
1559 raise util.Abort(_('cannot import merge revision %d') % r)
1572 raise util.Abort(_('cannot import merge revision %d') % r)
1560 if lastparent and lastparent != r:
1573 if lastparent and lastparent != r:
1561 raise util.Abort(_('revision %d is not the parent of %d')
1574 raise util.Abort(_('revision %d is not the parent of %d')
1562 % (r, lastparent))
1575 % (r, lastparent))
1563 lastparent = p1
1576 lastparent = p1
1564
1577
1565 if not patchname:
1578 if not patchname:
1566 patchname = normname('%d.diff' % r)
1579 patchname = normname('%d.diff' % r)
1567 self.check_reserved_name(patchname)
1580 self.check_reserved_name(patchname)
1568 checkseries(patchname)
1581 checkseries(patchname)
1569 checkfile(patchname)
1582 checkfile(patchname)
1570 self.full_series.insert(0, patchname)
1583 self.full_series.insert(0, patchname)
1571
1584
1572 patchf = self.opener(patchname, "w")
1585 patchf = self.opener(patchname, "w")
1573 patch.export(repo, [n], fp=patchf, opts=self.diffopts())
1586 patch.export(repo, [n], fp=patchf, opts=self.diffopts())
1574 patchf.close()
1587 patchf.close()
1575
1588
1576 se = statusentry(hex(n), patchname)
1589 se = statusentry(hex(n), patchname)
1577 self.applied.insert(0, se)
1590 self.applied.insert(0, se)
1578
1591
1579 added.append(patchname)
1592 added.append(patchname)
1580 patchname = None
1593 patchname = None
1581 self.parse_series()
1594 self.parse_series()
1582 self.applied_dirty = 1
1595 self.applied_dirty = 1
1583
1596
1584 for filename in files:
1597 for filename in files:
1585 if existing:
1598 if existing:
1586 if filename == '-':
1599 if filename == '-':
1587 raise util.Abort(_('-e is incompatible with import from -'))
1600 raise util.Abort(_('-e is incompatible with import from -'))
1588 if not patchname:
1601 if not patchname:
1589 patchname = normname(filename)
1602 patchname = normname(filename)
1590 self.check_reserved_name(patchname)
1603 self.check_reserved_name(patchname)
1591 if not os.path.isfile(self.join(patchname)):
1604 if not os.path.isfile(self.join(patchname)):
1592 raise util.Abort(_("patch %s does not exist") % patchname)
1605 raise util.Abort(_("patch %s does not exist") % patchname)
1593 else:
1606 else:
1594 try:
1607 try:
1595 if filename == '-':
1608 if filename == '-':
1596 if not patchname:
1609 if not patchname:
1597 raise util.Abort(_('need --name to import a patch from -'))
1610 raise util.Abort(_('need --name to import a patch from -'))
1598 text = sys.stdin.read()
1611 text = sys.stdin.read()
1599 else:
1612 else:
1600 text = url.open(self.ui, filename).read()
1613 text = url.open(self.ui, filename).read()
1601 except (OSError, IOError):
1614 except (OSError, IOError):
1602 raise util.Abort(_("unable to read %s") % filename)
1615 raise util.Abort(_("unable to read %s") % filename)
1603 if not patchname:
1616 if not patchname:
1604 patchname = normname(os.path.basename(filename))
1617 patchname = normname(os.path.basename(filename))
1605 self.check_reserved_name(patchname)
1618 self.check_reserved_name(patchname)
1606 checkfile(patchname)
1619 checkfile(patchname)
1607 patchf = self.opener(patchname, "w")
1620 patchf = self.opener(patchname, "w")
1608 patchf.write(text)
1621 patchf.write(text)
1609 if not force:
1622 if not force:
1610 checkseries(patchname)
1623 checkseries(patchname)
1611 if patchname not in self.series:
1624 if patchname not in self.series:
1612 index = self.full_series_end() + i
1625 index = self.full_series_end() + i
1613 self.full_series[index:index] = [patchname]
1626 self.full_series[index:index] = [patchname]
1614 self.parse_series()
1627 self.parse_series()
1615 self.ui.warn(_("adding %s to series file\n") % patchname)
1628 self.ui.warn(_("adding %s to series file\n") % patchname)
1616 i += 1
1629 i += 1
1617 added.append(patchname)
1630 added.append(patchname)
1618 patchname = None
1631 patchname = None
1619 self.series_dirty = 1
1632 self.series_dirty = 1
1620 qrepo = self.qrepo()
1633 qrepo = self.qrepo()
1621 if qrepo:
1634 if qrepo:
1622 qrepo.add(added)
1635 qrepo.add(added)
1623
1636
1624 def delete(ui, repo, *patches, **opts):
1637 def delete(ui, repo, *patches, **opts):
1625 """remove patches from queue
1638 """remove patches from queue
1626
1639
1627 The patches must not be applied, unless they are arguments to the
1640 The patches must not be applied, unless they are arguments to the
1628 -r/--rev parameter. At least one patch or revision is required.
1641 -r/--rev parameter. At least one patch or revision is required.
1629
1642
1630 With --rev, mq will stop managing the named revisions (converting
1643 With --rev, mq will stop managing the named revisions (converting
1631 them to regular mercurial changesets). The qfinish command should
1644 them to regular mercurial changesets). The qfinish command should
1632 be used as an alternative for qdelete -r, as the latter option is
1645 be used as an alternative for qdelete -r, as the latter option is
1633 deprecated.
1646 deprecated.
1634
1647
1635 With -k/--keep, the patch files are preserved in the patch
1648 With -k/--keep, the patch files are preserved in the patch
1636 directory."""
1649 directory."""
1637 q = repo.mq
1650 q = repo.mq
1638 q.delete(repo, patches, opts)
1651 q.delete(repo, patches, opts)
1639 q.save_dirty()
1652 q.save_dirty()
1640 return 0
1653 return 0
1641
1654
1642 def applied(ui, repo, patch=None, **opts):
1655 def applied(ui, repo, patch=None, **opts):
1643 """print the patches already applied"""
1656 """print the patches already applied"""
1644 q = repo.mq
1657 q = repo.mq
1645 if patch:
1658 if patch:
1646 if patch not in q.series:
1659 if patch not in q.series:
1647 raise util.Abort(_("patch %s is not in series file") % patch)
1660 raise util.Abort(_("patch %s is not in series file") % patch)
1648 end = q.series.index(patch) + 1
1661 end = q.series.index(patch) + 1
1649 else:
1662 else:
1650 end = q.series_end(True)
1663 end = q.series_end(True)
1651 return q.qseries(repo, length=end, status='A', summary=opts.get('summary'))
1664 return q.qseries(repo, length=end, status='A', summary=opts.get('summary'))
1652
1665
1653 def unapplied(ui, repo, patch=None, **opts):
1666 def unapplied(ui, repo, patch=None, **opts):
1654 """print the patches not yet applied"""
1667 """print the patches not yet applied"""
1655 q = repo.mq
1668 q = repo.mq
1656 if patch:
1669 if patch:
1657 if patch not in q.series:
1670 if patch not in q.series:
1658 raise util.Abort(_("patch %s is not in series file") % patch)
1671 raise util.Abort(_("patch %s is not in series file") % patch)
1659 start = q.series.index(patch) + 1
1672 start = q.series.index(patch) + 1
1660 else:
1673 else:
1661 start = q.series_end(True)
1674 start = q.series_end(True)
1662 q.qseries(repo, start=start, status='U', summary=opts.get('summary'))
1675 q.qseries(repo, start=start, status='U', summary=opts.get('summary'))
1663
1676
1664 def qimport(ui, repo, *filename, **opts):
1677 def qimport(ui, repo, *filename, **opts):
1665 """import a patch
1678 """import a patch
1666
1679
1667 The patch is inserted into the series after the last applied
1680 The patch is inserted into the series after the last applied
1668 patch. If no patches have been applied, qimport prepends the patch
1681 patch. If no patches have been applied, qimport prepends the patch
1669 to the series.
1682 to the series.
1670
1683
1671 The patch will have the same name as its source file unless you
1684 The patch will have the same name as its source file unless you
1672 give it a new one with -n/--name.
1685 give it a new one with -n/--name.
1673
1686
1674 You can register an existing patch inside the patch directory with
1687 You can register an existing patch inside the patch directory with
1675 the -e/--existing flag.
1688 the -e/--existing flag.
1676
1689
1677 With -f/--force, an existing patch of the same name will be
1690 With -f/--force, an existing patch of the same name will be
1678 overwritten.
1691 overwritten.
1679
1692
1680 An existing changeset may be placed under mq control with -r/--rev
1693 An existing changeset may be placed under mq control with -r/--rev
1681 (e.g. qimport --rev tip -n patch will place tip under mq control).
1694 (e.g. qimport --rev tip -n patch will place tip under mq control).
1682 With -g/--git, patches imported with --rev will use the git diff
1695 With -g/--git, patches imported with --rev will use the git diff
1683 format. See the diffs help topic for information on why this is
1696 format. See the diffs help topic for information on why this is
1684 important for preserving rename/copy information and permission
1697 important for preserving rename/copy information and permission
1685 changes.
1698 changes.
1686
1699
1687 To import a patch from standard input, pass - as the patch file.
1700 To import a patch from standard input, pass - as the patch file.
1688 When importing from standard input, a patch name must be specified
1701 When importing from standard input, a patch name must be specified
1689 using the --name flag.
1702 using the --name flag.
1690 """
1703 """
1691 q = repo.mq
1704 q = repo.mq
1692 q.qimport(repo, filename, patchname=opts['name'],
1705 q.qimport(repo, filename, patchname=opts['name'],
1693 existing=opts['existing'], force=opts['force'], rev=opts['rev'],
1706 existing=opts['existing'], force=opts['force'], rev=opts['rev'],
1694 git=opts['git'])
1707 git=opts['git'])
1695 q.save_dirty()
1708 q.save_dirty()
1696
1709
1697 if opts.get('push') and not opts.get('rev'):
1710 if opts.get('push') and not opts.get('rev'):
1698 return q.push(repo, None)
1711 return q.push(repo, None)
1699 return 0
1712 return 0
1700
1713
1701 def init(ui, repo, **opts):
1714 def init(ui, repo, **opts):
1702 """init a new queue repository
1715 """init a new queue repository
1703
1716
1704 The queue repository is unversioned by default. If
1717 The queue repository is unversioned by default. If
1705 -c/--create-repo is specified, qinit will create a separate nested
1718 -c/--create-repo is specified, qinit will create a separate nested
1706 repository for patches (qinit -c may also be run later to convert
1719 repository for patches (qinit -c may also be run later to convert
1707 an unversioned patch repository into a versioned one). You can use
1720 an unversioned patch repository into a versioned one). You can use
1708 qcommit to commit changes to this queue repository."""
1721 qcommit to commit changes to this queue repository."""
1709 q = repo.mq
1722 q = repo.mq
1710 r = q.init(repo, create=opts['create_repo'])
1723 r = q.init(repo, create=opts['create_repo'])
1711 q.save_dirty()
1724 q.save_dirty()
1712 if r:
1725 if r:
1713 if not os.path.exists(r.wjoin('.hgignore')):
1726 if not os.path.exists(r.wjoin('.hgignore')):
1714 fp = r.wopener('.hgignore', 'w')
1727 fp = r.wopener('.hgignore', 'w')
1715 fp.write('^\\.hg\n')
1728 fp.write('^\\.hg\n')
1716 fp.write('^\\.mq\n')
1729 fp.write('^\\.mq\n')
1717 fp.write('syntax: glob\n')
1730 fp.write('syntax: glob\n')
1718 fp.write('status\n')
1731 fp.write('status\n')
1719 fp.write('guards\n')
1732 fp.write('guards\n')
1720 fp.close()
1733 fp.close()
1721 if not os.path.exists(r.wjoin('series')):
1734 if not os.path.exists(r.wjoin('series')):
1722 r.wopener('series', 'w').close()
1735 r.wopener('series', 'w').close()
1723 r.add(['.hgignore', 'series'])
1736 r.add(['.hgignore', 'series'])
1724 commands.add(ui, r)
1737 commands.add(ui, r)
1725 return 0
1738 return 0
1726
1739
1727 def clone(ui, source, dest=None, **opts):
1740 def clone(ui, source, dest=None, **opts):
1728 '''clone main and patch repository at same time
1741 '''clone main and patch repository at same time
1729
1742
1730 If source is local, destination will have no patches applied. If
1743 If source is local, destination will have no patches applied. If
1731 source is remote, this command can not check if patches are
1744 source is remote, this command can not check if patches are
1732 applied in source, so cannot guarantee that patches are not
1745 applied in source, so cannot guarantee that patches are not
1733 applied in destination. If you clone remote repository, be sure
1746 applied in destination. If you clone remote repository, be sure
1734 before that it has no patches applied.
1747 before that it has no patches applied.
1735
1748
1736 Source patch repository is looked for in <src>/.hg/patches by
1749 Source patch repository is looked for in <src>/.hg/patches by
1737 default. Use -p <url> to change.
1750 default. Use -p <url> to change.
1738
1751
1739 The patch directory must be a nested mercurial repository, as
1752 The patch directory must be a nested mercurial repository, as
1740 would be created by qinit -c.
1753 would be created by qinit -c.
1741 '''
1754 '''
1742 def patchdir(repo):
1755 def patchdir(repo):
1743 url = repo.url()
1756 url = repo.url()
1744 if url.endswith('/'):
1757 if url.endswith('/'):
1745 url = url[:-1]
1758 url = url[:-1]
1746 return url + '/.hg/patches'
1759 return url + '/.hg/patches'
1747 if dest is None:
1760 if dest is None:
1748 dest = hg.defaultdest(source)
1761 dest = hg.defaultdest(source)
1749 sr = hg.repository(cmdutil.remoteui(ui, opts), ui.expandpath(source))
1762 sr = hg.repository(cmdutil.remoteui(ui, opts), ui.expandpath(source))
1750 if opts['patches']:
1763 if opts['patches']:
1751 patchespath = ui.expandpath(opts['patches'])
1764 patchespath = ui.expandpath(opts['patches'])
1752 else:
1765 else:
1753 patchespath = patchdir(sr)
1766 patchespath = patchdir(sr)
1754 try:
1767 try:
1755 hg.repository(ui, patchespath)
1768 hg.repository(ui, patchespath)
1756 except error.RepoError:
1769 except error.RepoError:
1757 raise util.Abort(_('versioned patch repository not found'
1770 raise util.Abort(_('versioned patch repository not found'
1758 ' (see qinit -c)'))
1771 ' (see qinit -c)'))
1759 qbase, destrev = None, None
1772 qbase, destrev = None, None
1760 if sr.local():
1773 if sr.local():
1761 if sr.mq.applied:
1774 if sr.mq.applied:
1762 qbase = bin(sr.mq.applied[0].rev)
1775 qbase = bin(sr.mq.applied[0].rev)
1763 if not hg.islocal(dest):
1776 if not hg.islocal(dest):
1764 heads = set(sr.heads())
1777 heads = set(sr.heads())
1765 destrev = list(heads.difference(sr.heads(qbase)))
1778 destrev = list(heads.difference(sr.heads(qbase)))
1766 destrev.append(sr.changelog.parents(qbase)[0])
1779 destrev.append(sr.changelog.parents(qbase)[0])
1767 elif sr.capable('lookup'):
1780 elif sr.capable('lookup'):
1768 try:
1781 try:
1769 qbase = sr.lookup('qbase')
1782 qbase = sr.lookup('qbase')
1770 except error.RepoError:
1783 except error.RepoError:
1771 pass
1784 pass
1772 ui.note(_('cloning main repository\n'))
1785 ui.note(_('cloning main repository\n'))
1773 sr, dr = hg.clone(ui, sr.url(), dest,
1786 sr, dr = hg.clone(ui, sr.url(), dest,
1774 pull=opts['pull'],
1787 pull=opts['pull'],
1775 rev=destrev,
1788 rev=destrev,
1776 update=False,
1789 update=False,
1777 stream=opts['uncompressed'])
1790 stream=opts['uncompressed'])
1778 ui.note(_('cloning patch repository\n'))
1791 ui.note(_('cloning patch repository\n'))
1779 hg.clone(ui, opts['patches'] or patchdir(sr), patchdir(dr),
1792 hg.clone(ui, opts['patches'] or patchdir(sr), patchdir(dr),
1780 pull=opts['pull'], update=not opts['noupdate'],
1793 pull=opts['pull'], update=not opts['noupdate'],
1781 stream=opts['uncompressed'])
1794 stream=opts['uncompressed'])
1782 if dr.local():
1795 if dr.local():
1783 if qbase:
1796 if qbase:
1784 ui.note(_('stripping applied patches from destination '
1797 ui.note(_('stripping applied patches from destination '
1785 'repository\n'))
1798 'repository\n'))
1786 dr.mq.strip(dr, qbase, update=False, backup=None)
1799 dr.mq.strip(dr, qbase, update=False, backup=None)
1787 if not opts['noupdate']:
1800 if not opts['noupdate']:
1788 ui.note(_('updating destination repository\n'))
1801 ui.note(_('updating destination repository\n'))
1789 hg.update(dr, dr.changelog.tip())
1802 hg.update(dr, dr.changelog.tip())
1790
1803
1791 def commit(ui, repo, *pats, **opts):
1804 def commit(ui, repo, *pats, **opts):
1792 """commit changes in the queue repository"""
1805 """commit changes in the queue repository"""
1793 q = repo.mq
1806 q = repo.mq
1794 r = q.qrepo()
1807 r = q.qrepo()
1795 if not r: raise util.Abort('no queue repository')
1808 if not r: raise util.Abort('no queue repository')
1796 commands.commit(r.ui, r, *pats, **opts)
1809 commands.commit(r.ui, r, *pats, **opts)
1797
1810
1798 def series(ui, repo, **opts):
1811 def series(ui, repo, **opts):
1799 """print the entire series file"""
1812 """print the entire series file"""
1800 repo.mq.qseries(repo, missing=opts['missing'], summary=opts['summary'])
1813 repo.mq.qseries(repo, missing=opts['missing'], summary=opts['summary'])
1801 return 0
1814 return 0
1802
1815
1803 def top(ui, repo, **opts):
1816 def top(ui, repo, **opts):
1804 """print the name of the current patch"""
1817 """print the name of the current patch"""
1805 q = repo.mq
1818 q = repo.mq
1806 t = q.applied and q.series_end(True) or 0
1819 t = q.applied and q.series_end(True) or 0
1807 if t:
1820 if t:
1808 return q.qseries(repo, start=t-1, length=1, status='A',
1821 return q.qseries(repo, start=t-1, length=1, status='A',
1809 summary=opts.get('summary'))
1822 summary=opts.get('summary'))
1810 else:
1823 else:
1811 ui.write(_("no patches applied\n"))
1824 ui.write(_("no patches applied\n"))
1812 return 1
1825 return 1
1813
1826
1814 def next(ui, repo, **opts):
1827 def next(ui, repo, **opts):
1815 """print the name of the next patch"""
1828 """print the name of the next patch"""
1816 q = repo.mq
1829 q = repo.mq
1817 end = q.series_end()
1830 end = q.series_end()
1818 if end == len(q.series):
1831 if end == len(q.series):
1819 ui.write(_("all patches applied\n"))
1832 ui.write(_("all patches applied\n"))
1820 return 1
1833 return 1
1821 return q.qseries(repo, start=end, length=1, summary=opts.get('summary'))
1834 return q.qseries(repo, start=end, length=1, summary=opts.get('summary'))
1822
1835
1823 def prev(ui, repo, **opts):
1836 def prev(ui, repo, **opts):
1824 """print the name of the previous patch"""
1837 """print the name of the previous patch"""
1825 q = repo.mq
1838 q = repo.mq
1826 l = len(q.applied)
1839 l = len(q.applied)
1827 if l == 1:
1840 if l == 1:
1828 ui.write(_("only one patch applied\n"))
1841 ui.write(_("only one patch applied\n"))
1829 return 1
1842 return 1
1830 if not l:
1843 if not l:
1831 ui.write(_("no patches applied\n"))
1844 ui.write(_("no patches applied\n"))
1832 return 1
1845 return 1
1833 return q.qseries(repo, start=l-2, length=1, status='A',
1846 return q.qseries(repo, start=l-2, length=1, status='A',
1834 summary=opts.get('summary'))
1847 summary=opts.get('summary'))
1835
1848
1836 def setupheaderopts(ui, opts):
1849 def setupheaderopts(ui, opts):
1837 def do(opt,val):
1850 def do(opt,val):
1838 if not opts[opt] and opts['current' + opt]:
1851 if not opts[opt] and opts['current' + opt]:
1839 opts[opt] = val
1852 opts[opt] = val
1840 do('user', ui.username())
1853 do('user', ui.username())
1841 do('date', "%d %d" % util.makedate())
1854 do('date', "%d %d" % util.makedate())
1842
1855
1843 def new(ui, repo, patch, *args, **opts):
1856 def new(ui, repo, patch, *args, **opts):
1844 """create a new patch
1857 """create a new patch
1845
1858
1846 qnew creates a new patch on top of the currently-applied patch (if
1859 qnew creates a new patch on top of the currently-applied patch (if
1847 any). It will refuse to run if there are any outstanding changes
1860 any). It will refuse to run if there are any outstanding changes
1848 unless -f/--force is specified, in which case the patch will be
1861 unless -f/--force is specified, in which case the patch will be
1849 initialized with them. You may also use -I/--include,
1862 initialized with them. You may also use -I/--include,
1850 -X/--exclude, and/or a list of files after the patch name to add
1863 -X/--exclude, and/or a list of files after the patch name to add
1851 only changes to matching files to the new patch, leaving the rest
1864 only changes to matching files to the new patch, leaving the rest
1852 as uncommitted modifications.
1865 as uncommitted modifications.
1853
1866
1854 -u/--user and -d/--date can be used to set the (given) user and
1867 -u/--user and -d/--date can be used to set the (given) user and
1855 date, respectively. -U/--currentuser and -D/--currentdate set user
1868 date, respectively. -U/--currentuser and -D/--currentdate set user
1856 to current user and date to current date.
1869 to current user and date to current date.
1857
1870
1858 -e/--edit, -m/--message or -l/--logfile set the patch header as
1871 -e/--edit, -m/--message or -l/--logfile set the patch header as
1859 well as the commit message. If none is specified, the header is
1872 well as the commit message. If none is specified, the header is
1860 empty and the commit message is '[mq]: PATCH'.
1873 empty and the commit message is '[mq]: PATCH'.
1861
1874
1862 Use the -g/--git option to keep the patch in the git extended diff
1875 Use the -g/--git option to keep the patch in the git extended diff
1863 format. Read the diffs help topic for more information on why this
1876 format. Read the diffs help topic for more information on why this
1864 is important for preserving permission changes and copy/rename
1877 is important for preserving permission changes and copy/rename
1865 information.
1878 information.
1866 """
1879 """
1867 msg = cmdutil.logmessage(opts)
1880 msg = cmdutil.logmessage(opts)
1868 def getmsg(): return ui.edit(msg, ui.username())
1881 def getmsg(): return ui.edit(msg, ui.username())
1869 q = repo.mq
1882 q = repo.mq
1870 opts['msg'] = msg
1883 opts['msg'] = msg
1871 if opts.get('edit'):
1884 if opts.get('edit'):
1872 opts['msg'] = getmsg
1885 opts['msg'] = getmsg
1873 else:
1886 else:
1874 opts['msg'] = msg
1887 opts['msg'] = msg
1875 setupheaderopts(ui, opts)
1888 setupheaderopts(ui, opts)
1876 q.new(repo, patch, *args, **opts)
1889 q.new(repo, patch, *args, **opts)
1877 q.save_dirty()
1890 q.save_dirty()
1878 return 0
1891 return 0
1879
1892
1880 def refresh(ui, repo, *pats, **opts):
1893 def refresh(ui, repo, *pats, **opts):
1881 """update the current patch
1894 """update the current patch
1882
1895
1883 If any file patterns are provided, the refreshed patch will
1896 If any file patterns are provided, the refreshed patch will
1884 contain only the modifications that match those patterns; the
1897 contain only the modifications that match those patterns; the
1885 remaining modifications will remain in the working directory.
1898 remaining modifications will remain in the working directory.
1886
1899
1887 If -s/--short is specified, files currently included in the patch
1900 If -s/--short is specified, files currently included in the patch
1888 will be refreshed just like matched files and remain in the patch.
1901 will be refreshed just like matched files and remain in the patch.
1889
1902
1890 hg add/remove/copy/rename work as usual, though you might want to
1903 hg add/remove/copy/rename work as usual, though you might want to
1891 use git-style patches (-g/--git or [diff] git=1) to track copies
1904 use git-style patches (-g/--git or [diff] git=1) to track copies
1892 and renames. See the diffs help topic for more information on the
1905 and renames. See the diffs help topic for more information on the
1893 git diff format.
1906 git diff format.
1894 """
1907 """
1895 q = repo.mq
1908 q = repo.mq
1896 message = cmdutil.logmessage(opts)
1909 message = cmdutil.logmessage(opts)
1897 if opts['edit']:
1910 if opts['edit']:
1898 if not q.applied:
1911 if not q.applied:
1899 ui.write(_("no patches applied\n"))
1912 ui.write(_("no patches applied\n"))
1900 return 1
1913 return 1
1901 if message:
1914 if message:
1902 raise util.Abort(_('option "-e" incompatible with "-m" or "-l"'))
1915 raise util.Abort(_('option "-e" incompatible with "-m" or "-l"'))
1903 patch = q.applied[-1].name
1916 patch = q.applied[-1].name
1904 ph = q.readheaders(patch)
1917 ph = q.readheaders(patch)
1905 message = ui.edit('\n'.join(ph.message), ph.user or ui.username())
1918 message = ui.edit('\n'.join(ph.message), ph.user or ui.username())
1906 setupheaderopts(ui, opts)
1919 setupheaderopts(ui, opts)
1907 ret = q.refresh(repo, pats, msg=message, **opts)
1920 ret = q.refresh(repo, pats, msg=message, **opts)
1908 q.save_dirty()
1921 q.save_dirty()
1909 return ret
1922 return ret
1910
1923
1911 def diff(ui, repo, *pats, **opts):
1924 def diff(ui, repo, *pats, **opts):
1912 """diff of the current patch and subsequent modifications
1925 """diff of the current patch and subsequent modifications
1913
1926
1914 Shows a diff which includes the current patch as well as any
1927 Shows a diff which includes the current patch as well as any
1915 changes which have been made in the working directory since the
1928 changes which have been made in the working directory since the
1916 last refresh (thus showing what the current patch would become
1929 last refresh (thus showing what the current patch would become
1917 after a qrefresh).
1930 after a qrefresh).
1918
1931
1919 Use 'hg diff' if you only want to see the changes made since the
1932 Use 'hg diff' if you only want to see the changes made since the
1920 last qrefresh, or 'hg export qtip' if you want to see changes made
1933 last qrefresh, or 'hg export qtip' if you want to see changes made
1921 by the current patch without including changes made since the
1934 by the current patch without including changes made since the
1922 qrefresh.
1935 qrefresh.
1923 """
1936 """
1924 repo.mq.diff(repo, pats, opts)
1937 repo.mq.diff(repo, pats, opts)
1925 return 0
1938 return 0
1926
1939
1927 def fold(ui, repo, *files, **opts):
1940 def fold(ui, repo, *files, **opts):
1928 """fold the named patches into the current patch
1941 """fold the named patches into the current patch
1929
1942
1930 Patches must not yet be applied. Each patch will be successively
1943 Patches must not yet be applied. Each patch will be successively
1931 applied to the current patch in the order given. If all the
1944 applied to the current patch in the order given. If all the
1932 patches apply successfully, the current patch will be refreshed
1945 patches apply successfully, the current patch will be refreshed
1933 with the new cumulative patch, and the folded patches will be
1946 with the new cumulative patch, and the folded patches will be
1934 deleted. With -k/--keep, the folded patch files will not be
1947 deleted. With -k/--keep, the folded patch files will not be
1935 removed afterwards.
1948 removed afterwards.
1936
1949
1937 The header for each folded patch will be concatenated with the
1950 The header for each folded patch will be concatenated with the
1938 current patch header, separated by a line of '* * *'."""
1951 current patch header, separated by a line of '* * *'."""
1939
1952
1940 q = repo.mq
1953 q = repo.mq
1941
1954
1942 if not files:
1955 if not files:
1943 raise util.Abort(_('qfold requires at least one patch name'))
1956 raise util.Abort(_('qfold requires at least one patch name'))
1944 if not q.check_toppatch(repo):
1957 if not q.check_toppatch(repo):
1945 raise util.Abort(_('No patches applied'))
1958 raise util.Abort(_('No patches applied'))
1946 q.check_localchanges(repo)
1959 q.check_localchanges(repo)
1947
1960
1948 message = cmdutil.logmessage(opts)
1961 message = cmdutil.logmessage(opts)
1949 if opts['edit']:
1962 if opts['edit']:
1950 if message:
1963 if message:
1951 raise util.Abort(_('option "-e" incompatible with "-m" or "-l"'))
1964 raise util.Abort(_('option "-e" incompatible with "-m" or "-l"'))
1952
1965
1953 parent = q.lookup('qtip')
1966 parent = q.lookup('qtip')
1954 patches = []
1967 patches = []
1955 messages = []
1968 messages = []
1956 for f in files:
1969 for f in files:
1957 p = q.lookup(f)
1970 p = q.lookup(f)
1958 if p in patches or p == parent:
1971 if p in patches or p == parent:
1959 ui.warn(_('Skipping already folded patch %s') % p)
1972 ui.warn(_('Skipping already folded patch %s') % p)
1960 if q.isapplied(p):
1973 if q.isapplied(p):
1961 raise util.Abort(_('qfold cannot fold already applied patch %s') % p)
1974 raise util.Abort(_('qfold cannot fold already applied patch %s') % p)
1962 patches.append(p)
1975 patches.append(p)
1963
1976
1964 for p in patches:
1977 for p in patches:
1965 if not message:
1978 if not message:
1966 ph = q.readheaders(p)
1979 ph = q.readheaders(p)
1967 if ph.message:
1980 if ph.message:
1968 messages.append(ph.message)
1981 messages.append(ph.message)
1969 pf = q.join(p)
1982 pf = q.join(p)
1970 (patchsuccess, files, fuzz) = q.patch(repo, pf)
1983 (patchsuccess, files, fuzz) = q.patch(repo, pf)
1971 if not patchsuccess:
1984 if not patchsuccess:
1972 raise util.Abort(_('Error folding patch %s') % p)
1985 raise util.Abort(_('Error folding patch %s') % p)
1973 patch.updatedir(ui, repo, files)
1986 patch.updatedir(ui, repo, files)
1974
1987
1975 if not message:
1988 if not message:
1976 ph = q.readheaders(parent)
1989 ph = q.readheaders(parent)
1977 message, user = ph.message, ph.user
1990 message, user = ph.message, ph.user
1978 for msg in messages:
1991 for msg in messages:
1979 message.append('* * *')
1992 message.append('* * *')
1980 message.extend(msg)
1993 message.extend(msg)
1981 message = '\n'.join(message)
1994 message = '\n'.join(message)
1982
1995
1983 if opts['edit']:
1996 if opts['edit']:
1984 message = ui.edit(message, user or ui.username())
1997 message = ui.edit(message, user or ui.username())
1985
1998
1986 q.refresh(repo, msg=message)
1999 q.refresh(repo, msg=message)
1987 q.delete(repo, patches, opts)
2000 q.delete(repo, patches, opts)
1988 q.save_dirty()
2001 q.save_dirty()
1989
2002
1990 def goto(ui, repo, patch, **opts):
2003 def goto(ui, repo, patch, **opts):
1991 '''push or pop patches until named patch is at top of stack'''
2004 '''push or pop patches until named patch is at top of stack'''
1992 q = repo.mq
2005 q = repo.mq
1993 patch = q.lookup(patch)
2006 patch = q.lookup(patch)
1994 if q.isapplied(patch):
2007 if q.isapplied(patch):
1995 ret = q.pop(repo, patch, force=opts['force'])
2008 ret = q.pop(repo, patch, force=opts['force'])
1996 else:
2009 else:
1997 ret = q.push(repo, patch, force=opts['force'])
2010 ret = q.push(repo, patch, force=opts['force'])
1998 q.save_dirty()
2011 q.save_dirty()
1999 return ret
2012 return ret
2000
2013
2001 def guard(ui, repo, *args, **opts):
2014 def guard(ui, repo, *args, **opts):
2002 '''set or print guards for a patch
2015 '''set or print guards for a patch
2003
2016
2004 Guards control whether a patch can be pushed. A patch with no
2017 Guards control whether a patch can be pushed. A patch with no
2005 guards is always pushed. A patch with a positive guard ("+foo") is
2018 guards is always pushed. A patch with a positive guard ("+foo") is
2006 pushed only if the qselect command has activated it. A patch with
2019 pushed only if the qselect command has activated it. A patch with
2007 a negative guard ("-foo") is never pushed if the qselect command
2020 a negative guard ("-foo") is never pushed if the qselect command
2008 has activated it.
2021 has activated it.
2009
2022
2010 With no arguments, print the currently active guards.
2023 With no arguments, print the currently active guards.
2011 With arguments, set guards for the named patch.
2024 With arguments, set guards for the named patch.
2012 NOTE: Specifying negative guards now requires '--'.
2025 NOTE: Specifying negative guards now requires '--'.
2013
2026
2014 To set guards on another patch:
2027 To set guards on another patch:
2015 hg qguard -- other.patch +2.6.17 -stable
2028 hg qguard -- other.patch +2.6.17 -stable
2016 '''
2029 '''
2017 def status(idx):
2030 def status(idx):
2018 guards = q.series_guards[idx] or ['unguarded']
2031 guards = q.series_guards[idx] or ['unguarded']
2019 ui.write('%s: %s\n' % (q.series[idx], ' '.join(guards)))
2032 ui.write('%s: %s\n' % (q.series[idx], ' '.join(guards)))
2020 q = repo.mq
2033 q = repo.mq
2021 patch = None
2034 patch = None
2022 args = list(args)
2035 args = list(args)
2023 if opts['list']:
2036 if opts['list']:
2024 if args or opts['none']:
2037 if args or opts['none']:
2025 raise util.Abort(_('cannot mix -l/--list with options or arguments'))
2038 raise util.Abort(_('cannot mix -l/--list with options or arguments'))
2026 for i in xrange(len(q.series)):
2039 for i in xrange(len(q.series)):
2027 status(i)
2040 status(i)
2028 return
2041 return
2029 if not args or args[0][0:1] in '-+':
2042 if not args or args[0][0:1] in '-+':
2030 if not q.applied:
2043 if not q.applied:
2031 raise util.Abort(_('no patches applied'))
2044 raise util.Abort(_('no patches applied'))
2032 patch = q.applied[-1].name
2045 patch = q.applied[-1].name
2033 if patch is None and args[0][0:1] not in '-+':
2046 if patch is None and args[0][0:1] not in '-+':
2034 patch = args.pop(0)
2047 patch = args.pop(0)
2035 if patch is None:
2048 if patch is None:
2036 raise util.Abort(_('no patch to work with'))
2049 raise util.Abort(_('no patch to work with'))
2037 if args or opts['none']:
2050 if args or opts['none']:
2038 idx = q.find_series(patch)
2051 idx = q.find_series(patch)
2039 if idx is None:
2052 if idx is None:
2040 raise util.Abort(_('no patch named %s') % patch)
2053 raise util.Abort(_('no patch named %s') % patch)
2041 q.set_guards(idx, args)
2054 q.set_guards(idx, args)
2042 q.save_dirty()
2055 q.save_dirty()
2043 else:
2056 else:
2044 status(q.series.index(q.lookup(patch)))
2057 status(q.series.index(q.lookup(patch)))
2045
2058
2046 def header(ui, repo, patch=None):
2059 def header(ui, repo, patch=None):
2047 """print the header of the topmost or specified patch"""
2060 """print the header of the topmost or specified patch"""
2048 q = repo.mq
2061 q = repo.mq
2049
2062
2050 if patch:
2063 if patch:
2051 patch = q.lookup(patch)
2064 patch = q.lookup(patch)
2052 else:
2065 else:
2053 if not q.applied:
2066 if not q.applied:
2054 ui.write('no patches applied\n')
2067 ui.write('no patches applied\n')
2055 return 1
2068 return 1
2056 patch = q.lookup('qtip')
2069 patch = q.lookup('qtip')
2057 ph = repo.mq.readheaders(patch)
2070 ph = repo.mq.readheaders(patch)
2058
2071
2059 ui.write('\n'.join(ph.message) + '\n')
2072 ui.write('\n'.join(ph.message) + '\n')
2060
2073
2061 def lastsavename(path):
2074 def lastsavename(path):
2062 (directory, base) = os.path.split(path)
2075 (directory, base) = os.path.split(path)
2063 names = os.listdir(directory)
2076 names = os.listdir(directory)
2064 namere = re.compile("%s.([0-9]+)" % base)
2077 namere = re.compile("%s.([0-9]+)" % base)
2065 maxindex = None
2078 maxindex = None
2066 maxname = None
2079 maxname = None
2067 for f in names:
2080 for f in names:
2068 m = namere.match(f)
2081 m = namere.match(f)
2069 if m:
2082 if m:
2070 index = int(m.group(1))
2083 index = int(m.group(1))
2071 if maxindex == None or index > maxindex:
2084 if maxindex == None or index > maxindex:
2072 maxindex = index
2085 maxindex = index
2073 maxname = f
2086 maxname = f
2074 if maxname:
2087 if maxname:
2075 return (os.path.join(directory, maxname), maxindex)
2088 return (os.path.join(directory, maxname), maxindex)
2076 return (None, None)
2089 return (None, None)
2077
2090
2078 def savename(path):
2091 def savename(path):
2079 (last, index) = lastsavename(path)
2092 (last, index) = lastsavename(path)
2080 if last is None:
2093 if last is None:
2081 index = 0
2094 index = 0
2082 newpath = path + ".%d" % (index + 1)
2095 newpath = path + ".%d" % (index + 1)
2083 return newpath
2096 return newpath
2084
2097
2085 def push(ui, repo, patch=None, **opts):
2098 def push(ui, repo, patch=None, **opts):
2086 """push the next patch onto the stack
2099 """push the next patch onto the stack
2087
2100
2088 When -f/--force is applied, all local changes in patched files
2101 When -f/--force is applied, all local changes in patched files
2089 will be lost.
2102 will be lost.
2090 """
2103 """
2091 q = repo.mq
2104 q = repo.mq
2092 mergeq = None
2105 mergeq = None
2093
2106
2094 if opts['merge']:
2107 if opts['merge']:
2095 if opts['name']:
2108 if opts['name']:
2096 newpath = repo.join(opts['name'])
2109 newpath = repo.join(opts['name'])
2097 else:
2110 else:
2098 newpath, i = lastsavename(q.path)
2111 newpath, i = lastsavename(q.path)
2099 if not newpath:
2112 if not newpath:
2100 ui.warn(_("no saved queues found, please use -n\n"))
2113 ui.warn(_("no saved queues found, please use -n\n"))
2101 return 1
2114 return 1
2102 mergeq = queue(ui, repo.join(""), newpath)
2115 mergeq = queue(ui, repo.join(""), newpath)
2103 ui.warn(_("merging with queue at: %s\n") % mergeq.path)
2116 ui.warn(_("merging with queue at: %s\n") % mergeq.path)
2104 ret = q.push(repo, patch, force=opts['force'], list=opts['list'],
2117 ret = q.push(repo, patch, force=opts['force'], list=opts['list'],
2105 mergeq=mergeq, all=opts.get('all'))
2118 mergeq=mergeq, all=opts.get('all'))
2106 return ret
2119 return ret
2107
2120
2108 def pop(ui, repo, patch=None, **opts):
2121 def pop(ui, repo, patch=None, **opts):
2109 """pop the current patch off the stack
2122 """pop the current patch off the stack
2110
2123
2111 By default, pops off the top of the patch stack. If given a patch
2124 By default, pops off the top of the patch stack. If given a patch
2112 name, keeps popping off patches until the named patch is at the
2125 name, keeps popping off patches until the named patch is at the
2113 top of the stack.
2126 top of the stack.
2114 """
2127 """
2115 localupdate = True
2128 localupdate = True
2116 if opts['name']:
2129 if opts['name']:
2117 q = queue(ui, repo.join(""), repo.join(opts['name']))
2130 q = queue(ui, repo.join(""), repo.join(opts['name']))
2118 ui.warn(_('using patch queue: %s\n') % q.path)
2131 ui.warn(_('using patch queue: %s\n') % q.path)
2119 localupdate = False
2132 localupdate = False
2120 else:
2133 else:
2121 q = repo.mq
2134 q = repo.mq
2122 ret = q.pop(repo, patch, force=opts['force'], update=localupdate,
2135 ret = q.pop(repo, patch, force=opts['force'], update=localupdate,
2123 all=opts['all'])
2136 all=opts['all'])
2124 q.save_dirty()
2137 q.save_dirty()
2125 return ret
2138 return ret
2126
2139
2127 def rename(ui, repo, patch, name=None, **opts):
2140 def rename(ui, repo, patch, name=None, **opts):
2128 """rename a patch
2141 """rename a patch
2129
2142
2130 With one argument, renames the current patch to PATCH1.
2143 With one argument, renames the current patch to PATCH1.
2131 With two arguments, renames PATCH1 to PATCH2."""
2144 With two arguments, renames PATCH1 to PATCH2."""
2132
2145
2133 q = repo.mq
2146 q = repo.mq
2134
2147
2135 if not name:
2148 if not name:
2136 name = patch
2149 name = patch
2137 patch = None
2150 patch = None
2138
2151
2139 if patch:
2152 if patch:
2140 patch = q.lookup(patch)
2153 patch = q.lookup(patch)
2141 else:
2154 else:
2142 if not q.applied:
2155 if not q.applied:
2143 ui.write(_('no patches applied\n'))
2156 ui.write(_('no patches applied\n'))
2144 return
2157 return
2145 patch = q.lookup('qtip')
2158 patch = q.lookup('qtip')
2146 absdest = q.join(name)
2159 absdest = q.join(name)
2147 if os.path.isdir(absdest):
2160 if os.path.isdir(absdest):
2148 name = normname(os.path.join(name, os.path.basename(patch)))
2161 name = normname(os.path.join(name, os.path.basename(patch)))
2149 absdest = q.join(name)
2162 absdest = q.join(name)
2150 if os.path.exists(absdest):
2163 if os.path.exists(absdest):
2151 raise util.Abort(_('%s already exists') % absdest)
2164 raise util.Abort(_('%s already exists') % absdest)
2152
2165
2153 if name in q.series:
2166 if name in q.series:
2154 raise util.Abort(_('A patch named %s already exists in the series file') % name)
2167 raise util.Abort(_('A patch named %s already exists in the series file') % name)
2155
2168
2156 if ui.verbose:
2169 if ui.verbose:
2157 ui.write('renaming %s to %s\n' % (patch, name))
2170 ui.write('renaming %s to %s\n' % (patch, name))
2158 i = q.find_series(patch)
2171 i = q.find_series(patch)
2159 guards = q.guard_re.findall(q.full_series[i])
2172 guards = q.guard_re.findall(q.full_series[i])
2160 q.full_series[i] = name + ''.join([' #' + g for g in guards])
2173 q.full_series[i] = name + ''.join([' #' + g for g in guards])
2161 q.parse_series()
2174 q.parse_series()
2162 q.series_dirty = 1
2175 q.series_dirty = 1
2163
2176
2164 info = q.isapplied(patch)
2177 info = q.isapplied(patch)
2165 if info:
2178 if info:
2166 q.applied[info[0]] = statusentry(info[1], name)
2179 q.applied[info[0]] = statusentry(info[1], name)
2167 q.applied_dirty = 1
2180 q.applied_dirty = 1
2168
2181
2169 util.rename(q.join(patch), absdest)
2182 util.rename(q.join(patch), absdest)
2170 r = q.qrepo()
2183 r = q.qrepo()
2171 if r:
2184 if r:
2172 wlock = r.wlock()
2185 wlock = r.wlock()
2173 try:
2186 try:
2174 if r.dirstate[patch] == 'a':
2187 if r.dirstate[patch] == 'a':
2175 r.dirstate.forget(patch)
2188 r.dirstate.forget(patch)
2176 r.dirstate.add(name)
2189 r.dirstate.add(name)
2177 else:
2190 else:
2178 if r.dirstate[name] == 'r':
2191 if r.dirstate[name] == 'r':
2179 r.undelete([name])
2192 r.undelete([name])
2180 r.copy(patch, name)
2193 r.copy(patch, name)
2181 r.remove([patch], False)
2194 r.remove([patch], False)
2182 finally:
2195 finally:
2183 wlock.release()
2196 wlock.release()
2184
2197
2185 q.save_dirty()
2198 q.save_dirty()
2186
2199
2187 def restore(ui, repo, rev, **opts):
2200 def restore(ui, repo, rev, **opts):
2188 """restore the queue state saved by a revision"""
2201 """restore the queue state saved by a revision"""
2189 rev = repo.lookup(rev)
2202 rev = repo.lookup(rev)
2190 q = repo.mq
2203 q = repo.mq
2191 q.restore(repo, rev, delete=opts['delete'],
2204 q.restore(repo, rev, delete=opts['delete'],
2192 qupdate=opts['update'])
2205 qupdate=opts['update'])
2193 q.save_dirty()
2206 q.save_dirty()
2194 return 0
2207 return 0
2195
2208
2196 def save(ui, repo, **opts):
2209 def save(ui, repo, **opts):
2197 """save current queue state"""
2210 """save current queue state"""
2198 q = repo.mq
2211 q = repo.mq
2199 message = cmdutil.logmessage(opts)
2212 message = cmdutil.logmessage(opts)
2200 ret = q.save(repo, msg=message)
2213 ret = q.save(repo, msg=message)
2201 if ret:
2214 if ret:
2202 return ret
2215 return ret
2203 q.save_dirty()
2216 q.save_dirty()
2204 if opts['copy']:
2217 if opts['copy']:
2205 path = q.path
2218 path = q.path
2206 if opts['name']:
2219 if opts['name']:
2207 newpath = os.path.join(q.basepath, opts['name'])
2220 newpath = os.path.join(q.basepath, opts['name'])
2208 if os.path.exists(newpath):
2221 if os.path.exists(newpath):
2209 if not os.path.isdir(newpath):
2222 if not os.path.isdir(newpath):
2210 raise util.Abort(_('destination %s exists and is not '
2223 raise util.Abort(_('destination %s exists and is not '
2211 'a directory') % newpath)
2224 'a directory') % newpath)
2212 if not opts['force']:
2225 if not opts['force']:
2213 raise util.Abort(_('destination %s exists, '
2226 raise util.Abort(_('destination %s exists, '
2214 'use -f to force') % newpath)
2227 'use -f to force') % newpath)
2215 else:
2228 else:
2216 newpath = savename(path)
2229 newpath = savename(path)
2217 ui.warn(_("copy %s to %s\n") % (path, newpath))
2230 ui.warn(_("copy %s to %s\n") % (path, newpath))
2218 util.copyfiles(path, newpath)
2231 util.copyfiles(path, newpath)
2219 if opts['empty']:
2232 if opts['empty']:
2220 try:
2233 try:
2221 os.unlink(q.join(q.status_path))
2234 os.unlink(q.join(q.status_path))
2222 except:
2235 except:
2223 pass
2236 pass
2224 return 0
2237 return 0
2225
2238
2226 def strip(ui, repo, rev, **opts):
2239 def strip(ui, repo, rev, **opts):
2227 """strip a revision and all its descendants from the repository
2240 """strip a revision and all its descendants from the repository
2228
2241
2229 If one of the working directory's parent revisions is stripped, the
2242 If one of the working directory's parent revisions is stripped, the
2230 working directory will be updated to the parent of the stripped
2243 working directory will be updated to the parent of the stripped
2231 revision.
2244 revision.
2232 """
2245 """
2233 backup = 'all'
2246 backup = 'all'
2234 if opts['backup']:
2247 if opts['backup']:
2235 backup = 'strip'
2248 backup = 'strip'
2236 elif opts['nobackup']:
2249 elif opts['nobackup']:
2237 backup = 'none'
2250 backup = 'none'
2238
2251
2239 rev = repo.lookup(rev)
2252 rev = repo.lookup(rev)
2240 p = repo.dirstate.parents()
2253 p = repo.dirstate.parents()
2241 cl = repo.changelog
2254 cl = repo.changelog
2242 update = True
2255 update = True
2243 if p[0] == nullid:
2256 if p[0] == nullid:
2244 update = False
2257 update = False
2245 elif p[1] == nullid and rev != cl.ancestor(p[0], rev):
2258 elif p[1] == nullid and rev != cl.ancestor(p[0], rev):
2246 update = False
2259 update = False
2247 elif rev not in (cl.ancestor(p[0], rev), cl.ancestor(p[1], rev)):
2260 elif rev not in (cl.ancestor(p[0], rev), cl.ancestor(p[1], rev)):
2248 update = False
2261 update = False
2249
2262
2250 repo.mq.strip(repo, rev, backup=backup, update=update, force=opts['force'])
2263 repo.mq.strip(repo, rev, backup=backup, update=update, force=opts['force'])
2251 return 0
2264 return 0
2252
2265
2253 def select(ui, repo, *args, **opts):
2266 def select(ui, repo, *args, **opts):
2254 '''set or print guarded patches to push
2267 '''set or print guarded patches to push
2255
2268
2256 Use the qguard command to set or print guards on patch, then use
2269 Use the qguard command to set or print guards on patch, then use
2257 qselect to tell mq which guards to use. A patch will be pushed if
2270 qselect to tell mq which guards to use. A patch will be pushed if
2258 it has no guards or any positive guards match the currently
2271 it has no guards or any positive guards match the currently
2259 selected guard, but will not be pushed if any negative guards
2272 selected guard, but will not be pushed if any negative guards
2260 match the current guard. For example:
2273 match the current guard. For example:
2261
2274
2262 qguard foo.patch -stable (negative guard)
2275 qguard foo.patch -stable (negative guard)
2263 qguard bar.patch +stable (positive guard)
2276 qguard bar.patch +stable (positive guard)
2264 qselect stable
2277 qselect stable
2265
2278
2266 This activates the "stable" guard. mq will skip foo.patch (because
2279 This activates the "stable" guard. mq will skip foo.patch (because
2267 it has a negative match) but push bar.patch (because it has a
2280 it has a negative match) but push bar.patch (because it has a
2268 positive match).
2281 positive match).
2269
2282
2270 With no arguments, prints the currently active guards.
2283 With no arguments, prints the currently active guards.
2271 With one argument, sets the active guard.
2284 With one argument, sets the active guard.
2272
2285
2273 Use -n/--none to deactivate guards (no other arguments needed).
2286 Use -n/--none to deactivate guards (no other arguments needed).
2274 When no guards are active, patches with positive guards are
2287 When no guards are active, patches with positive guards are
2275 skipped and patches with negative guards are pushed.
2288 skipped and patches with negative guards are pushed.
2276
2289
2277 qselect can change the guards on applied patches. It does not pop
2290 qselect can change the guards on applied patches. It does not pop
2278 guarded patches by default. Use --pop to pop back to the last
2291 guarded patches by default. Use --pop to pop back to the last
2279 applied patch that is not guarded. Use --reapply (which implies
2292 applied patch that is not guarded. Use --reapply (which implies
2280 --pop) to push back to the current patch afterwards, but skip
2293 --pop) to push back to the current patch afterwards, but skip
2281 guarded patches.
2294 guarded patches.
2282
2295
2283 Use -s/--series to print a list of all guards in the series file
2296 Use -s/--series to print a list of all guards in the series file
2284 (no other arguments needed). Use -v for more information.'''
2297 (no other arguments needed). Use -v for more information.'''
2285
2298
2286 q = repo.mq
2299 q = repo.mq
2287 guards = q.active()
2300 guards = q.active()
2288 if args or opts['none']:
2301 if args or opts['none']:
2289 old_unapplied = q.unapplied(repo)
2302 old_unapplied = q.unapplied(repo)
2290 old_guarded = [i for i in xrange(len(q.applied)) if
2303 old_guarded = [i for i in xrange(len(q.applied)) if
2291 not q.pushable(i)[0]]
2304 not q.pushable(i)[0]]
2292 q.set_active(args)
2305 q.set_active(args)
2293 q.save_dirty()
2306 q.save_dirty()
2294 if not args:
2307 if not args:
2295 ui.status(_('guards deactivated\n'))
2308 ui.status(_('guards deactivated\n'))
2296 if not opts['pop'] and not opts['reapply']:
2309 if not opts['pop'] and not opts['reapply']:
2297 unapplied = q.unapplied(repo)
2310 unapplied = q.unapplied(repo)
2298 guarded = [i for i in xrange(len(q.applied))
2311 guarded = [i for i in xrange(len(q.applied))
2299 if not q.pushable(i)[0]]
2312 if not q.pushable(i)[0]]
2300 if len(unapplied) != len(old_unapplied):
2313 if len(unapplied) != len(old_unapplied):
2301 ui.status(_('number of unguarded, unapplied patches has '
2314 ui.status(_('number of unguarded, unapplied patches has '
2302 'changed from %d to %d\n') %
2315 'changed from %d to %d\n') %
2303 (len(old_unapplied), len(unapplied)))
2316 (len(old_unapplied), len(unapplied)))
2304 if len(guarded) != len(old_guarded):
2317 if len(guarded) != len(old_guarded):
2305 ui.status(_('number of guarded, applied patches has changed '
2318 ui.status(_('number of guarded, applied patches has changed '
2306 'from %d to %d\n') %
2319 'from %d to %d\n') %
2307 (len(old_guarded), len(guarded)))
2320 (len(old_guarded), len(guarded)))
2308 elif opts['series']:
2321 elif opts['series']:
2309 guards = {}
2322 guards = {}
2310 noguards = 0
2323 noguards = 0
2311 for gs in q.series_guards:
2324 for gs in q.series_guards:
2312 if not gs:
2325 if not gs:
2313 noguards += 1
2326 noguards += 1
2314 for g in gs:
2327 for g in gs:
2315 guards.setdefault(g, 0)
2328 guards.setdefault(g, 0)
2316 guards[g] += 1
2329 guards[g] += 1
2317 if ui.verbose:
2330 if ui.verbose:
2318 guards['NONE'] = noguards
2331 guards['NONE'] = noguards
2319 guards = guards.items()
2332 guards = guards.items()
2320 guards.sort(lambda a, b: cmp(a[0][1:], b[0][1:]))
2333 guards.sort(lambda a, b: cmp(a[0][1:], b[0][1:]))
2321 if guards:
2334 if guards:
2322 ui.note(_('guards in series file:\n'))
2335 ui.note(_('guards in series file:\n'))
2323 for guard, count in guards:
2336 for guard, count in guards:
2324 ui.note('%2d ' % count)
2337 ui.note('%2d ' % count)
2325 ui.write(guard, '\n')
2338 ui.write(guard, '\n')
2326 else:
2339 else:
2327 ui.note(_('no guards in series file\n'))
2340 ui.note(_('no guards in series file\n'))
2328 else:
2341 else:
2329 if guards:
2342 if guards:
2330 ui.note(_('active guards:\n'))
2343 ui.note(_('active guards:\n'))
2331 for g in guards:
2344 for g in guards:
2332 ui.write(g, '\n')
2345 ui.write(g, '\n')
2333 else:
2346 else:
2334 ui.write(_('no active guards\n'))
2347 ui.write(_('no active guards\n'))
2335 reapply = opts['reapply'] and q.applied and q.appliedname(-1)
2348 reapply = opts['reapply'] and q.applied and q.appliedname(-1)
2336 popped = False
2349 popped = False
2337 if opts['pop'] or opts['reapply']:
2350 if opts['pop'] or opts['reapply']:
2338 for i in xrange(len(q.applied)):
2351 for i in xrange(len(q.applied)):
2339 pushable, reason = q.pushable(i)
2352 pushable, reason = q.pushable(i)
2340 if not pushable:
2353 if not pushable:
2341 ui.status(_('popping guarded patches\n'))
2354 ui.status(_('popping guarded patches\n'))
2342 popped = True
2355 popped = True
2343 if i == 0:
2356 if i == 0:
2344 q.pop(repo, all=True)
2357 q.pop(repo, all=True)
2345 else:
2358 else:
2346 q.pop(repo, i-1)
2359 q.pop(repo, i-1)
2347 break
2360 break
2348 if popped:
2361 if popped:
2349 try:
2362 try:
2350 if reapply:
2363 if reapply:
2351 ui.status(_('reapplying unguarded patches\n'))
2364 ui.status(_('reapplying unguarded patches\n'))
2352 q.push(repo, reapply)
2365 q.push(repo, reapply)
2353 finally:
2366 finally:
2354 q.save_dirty()
2367 q.save_dirty()
2355
2368
2356 def finish(ui, repo, *revrange, **opts):
2369 def finish(ui, repo, *revrange, **opts):
2357 """move applied patches into repository history
2370 """move applied patches into repository history
2358
2371
2359 Finishes the specified revisions (corresponding to applied
2372 Finishes the specified revisions (corresponding to applied
2360 patches) by moving them out of mq control into regular repository
2373 patches) by moving them out of mq control into regular repository
2361 history.
2374 history.
2362
2375
2363 Accepts a revision range or the -a/--applied option. If --applied
2376 Accepts a revision range or the -a/--applied option. If --applied
2364 is specified, all applied mq revisions are removed from mq
2377 is specified, all applied mq revisions are removed from mq
2365 control. Otherwise, the given revisions must be at the base of the
2378 control. Otherwise, the given revisions must be at the base of the
2366 stack of applied patches.
2379 stack of applied patches.
2367
2380
2368 This can be especially useful if your changes have been applied to
2381 This can be especially useful if your changes have been applied to
2369 an upstream repository, or if you are about to push your changes
2382 an upstream repository, or if you are about to push your changes
2370 to upstream.
2383 to upstream.
2371 """
2384 """
2372 if not opts['applied'] and not revrange:
2385 if not opts['applied'] and not revrange:
2373 raise util.Abort(_('no revisions specified'))
2386 raise util.Abort(_('no revisions specified'))
2374 elif opts['applied']:
2387 elif opts['applied']:
2375 revrange = ('qbase:qtip',) + revrange
2388 revrange = ('qbase:qtip',) + revrange
2376
2389
2377 q = repo.mq
2390 q = repo.mq
2378 if not q.applied:
2391 if not q.applied:
2379 ui.status(_('no patches applied\n'))
2392 ui.status(_('no patches applied\n'))
2380 return 0
2393 return 0
2381
2394
2382 revs = cmdutil.revrange(repo, revrange)
2395 revs = cmdutil.revrange(repo, revrange)
2383 q.finish(repo, revs)
2396 q.finish(repo, revs)
2384 q.save_dirty()
2397 q.save_dirty()
2385 return 0
2398 return 0
2386
2399
2387 def reposetup(ui, repo):
2400 def reposetup(ui, repo):
2388 class mqrepo(repo.__class__):
2401 class mqrepo(repo.__class__):
2402 @util.propertycache
2403 def mq(self):
2404 return queue(self.ui, self.join(""))
2405
2389 def abort_if_wdir_patched(self, errmsg, force=False):
2406 def abort_if_wdir_patched(self, errmsg, force=False):
2390 if self.mq.applied and not force:
2407 if self.mq.applied and not force:
2391 parent = hex(self.dirstate.parents()[0])
2408 parent = hex(self.dirstate.parents()[0])
2392 if parent in [s.rev for s in self.mq.applied]:
2409 if parent in [s.rev for s in self.mq.applied]:
2393 raise util.Abort(errmsg)
2410 raise util.Abort(errmsg)
2394
2411
2395 def commit(self, *args, **opts):
2412 def commit(self, *args, **opts):
2396 if len(args) >= 6:
2413 if len(args) >= 6:
2397 force = args[5]
2414 force = args[5]
2398 else:
2415 else:
2399 force = opts.get('force')
2416 force = opts.get('force')
2400 self.abort_if_wdir_patched(
2417 self.abort_if_wdir_patched(
2401 _('cannot commit over an applied mq patch'),
2418 _('cannot commit over an applied mq patch'),
2402 force)
2419 force)
2403
2420
2404 return super(mqrepo, self).commit(*args, **opts)
2421 return super(mqrepo, self).commit(*args, **opts)
2405
2422
2406 def push(self, remote, force=False, revs=None):
2423 def push(self, remote, force=False, revs=None):
2407 if self.mq.applied and not force and not revs:
2424 if self.mq.applied and not force and not revs:
2408 raise util.Abort(_('source has mq patches applied'))
2425 raise util.Abort(_('source has mq patches applied'))
2409 return super(mqrepo, self).push(remote, force, revs)
2426 return super(mqrepo, self).push(remote, force, revs)
2410
2427
2411 def tags(self):
2428 def tags(self):
2412 if self.tagscache:
2429 if self.tagscache:
2413 return self.tagscache
2430 return self.tagscache
2414
2431
2415 tagscache = super(mqrepo, self).tags()
2432 tagscache = super(mqrepo, self).tags()
2416
2433
2417 q = self.mq
2434 q = self.mq
2418 if not q.applied:
2435 if not q.applied:
2419 return tagscache
2436 return tagscache
2420
2437
2421 mqtags = [(bin(patch.rev), patch.name) for patch in q.applied]
2438 mqtags = [(bin(patch.rev), patch.name) for patch in q.applied]
2422
2439
2423 if mqtags[-1][0] not in self.changelog.nodemap:
2440 if mqtags[-1][0] not in self.changelog.nodemap:
2424 self.ui.warn(_('mq status file refers to unknown node %s\n')
2441 self.ui.warn(_('mq status file refers to unknown node %s\n')
2425 % short(mqtags[-1][0]))
2442 % short(mqtags[-1][0]))
2426 return tagscache
2443 return tagscache
2427
2444
2428 mqtags.append((mqtags[-1][0], 'qtip'))
2445 mqtags.append((mqtags[-1][0], 'qtip'))
2429 mqtags.append((mqtags[0][0], 'qbase'))
2446 mqtags.append((mqtags[0][0], 'qbase'))
2430 mqtags.append((self.changelog.parents(mqtags[0][0])[0], 'qparent'))
2447 mqtags.append((self.changelog.parents(mqtags[0][0])[0], 'qparent'))
2431 for patch in mqtags:
2448 for patch in mqtags:
2432 if patch[1] in tagscache:
2449 if patch[1] in tagscache:
2433 self.ui.warn(_('Tag %s overrides mq patch of the same name\n')
2450 self.ui.warn(_('Tag %s overrides mq patch of the same name\n')
2434 % patch[1])
2451 % patch[1])
2435 else:
2452 else:
2436 tagscache[patch[1]] = patch[0]
2453 tagscache[patch[1]] = patch[0]
2437
2454
2438 return tagscache
2455 return tagscache
2439
2456
2440 def _branchtags(self, partial, lrev):
2457 def _branchtags(self, partial, lrev):
2441 q = self.mq
2458 q = self.mq
2442 if not q.applied:
2459 if not q.applied:
2443 return super(mqrepo, self)._branchtags(partial, lrev)
2460 return super(mqrepo, self)._branchtags(partial, lrev)
2444
2461
2445 cl = self.changelog
2462 cl = self.changelog
2446 qbasenode = bin(q.applied[0].rev)
2463 qbasenode = bin(q.applied[0].rev)
2447 if qbasenode not in cl.nodemap:
2464 if qbasenode not in cl.nodemap:
2448 self.ui.warn(_('mq status file refers to unknown node %s\n')
2465 self.ui.warn(_('mq status file refers to unknown node %s\n')
2449 % short(qbasenode))
2466 % short(qbasenode))
2450 return super(mqrepo, self)._branchtags(partial, lrev)
2467 return super(mqrepo, self)._branchtags(partial, lrev)
2451
2468
2452 qbase = cl.rev(qbasenode)
2469 qbase = cl.rev(qbasenode)
2453 start = lrev + 1
2470 start = lrev + 1
2454 if start < qbase:
2471 if start < qbase:
2455 # update the cache (excluding the patches) and save it
2472 # update the cache (excluding the patches) and save it
2456 self._updatebranchcache(partial, lrev+1, qbase)
2473 self._updatebranchcache(partial, lrev+1, qbase)
2457 self._writebranchcache(partial, cl.node(qbase-1), qbase-1)
2474 self._writebranchcache(partial, cl.node(qbase-1), qbase-1)
2458 start = qbase
2475 start = qbase
2459 # if start = qbase, the cache is as updated as it should be.
2476 # if start = qbase, the cache is as updated as it should be.
2460 # if start > qbase, the cache includes (part of) the patches.
2477 # if start > qbase, the cache includes (part of) the patches.
2461 # we might as well use it, but we won't save it.
2478 # we might as well use it, but we won't save it.
2462
2479
2463 # update the cache up to the tip
2480 # update the cache up to the tip
2464 self._updatebranchcache(partial, start, len(cl))
2481 self._updatebranchcache(partial, start, len(cl))
2465
2482
2466 return partial
2483 return partial
2467
2484
2468 if repo.local():
2485 if repo.local():
2469 repo.__class__ = mqrepo
2486 repo.__class__ = mqrepo
2470 repo.mq = queue(ui, repo.join(""))
2471
2487
2472 def mqimport(orig, ui, repo, *args, **kwargs):
2488 def mqimport(orig, ui, repo, *args, **kwargs):
2473 if hasattr(repo, 'abort_if_wdir_patched'):
2489 if hasattr(repo, 'abort_if_wdir_patched'):
2474 repo.abort_if_wdir_patched(_('cannot import over an applied patch'),
2490 repo.abort_if_wdir_patched(_('cannot import over an applied patch'),
2475 kwargs.get('force'))
2491 kwargs.get('force'))
2476 return orig(ui, repo, *args, **kwargs)
2492 return orig(ui, repo, *args, **kwargs)
2477
2493
2478 def uisetup(ui):
2494 def uisetup(ui):
2479 extensions.wrapcommand(commands.table, 'import', mqimport)
2495 extensions.wrapcommand(commands.table, 'import', mqimport)
2480
2496
2481 seriesopts = [('s', 'summary', None, _('print first line of patch header'))]
2497 seriesopts = [('s', 'summary', None, _('print first line of patch header'))]
2482
2498
2483 cmdtable = {
2499 cmdtable = {
2484 "qapplied": (applied, [] + seriesopts, _('hg qapplied [-s] [PATCH]')),
2500 "qapplied": (applied, [] + seriesopts, _('hg qapplied [-s] [PATCH]')),
2485 "qclone":
2501 "qclone":
2486 (clone,
2502 (clone,
2487 [('', 'pull', None, _('use pull protocol to copy metadata')),
2503 [('', 'pull', None, _('use pull protocol to copy metadata')),
2488 ('U', 'noupdate', None, _('do not update the new working directories')),
2504 ('U', 'noupdate', None, _('do not update the new working directories')),
2489 ('', 'uncompressed', None,
2505 ('', 'uncompressed', None,
2490 _('use uncompressed transfer (fast over LAN)')),
2506 _('use uncompressed transfer (fast over LAN)')),
2491 ('p', 'patches', '', _('location of source patch repository')),
2507 ('p', 'patches', '', _('location of source patch repository')),
2492 ] + commands.remoteopts,
2508 ] + commands.remoteopts,
2493 _('hg qclone [OPTION]... SOURCE [DEST]')),
2509 _('hg qclone [OPTION]... SOURCE [DEST]')),
2494 "qcommit|qci":
2510 "qcommit|qci":
2495 (commit,
2511 (commit,
2496 commands.table["^commit|ci"][1],
2512 commands.table["^commit|ci"][1],
2497 _('hg qcommit [OPTION]... [FILE]...')),
2513 _('hg qcommit [OPTION]... [FILE]...')),
2498 "^qdiff":
2514 "^qdiff":
2499 (diff,
2515 (diff,
2500 commands.diffopts + commands.diffopts2 + commands.walkopts,
2516 commands.diffopts + commands.diffopts2 + commands.walkopts,
2501 _('hg qdiff [OPTION]... [FILE]...')),
2517 _('hg qdiff [OPTION]... [FILE]...')),
2502 "qdelete|qremove|qrm":
2518 "qdelete|qremove|qrm":
2503 (delete,
2519 (delete,
2504 [('k', 'keep', None, _('keep patch file')),
2520 [('k', 'keep', None, _('keep patch file')),
2505 ('r', 'rev', [], _('stop managing a revision'))],
2521 ('r', 'rev', [], _('stop managing a revision'))],
2506 _('hg qdelete [-k] [-r REV]... [PATCH]...')),
2522 _('hg qdelete [-k] [-r REV]... [PATCH]...')),
2507 'qfold':
2523 'qfold':
2508 (fold,
2524 (fold,
2509 [('e', 'edit', None, _('edit patch header')),
2525 [('e', 'edit', None, _('edit patch header')),
2510 ('k', 'keep', None, _('keep folded patch files')),
2526 ('k', 'keep', None, _('keep folded patch files')),
2511 ] + commands.commitopts,
2527 ] + commands.commitopts,
2512 _('hg qfold [-e] [-k] [-m TEXT] [-l FILE] PATCH...')),
2528 _('hg qfold [-e] [-k] [-m TEXT] [-l FILE] PATCH...')),
2513 'qgoto':
2529 'qgoto':
2514 (goto,
2530 (goto,
2515 [('f', 'force', None, _('overwrite any local changes'))],
2531 [('f', 'force', None, _('overwrite any local changes'))],
2516 _('hg qgoto [OPTION]... PATCH')),
2532 _('hg qgoto [OPTION]... PATCH')),
2517 'qguard':
2533 'qguard':
2518 (guard,
2534 (guard,
2519 [('l', 'list', None, _('list all patches and guards')),
2535 [('l', 'list', None, _('list all patches and guards')),
2520 ('n', 'none', None, _('drop all guards'))],
2536 ('n', 'none', None, _('drop all guards'))],
2521 _('hg qguard [-l] [-n] -- [PATCH] [+GUARD]... [-GUARD]...')),
2537 _('hg qguard [-l] [-n] -- [PATCH] [+GUARD]... [-GUARD]...')),
2522 'qheader': (header, [], _('hg qheader [PATCH]')),
2538 'qheader': (header, [], _('hg qheader [PATCH]')),
2523 "^qimport":
2539 "^qimport":
2524 (qimport,
2540 (qimport,
2525 [('e', 'existing', None, _('import file in patch directory')),
2541 [('e', 'existing', None, _('import file in patch directory')),
2526 ('n', 'name', '', _('patch file name')),
2542 ('n', 'name', '', _('patch file name')),
2527 ('f', 'force', None, _('overwrite existing files')),
2543 ('f', 'force', None, _('overwrite existing files')),
2528 ('r', 'rev', [], _('place existing revisions under mq control')),
2544 ('r', 'rev', [], _('place existing revisions under mq control')),
2529 ('g', 'git', None, _('use git extended diff format')),
2545 ('g', 'git', None, _('use git extended diff format')),
2530 ('P', 'push', None, _('qpush after importing'))],
2546 ('P', 'push', None, _('qpush after importing'))],
2531 _('hg qimport [-e] [-n NAME] [-f] [-g] [-P] [-r REV]... FILE...')),
2547 _('hg qimport [-e] [-n NAME] [-f] [-g] [-P] [-r REV]... FILE...')),
2532 "^qinit":
2548 "^qinit":
2533 (init,
2549 (init,
2534 [('c', 'create-repo', None, _('create queue repository'))],
2550 [('c', 'create-repo', None, _('create queue repository'))],
2535 _('hg qinit [-c]')),
2551 _('hg qinit [-c]')),
2536 "qnew":
2552 "qnew":
2537 (new,
2553 (new,
2538 [('e', 'edit', None, _('edit commit message')),
2554 [('e', 'edit', None, _('edit commit message')),
2539 ('f', 'force', None, _('import uncommitted changes into patch')),
2555 ('f', 'force', None, _('import uncommitted changes into patch')),
2540 ('g', 'git', None, _('use git extended diff format')),
2556 ('g', 'git', None, _('use git extended diff format')),
2541 ('U', 'currentuser', None, _('add "From: <current user>" to patch')),
2557 ('U', 'currentuser', None, _('add "From: <current user>" to patch')),
2542 ('u', 'user', '', _('add "From: <given user>" to patch')),
2558 ('u', 'user', '', _('add "From: <given user>" to patch')),
2543 ('D', 'currentdate', None, _('add "Date: <current date>" to patch')),
2559 ('D', 'currentdate', None, _('add "Date: <current date>" to patch')),
2544 ('d', 'date', '', _('add "Date: <given date>" to patch'))
2560 ('d', 'date', '', _('add "Date: <given date>" to patch'))
2545 ] + commands.walkopts + commands.commitopts,
2561 ] + commands.walkopts + commands.commitopts,
2546 _('hg qnew [-e] [-m TEXT] [-l FILE] [-f] PATCH [FILE]...')),
2562 _('hg qnew [-e] [-m TEXT] [-l FILE] [-f] PATCH [FILE]...')),
2547 "qnext": (next, [] + seriesopts, _('hg qnext [-s]')),
2563 "qnext": (next, [] + seriesopts, _('hg qnext [-s]')),
2548 "qprev": (prev, [] + seriesopts, _('hg qprev [-s]')),
2564 "qprev": (prev, [] + seriesopts, _('hg qprev [-s]')),
2549 "^qpop":
2565 "^qpop":
2550 (pop,
2566 (pop,
2551 [('a', 'all', None, _('pop all patches')),
2567 [('a', 'all', None, _('pop all patches')),
2552 ('n', 'name', '', _('queue name to pop')),
2568 ('n', 'name', '', _('queue name to pop')),
2553 ('f', 'force', None, _('forget any local changes'))],
2569 ('f', 'force', None, _('forget any local changes'))],
2554 _('hg qpop [-a] [-n NAME] [-f] [PATCH | INDEX]')),
2570 _('hg qpop [-a] [-n NAME] [-f] [PATCH | INDEX]')),
2555 "^qpush":
2571 "^qpush":
2556 (push,
2572 (push,
2557 [('f', 'force', None, _('apply if the patch has rejects')),
2573 [('f', 'force', None, _('apply if the patch has rejects')),
2558 ('l', 'list', None, _('list patch name in commit text')),
2574 ('l', 'list', None, _('list patch name in commit text')),
2559 ('a', 'all', None, _('apply all patches')),
2575 ('a', 'all', None, _('apply all patches')),
2560 ('m', 'merge', None, _('merge from another queue')),
2576 ('m', 'merge', None, _('merge from another queue')),
2561 ('n', 'name', '', _('merge queue name'))],
2577 ('n', 'name', '', _('merge queue name'))],
2562 _('hg qpush [-f] [-l] [-a] [-m] [-n NAME] [PATCH | INDEX]')),
2578 _('hg qpush [-f] [-l] [-a] [-m] [-n NAME] [PATCH | INDEX]')),
2563 "^qrefresh":
2579 "^qrefresh":
2564 (refresh,
2580 (refresh,
2565 [('e', 'edit', None, _('edit commit message')),
2581 [('e', 'edit', None, _('edit commit message')),
2566 ('g', 'git', None, _('use git extended diff format')),
2582 ('g', 'git', None, _('use git extended diff format')),
2567 ('s', 'short', None, _('refresh only files already in the patch and specified files')),
2583 ('s', 'short', None, _('refresh only files already in the patch and specified files')),
2568 ('U', 'currentuser', None, _('add/update "From: <current user>" in patch')),
2584 ('U', 'currentuser', None, _('add/update "From: <current user>" in patch')),
2569 ('u', 'user', '', _('add/update "From: <given user>" in patch')),
2585 ('u', 'user', '', _('add/update "From: <given user>" in patch')),
2570 ('D', 'currentdate', None, _('update "Date: <current date>" in patch (if present)')),
2586 ('D', 'currentdate', None, _('update "Date: <current date>" in patch (if present)')),
2571 ('d', 'date', '', _('update "Date: <given date>" in patch (if present)'))
2587 ('d', 'date', '', _('update "Date: <given date>" in patch (if present)'))
2572 ] + commands.walkopts + commands.commitopts,
2588 ] + commands.walkopts + commands.commitopts,
2573 _('hg qrefresh [-I] [-X] [-e] [-m TEXT] [-l FILE] [-s] [FILE]...')),
2589 _('hg qrefresh [-I] [-X] [-e] [-m TEXT] [-l FILE] [-s] [FILE]...')),
2574 'qrename|qmv':
2590 'qrename|qmv':
2575 (rename, [], _('hg qrename PATCH1 [PATCH2]')),
2591 (rename, [], _('hg qrename PATCH1 [PATCH2]')),
2576 "qrestore":
2592 "qrestore":
2577 (restore,
2593 (restore,
2578 [('d', 'delete', None, _('delete save entry')),
2594 [('d', 'delete', None, _('delete save entry')),
2579 ('u', 'update', None, _('update queue working directory'))],
2595 ('u', 'update', None, _('update queue working directory'))],
2580 _('hg qrestore [-d] [-u] REV')),
2596 _('hg qrestore [-d] [-u] REV')),
2581 "qsave":
2597 "qsave":
2582 (save,
2598 (save,
2583 [('c', 'copy', None, _('copy patch directory')),
2599 [('c', 'copy', None, _('copy patch directory')),
2584 ('n', 'name', '', _('copy directory name')),
2600 ('n', 'name', '', _('copy directory name')),
2585 ('e', 'empty', None, _('clear queue status file')),
2601 ('e', 'empty', None, _('clear queue status file')),
2586 ('f', 'force', None, _('force copy'))] + commands.commitopts,
2602 ('f', 'force', None, _('force copy'))] + commands.commitopts,
2587 _('hg qsave [-m TEXT] [-l FILE] [-c] [-n NAME] [-e] [-f]')),
2603 _('hg qsave [-m TEXT] [-l FILE] [-c] [-n NAME] [-e] [-f]')),
2588 "qselect":
2604 "qselect":
2589 (select,
2605 (select,
2590 [('n', 'none', None, _('disable all guards')),
2606 [('n', 'none', None, _('disable all guards')),
2591 ('s', 'series', None, _('list all guards in series file')),
2607 ('s', 'series', None, _('list all guards in series file')),
2592 ('', 'pop', None, _('pop to before first guarded applied patch')),
2608 ('', 'pop', None, _('pop to before first guarded applied patch')),
2593 ('', 'reapply', None, _('pop, then reapply patches'))],
2609 ('', 'reapply', None, _('pop, then reapply patches'))],
2594 _('hg qselect [OPTION]... [GUARD]...')),
2610 _('hg qselect [OPTION]... [GUARD]...')),
2595 "qseries":
2611 "qseries":
2596 (series,
2612 (series,
2597 [('m', 'missing', None, _('print patches not in series')),
2613 [('m', 'missing', None, _('print patches not in series')),
2598 ] + seriesopts,
2614 ] + seriesopts,
2599 _('hg qseries [-ms]')),
2615 _('hg qseries [-ms]')),
2600 "^strip":
2616 "^strip":
2601 (strip,
2617 (strip,
2602 [('f', 'force', None, _('force removal with local changes')),
2618 [('f', 'force', None, _('force removal with local changes')),
2603 ('b', 'backup', None, _('bundle unrelated changesets')),
2619 ('b', 'backup', None, _('bundle unrelated changesets')),
2604 ('n', 'nobackup', None, _('no backups'))],
2620 ('n', 'nobackup', None, _('no backups'))],
2605 _('hg strip [-f] [-b] [-n] REV')),
2621 _('hg strip [-f] [-b] [-n] REV')),
2606 "qtop": (top, [] + seriesopts, _('hg qtop [-s]')),
2622 "qtop": (top, [] + seriesopts, _('hg qtop [-s]')),
2607 "qunapplied": (unapplied, [] + seriesopts, _('hg qunapplied [-s] [PATCH]')),
2623 "qunapplied": (unapplied, [] + seriesopts, _('hg qunapplied [-s] [PATCH]')),
2608 "qfinish":
2624 "qfinish":
2609 (finish,
2625 (finish,
2610 [('a', 'applied', None, _('finish all applied changesets'))],
2626 [('a', 'applied', None, _('finish all applied changesets'))],
2611 _('hg qfinish [-a] [REV...]')),
2627 _('hg qfinish [-a] [REV...]')),
2612 }
2628 }
General Comments 0
You need to be logged in to leave comments. Login now