##// END OF EJS Templates
mq: write headers for new HG patches in the same order as export (BC)
Mads Kiilerich -
r22520:9d4ebb75 default
parent child Browse files
Show More
@@ -1,3483 +1,3483 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 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 '''manage a stack of patches
8 '''manage a stack of patches
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 create new patch qnew
19 create new patch qnew
20 import existing patch qimport
20 import existing patch qimport
21
21
22 print patch series qseries
22 print patch series qseries
23 print applied patches qapplied
23 print applied patches qapplied
24
24
25 add known patch to applied stack qpush
25 add known patch to applied stack qpush
26 remove patch from applied stack qpop
26 remove patch from applied stack qpop
27 refresh contents of top applied patch qrefresh
27 refresh contents of top applied patch qrefresh
28
28
29 By default, mq will automatically use git patches when required to
29 By default, mq will automatically use git patches when required to
30 avoid losing file mode changes, copy records, binary files or empty
30 avoid losing file mode changes, copy records, binary files or empty
31 files creations or deletions. This behaviour can be configured with::
31 files creations or deletions. This behaviour can be configured with::
32
32
33 [mq]
33 [mq]
34 git = auto/keep/yes/no
34 git = auto/keep/yes/no
35
35
36 If set to 'keep', mq will obey the [diff] section configuration while
36 If set to 'keep', mq will obey the [diff] section configuration while
37 preserving existing git patches upon qrefresh. If set to 'yes' or
37 preserving existing git patches upon qrefresh. If set to 'yes' or
38 'no', mq will override the [diff] section and always generate git or
38 'no', mq will override the [diff] section and always generate git or
39 regular patches, possibly losing data in the second case.
39 regular patches, possibly losing data in the second case.
40
40
41 It may be desirable for mq changesets to be kept in the secret phase (see
41 It may be desirable for mq changesets to be kept in the secret phase (see
42 :hg:`help phases`), which can be enabled with the following setting::
42 :hg:`help phases`), which can be enabled with the following setting::
43
43
44 [mq]
44 [mq]
45 secret = True
45 secret = True
46
46
47 You will by default be managing a patch queue named "patches". You can
47 You will by default be managing a patch queue named "patches". You can
48 create other, independent patch queues with the :hg:`qqueue` command.
48 create other, independent patch queues with the :hg:`qqueue` command.
49
49
50 If the working directory contains uncommitted files, qpush, qpop and
50 If the working directory contains uncommitted files, qpush, qpop and
51 qgoto abort immediately. If -f/--force is used, the changes are
51 qgoto abort immediately. If -f/--force is used, the changes are
52 discarded. Setting::
52 discarded. Setting::
53
53
54 [mq]
54 [mq]
55 keepchanges = True
55 keepchanges = True
56
56
57 make them behave as if --keep-changes were passed, and non-conflicting
57 make them behave as if --keep-changes were passed, and non-conflicting
58 local changes will be tolerated and preserved. If incompatible options
58 local changes will be tolerated and preserved. If incompatible options
59 such as -f/--force or --exact are passed, this setting is ignored.
59 such as -f/--force or --exact are passed, this setting is ignored.
60
60
61 This extension used to provide a strip command. This command now lives
61 This extension used to provide a strip command. This command now lives
62 in the strip extension.
62 in the strip extension.
63 '''
63 '''
64
64
65 from mercurial.i18n import _
65 from mercurial.i18n import _
66 from mercurial.node import bin, hex, short, nullid, nullrev
66 from mercurial.node import bin, hex, short, nullid, nullrev
67 from mercurial.lock import release
67 from mercurial.lock import release
68 from mercurial import commands, cmdutil, hg, scmutil, util, revset
68 from mercurial import commands, cmdutil, hg, scmutil, util, revset
69 from mercurial import extensions, error, phases
69 from mercurial import extensions, error, phases
70 from mercurial import patch as patchmod
70 from mercurial import patch as patchmod
71 from mercurial import localrepo
71 from mercurial import localrepo
72 from mercurial import subrepo
72 from mercurial import subrepo
73 import os, re, errno, shutil
73 import os, re, errno, shutil
74
74
75 seriesopts = [('s', 'summary', None, _('print first line of patch header'))]
75 seriesopts = [('s', 'summary', None, _('print first line of patch header'))]
76
76
77 cmdtable = {}
77 cmdtable = {}
78 command = cmdutil.command(cmdtable)
78 command = cmdutil.command(cmdtable)
79 testedwith = 'internal'
79 testedwith = 'internal'
80
80
81 # force load strip extension formerly included in mq and import some utility
81 # force load strip extension formerly included in mq and import some utility
82 try:
82 try:
83 stripext = extensions.find('strip')
83 stripext = extensions.find('strip')
84 except KeyError:
84 except KeyError:
85 # note: load is lazy so we could avoid the try-except,
85 # note: load is lazy so we could avoid the try-except,
86 # but I (marmoute) prefer this explicit code.
86 # but I (marmoute) prefer this explicit code.
87 class dummyui(object):
87 class dummyui(object):
88 def debug(self, msg):
88 def debug(self, msg):
89 pass
89 pass
90 stripext = extensions.load(dummyui(), 'strip', '')
90 stripext = extensions.load(dummyui(), 'strip', '')
91
91
92 strip = stripext.strip
92 strip = stripext.strip
93 checksubstate = stripext.checksubstate
93 checksubstate = stripext.checksubstate
94 checklocalchanges = stripext.checklocalchanges
94 checklocalchanges = stripext.checklocalchanges
95
95
96
96
97 # Patch names looks like unix-file names.
97 # Patch names looks like unix-file names.
98 # They must be joinable with queue directory and result in the patch path.
98 # They must be joinable with queue directory and result in the patch path.
99 normname = util.normpath
99 normname = util.normpath
100
100
101 class statusentry(object):
101 class statusentry(object):
102 def __init__(self, node, name):
102 def __init__(self, node, name):
103 self.node, self.name = node, name
103 self.node, self.name = node, name
104 def __repr__(self):
104 def __repr__(self):
105 return hex(self.node) + ':' + self.name
105 return hex(self.node) + ':' + self.name
106
106
107 class patchheader(object):
107 class patchheader(object):
108 def __init__(self, pf, plainmode=False):
108 def __init__(self, pf, plainmode=False):
109 def eatdiff(lines):
109 def eatdiff(lines):
110 while lines:
110 while lines:
111 l = lines[-1]
111 l = lines[-1]
112 if (l.startswith("diff -") or
112 if (l.startswith("diff -") or
113 l.startswith("Index:") or
113 l.startswith("Index:") or
114 l.startswith("===========")):
114 l.startswith("===========")):
115 del lines[-1]
115 del lines[-1]
116 else:
116 else:
117 break
117 break
118 def eatempty(lines):
118 def eatempty(lines):
119 while lines:
119 while lines:
120 if not lines[-1].strip():
120 if not lines[-1].strip():
121 del lines[-1]
121 del lines[-1]
122 else:
122 else:
123 break
123 break
124
124
125 message = []
125 message = []
126 comments = []
126 comments = []
127 user = None
127 user = None
128 date = None
128 date = None
129 parent = None
129 parent = None
130 format = None
130 format = None
131 subject = None
131 subject = None
132 branch = None
132 branch = None
133 nodeid = None
133 nodeid = None
134 diffstart = 0
134 diffstart = 0
135
135
136 for line in file(pf):
136 for line in file(pf):
137 line = line.rstrip()
137 line = line.rstrip()
138 if (line.startswith('diff --git')
138 if (line.startswith('diff --git')
139 or (diffstart and line.startswith('+++ '))):
139 or (diffstart and line.startswith('+++ '))):
140 diffstart = 2
140 diffstart = 2
141 break
141 break
142 diffstart = 0 # reset
142 diffstart = 0 # reset
143 if line.startswith("--- "):
143 if line.startswith("--- "):
144 diffstart = 1
144 diffstart = 1
145 continue
145 continue
146 elif format == "hgpatch":
146 elif format == "hgpatch":
147 # parse values when importing the result of an hg export
147 # parse values when importing the result of an hg export
148 if line.startswith("# User "):
148 if line.startswith("# User "):
149 user = line[7:]
149 user = line[7:]
150 elif line.startswith("# Date "):
150 elif line.startswith("# Date "):
151 date = line[7:]
151 date = line[7:]
152 elif line.startswith("# Parent "):
152 elif line.startswith("# Parent "):
153 parent = line[9:].lstrip()
153 parent = line[9:].lstrip()
154 elif line.startswith("# Branch "):
154 elif line.startswith("# Branch "):
155 branch = line[9:]
155 branch = line[9:]
156 elif line.startswith("# Node ID "):
156 elif line.startswith("# Node ID "):
157 nodeid = line[10:]
157 nodeid = line[10:]
158 elif not line.startswith("# ") and line:
158 elif not line.startswith("# ") and line:
159 message.append(line)
159 message.append(line)
160 format = None
160 format = None
161 elif line == '# HG changeset patch':
161 elif line == '# HG changeset patch':
162 message = []
162 message = []
163 format = "hgpatch"
163 format = "hgpatch"
164 elif (format != "tagdone" and (line.startswith("Subject: ") or
164 elif (format != "tagdone" and (line.startswith("Subject: ") or
165 line.startswith("subject: "))):
165 line.startswith("subject: "))):
166 subject = line[9:]
166 subject = line[9:]
167 format = "tag"
167 format = "tag"
168 elif (format != "tagdone" and (line.startswith("From: ") or
168 elif (format != "tagdone" and (line.startswith("From: ") or
169 line.startswith("from: "))):
169 line.startswith("from: "))):
170 user = line[6:]
170 user = line[6:]
171 format = "tag"
171 format = "tag"
172 elif (format != "tagdone" and (line.startswith("Date: ") or
172 elif (format != "tagdone" and (line.startswith("Date: ") or
173 line.startswith("date: "))):
173 line.startswith("date: "))):
174 date = line[6:]
174 date = line[6:]
175 format = "tag"
175 format = "tag"
176 elif format == "tag" and line == "":
176 elif format == "tag" and line == "":
177 # when looking for tags (subject: from: etc) they
177 # when looking for tags (subject: from: etc) they
178 # end once you find a blank line in the source
178 # end once you find a blank line in the source
179 format = "tagdone"
179 format = "tagdone"
180 elif message or line:
180 elif message or line:
181 message.append(line)
181 message.append(line)
182 comments.append(line)
182 comments.append(line)
183
183
184 eatdiff(message)
184 eatdiff(message)
185 eatdiff(comments)
185 eatdiff(comments)
186 # Remember the exact starting line of the patch diffs before consuming
186 # Remember the exact starting line of the patch diffs before consuming
187 # empty lines, for external use by TortoiseHg and others
187 # empty lines, for external use by TortoiseHg and others
188 self.diffstartline = len(comments)
188 self.diffstartline = len(comments)
189 eatempty(message)
189 eatempty(message)
190 eatempty(comments)
190 eatempty(comments)
191
191
192 # make sure message isn't empty
192 # make sure message isn't empty
193 if format and format.startswith("tag") and subject:
193 if format and format.startswith("tag") and subject:
194 message.insert(0, "")
194 message.insert(0, "")
195 message.insert(0, subject)
195 message.insert(0, subject)
196
196
197 self.message = message
197 self.message = message
198 self.comments = comments
198 self.comments = comments
199 self.user = user
199 self.user = user
200 self.date = date
200 self.date = date
201 self.parent = parent
201 self.parent = parent
202 # nodeid and branch are for external use by TortoiseHg and others
202 # nodeid and branch are for external use by TortoiseHg and others
203 self.nodeid = nodeid
203 self.nodeid = nodeid
204 self.branch = branch
204 self.branch = branch
205 self.haspatch = diffstart > 1
205 self.haspatch = diffstart > 1
206 self.plainmode = plainmode
206 self.plainmode = plainmode
207
207
208 def setuser(self, user):
208 def setuser(self, user):
209 if not self.updateheader(['From: ', '# User '], user):
209 if not self.updateheader(['From: ', '# User '], user):
210 try:
210 try:
211 patchheaderat = self.comments.index('# HG changeset patch')
211 patchheaderat = self.comments.index('# HG changeset patch')
212 self.comments.insert(patchheaderat + 1, '# User ' + user)
212 self.comments.insert(patchheaderat + 1, '# User ' + user)
213 except ValueError:
213 except ValueError:
214 if self.plainmode or self._hasheader(['Date: ']):
214 if self.plainmode or self._hasheader(['Date: ']):
215 self.comments = ['From: ' + user] + self.comments
215 self.comments = ['From: ' + user] + self.comments
216 else:
216 else:
217 tmp = ['# HG changeset patch', '# User ' + user, '']
217 tmp = ['# HG changeset patch', '# User ' + user, '']
218 self.comments = tmp + self.comments
218 self.comments = tmp + self.comments
219 self.user = user
219 self.user = user
220
220
221 def setdate(self, date):
221 def setdate(self, date):
222 if not self.updateheader(['Date: ', '# Date '], date):
222 if not self.updateheader(['Date: ', '# Date '], date):
223 try:
223 try:
224 patchheaderat = self.comments.index('# HG changeset patch')
224 patchheaderat = self.comments.index('# HG changeset patch')
225 self.comments.insert(patchheaderat + 1, '# Date ' + date)
225 self.comments.insert(patchheaderat + 1, '# Date ' + date)
226 except ValueError:
226 except ValueError:
227 if self.plainmode or self._hasheader(['From: ']):
227 if self.plainmode or self._hasheader(['From: ']):
228 self.comments = ['Date: ' + date] + self.comments
228 self.comments = ['Date: ' + date] + self.comments
229 else:
229 else:
230 tmp = ['# HG changeset patch', '# Date ' + date, '']
230 tmp = ['# HG changeset patch', '# Date ' + date, '']
231 self.comments = tmp + self.comments
231 self.comments = tmp + self.comments
232 self.date = date
232 self.date = date
233
233
234 def setparent(self, parent):
234 def setparent(self, parent):
235 if not self.updateheader(['# Parent '], parent):
235 if not self.updateheader(['# Parent '], parent):
236 try:
236 try:
237 patchheaderat = self.comments.index('# HG changeset patch')
237 patchheaderat = self.comments.index('# HG changeset patch')
238 self.comments.insert(patchheaderat + 1, '# Parent ' + parent)
238 self.comments.insert(patchheaderat + 1, '# Parent ' + parent)
239 except ValueError:
239 except ValueError:
240 pass
240 pass
241 self.parent = parent
241 self.parent = parent
242
242
243 def setmessage(self, message):
243 def setmessage(self, message):
244 if self.comments:
244 if self.comments:
245 self._delmsg()
245 self._delmsg()
246 self.message = [message]
246 self.message = [message]
247 self.comments += self.message
247 self.comments += self.message
248
248
249 def updateheader(self, prefixes, new):
249 def updateheader(self, prefixes, new):
250 '''Update all references to a field in the patch header.
250 '''Update all references to a field in the patch header.
251 Return whether the field is present.'''
251 Return whether the field is present.'''
252 res = False
252 res = False
253 for prefix in prefixes:
253 for prefix in prefixes:
254 for i in xrange(len(self.comments)):
254 for i in xrange(len(self.comments)):
255 if self.comments[i].startswith(prefix):
255 if self.comments[i].startswith(prefix):
256 self.comments[i] = prefix + new
256 self.comments[i] = prefix + new
257 res = True
257 res = True
258 break
258 break
259 return res
259 return res
260
260
261 def _hasheader(self, prefixes):
261 def _hasheader(self, prefixes):
262 '''Check if a header starts with any of the given prefixes.'''
262 '''Check if a header starts with any of the given prefixes.'''
263 for prefix in prefixes:
263 for prefix in prefixes:
264 for comment in self.comments:
264 for comment in self.comments:
265 if comment.startswith(prefix):
265 if comment.startswith(prefix):
266 return True
266 return True
267 return False
267 return False
268
268
269 def __str__(self):
269 def __str__(self):
270 if not self.comments:
270 if not self.comments:
271 return ''
271 return ''
272 return '\n'.join(self.comments) + '\n\n'
272 return '\n'.join(self.comments) + '\n\n'
273
273
274 def _delmsg(self):
274 def _delmsg(self):
275 '''Remove existing message, keeping the rest of the comments fields.
275 '''Remove existing message, keeping the rest of the comments fields.
276 If comments contains 'subject: ', message will prepend
276 If comments contains 'subject: ', message will prepend
277 the field and a blank line.'''
277 the field and a blank line.'''
278 if self.message:
278 if self.message:
279 subj = 'subject: ' + self.message[0].lower()
279 subj = 'subject: ' + self.message[0].lower()
280 for i in xrange(len(self.comments)):
280 for i in xrange(len(self.comments)):
281 if subj == self.comments[i].lower():
281 if subj == self.comments[i].lower():
282 del self.comments[i]
282 del self.comments[i]
283 self.message = self.message[2:]
283 self.message = self.message[2:]
284 break
284 break
285 ci = 0
285 ci = 0
286 for mi in self.message:
286 for mi in self.message:
287 while mi != self.comments[ci]:
287 while mi != self.comments[ci]:
288 ci += 1
288 ci += 1
289 del self.comments[ci]
289 del self.comments[ci]
290
290
291 def newcommit(repo, phase, *args, **kwargs):
291 def newcommit(repo, phase, *args, **kwargs):
292 """helper dedicated to ensure a commit respect mq.secret setting
292 """helper dedicated to ensure a commit respect mq.secret setting
293
293
294 It should be used instead of repo.commit inside the mq source for operation
294 It should be used instead of repo.commit inside the mq source for operation
295 creating new changeset.
295 creating new changeset.
296 """
296 """
297 repo = repo.unfiltered()
297 repo = repo.unfiltered()
298 if phase is None:
298 if phase is None:
299 if repo.ui.configbool('mq', 'secret', False):
299 if repo.ui.configbool('mq', 'secret', False):
300 phase = phases.secret
300 phase = phases.secret
301 if phase is not None:
301 if phase is not None:
302 backup = repo.ui.backupconfig('phases', 'new-commit')
302 backup = repo.ui.backupconfig('phases', 'new-commit')
303 try:
303 try:
304 if phase is not None:
304 if phase is not None:
305 repo.ui.setconfig('phases', 'new-commit', phase, 'mq')
305 repo.ui.setconfig('phases', 'new-commit', phase, 'mq')
306 return repo.commit(*args, **kwargs)
306 return repo.commit(*args, **kwargs)
307 finally:
307 finally:
308 if phase is not None:
308 if phase is not None:
309 repo.ui.restoreconfig(backup)
309 repo.ui.restoreconfig(backup)
310
310
311 class AbortNoCleanup(error.Abort):
311 class AbortNoCleanup(error.Abort):
312 pass
312 pass
313
313
314 class queue(object):
314 class queue(object):
315 def __init__(self, ui, baseui, path, patchdir=None):
315 def __init__(self, ui, baseui, path, patchdir=None):
316 self.basepath = path
316 self.basepath = path
317 try:
317 try:
318 fh = open(os.path.join(path, 'patches.queue'))
318 fh = open(os.path.join(path, 'patches.queue'))
319 cur = fh.read().rstrip()
319 cur = fh.read().rstrip()
320 fh.close()
320 fh.close()
321 if not cur:
321 if not cur:
322 curpath = os.path.join(path, 'patches')
322 curpath = os.path.join(path, 'patches')
323 else:
323 else:
324 curpath = os.path.join(path, 'patches-' + cur)
324 curpath = os.path.join(path, 'patches-' + cur)
325 except IOError:
325 except IOError:
326 curpath = os.path.join(path, 'patches')
326 curpath = os.path.join(path, 'patches')
327 self.path = patchdir or curpath
327 self.path = patchdir or curpath
328 self.opener = scmutil.opener(self.path)
328 self.opener = scmutil.opener(self.path)
329 self.ui = ui
329 self.ui = ui
330 self.baseui = baseui
330 self.baseui = baseui
331 self.applieddirty = False
331 self.applieddirty = False
332 self.seriesdirty = False
332 self.seriesdirty = False
333 self.added = []
333 self.added = []
334 self.seriespath = "series"
334 self.seriespath = "series"
335 self.statuspath = "status"
335 self.statuspath = "status"
336 self.guardspath = "guards"
336 self.guardspath = "guards"
337 self.activeguards = None
337 self.activeguards = None
338 self.guardsdirty = False
338 self.guardsdirty = False
339 # Handle mq.git as a bool with extended values
339 # Handle mq.git as a bool with extended values
340 try:
340 try:
341 gitmode = ui.configbool('mq', 'git', None)
341 gitmode = ui.configbool('mq', 'git', None)
342 if gitmode is None:
342 if gitmode is None:
343 raise error.ConfigError
343 raise error.ConfigError
344 self.gitmode = gitmode and 'yes' or 'no'
344 self.gitmode = gitmode and 'yes' or 'no'
345 except error.ConfigError:
345 except error.ConfigError:
346 self.gitmode = ui.config('mq', 'git', 'auto').lower()
346 self.gitmode = ui.config('mq', 'git', 'auto').lower()
347 self.plainmode = ui.configbool('mq', 'plain', False)
347 self.plainmode = ui.configbool('mq', 'plain', False)
348 self.checkapplied = True
348 self.checkapplied = True
349
349
350 @util.propertycache
350 @util.propertycache
351 def applied(self):
351 def applied(self):
352 def parselines(lines):
352 def parselines(lines):
353 for l in lines:
353 for l in lines:
354 entry = l.split(':', 1)
354 entry = l.split(':', 1)
355 if len(entry) > 1:
355 if len(entry) > 1:
356 n, name = entry
356 n, name = entry
357 yield statusentry(bin(n), name)
357 yield statusentry(bin(n), name)
358 elif l.strip():
358 elif l.strip():
359 self.ui.warn(_('malformated mq status line: %s\n') % entry)
359 self.ui.warn(_('malformated mq status line: %s\n') % entry)
360 # else we ignore empty lines
360 # else we ignore empty lines
361 try:
361 try:
362 lines = self.opener.read(self.statuspath).splitlines()
362 lines = self.opener.read(self.statuspath).splitlines()
363 return list(parselines(lines))
363 return list(parselines(lines))
364 except IOError, e:
364 except IOError, e:
365 if e.errno == errno.ENOENT:
365 if e.errno == errno.ENOENT:
366 return []
366 return []
367 raise
367 raise
368
368
369 @util.propertycache
369 @util.propertycache
370 def fullseries(self):
370 def fullseries(self):
371 try:
371 try:
372 return self.opener.read(self.seriespath).splitlines()
372 return self.opener.read(self.seriespath).splitlines()
373 except IOError, e:
373 except IOError, e:
374 if e.errno == errno.ENOENT:
374 if e.errno == errno.ENOENT:
375 return []
375 return []
376 raise
376 raise
377
377
378 @util.propertycache
378 @util.propertycache
379 def series(self):
379 def series(self):
380 self.parseseries()
380 self.parseseries()
381 return self.series
381 return self.series
382
382
383 @util.propertycache
383 @util.propertycache
384 def seriesguards(self):
384 def seriesguards(self):
385 self.parseseries()
385 self.parseseries()
386 return self.seriesguards
386 return self.seriesguards
387
387
388 def invalidate(self):
388 def invalidate(self):
389 for a in 'applied fullseries series seriesguards'.split():
389 for a in 'applied fullseries series seriesguards'.split():
390 if a in self.__dict__:
390 if a in self.__dict__:
391 delattr(self, a)
391 delattr(self, a)
392 self.applieddirty = False
392 self.applieddirty = False
393 self.seriesdirty = False
393 self.seriesdirty = False
394 self.guardsdirty = False
394 self.guardsdirty = False
395 self.activeguards = None
395 self.activeguards = None
396
396
397 def diffopts(self, opts={}, patchfn=None):
397 def diffopts(self, opts={}, patchfn=None):
398 diffopts = patchmod.diffopts(self.ui, opts)
398 diffopts = patchmod.diffopts(self.ui, opts)
399 if self.gitmode == 'auto':
399 if self.gitmode == 'auto':
400 diffopts.upgrade = True
400 diffopts.upgrade = True
401 elif self.gitmode == 'keep':
401 elif self.gitmode == 'keep':
402 pass
402 pass
403 elif self.gitmode in ('yes', 'no'):
403 elif self.gitmode in ('yes', 'no'):
404 diffopts.git = self.gitmode == 'yes'
404 diffopts.git = self.gitmode == 'yes'
405 else:
405 else:
406 raise util.Abort(_('mq.git option can be auto/keep/yes/no'
406 raise util.Abort(_('mq.git option can be auto/keep/yes/no'
407 ' got %s') % self.gitmode)
407 ' got %s') % self.gitmode)
408 if patchfn:
408 if patchfn:
409 diffopts = self.patchopts(diffopts, patchfn)
409 diffopts = self.patchopts(diffopts, patchfn)
410 return diffopts
410 return diffopts
411
411
412 def patchopts(self, diffopts, *patches):
412 def patchopts(self, diffopts, *patches):
413 """Return a copy of input diff options with git set to true if
413 """Return a copy of input diff options with git set to true if
414 referenced patch is a git patch and should be preserved as such.
414 referenced patch is a git patch and should be preserved as such.
415 """
415 """
416 diffopts = diffopts.copy()
416 diffopts = diffopts.copy()
417 if not diffopts.git and self.gitmode == 'keep':
417 if not diffopts.git and self.gitmode == 'keep':
418 for patchfn in patches:
418 for patchfn in patches:
419 patchf = self.opener(patchfn, 'r')
419 patchf = self.opener(patchfn, 'r')
420 # if the patch was a git patch, refresh it as a git patch
420 # if the patch was a git patch, refresh it as a git patch
421 for line in patchf:
421 for line in patchf:
422 if line.startswith('diff --git'):
422 if line.startswith('diff --git'):
423 diffopts.git = True
423 diffopts.git = True
424 break
424 break
425 patchf.close()
425 patchf.close()
426 return diffopts
426 return diffopts
427
427
428 def join(self, *p):
428 def join(self, *p):
429 return os.path.join(self.path, *p)
429 return os.path.join(self.path, *p)
430
430
431 def findseries(self, patch):
431 def findseries(self, patch):
432 def matchpatch(l):
432 def matchpatch(l):
433 l = l.split('#', 1)[0]
433 l = l.split('#', 1)[0]
434 return l.strip() == patch
434 return l.strip() == patch
435 for index, l in enumerate(self.fullseries):
435 for index, l in enumerate(self.fullseries):
436 if matchpatch(l):
436 if matchpatch(l):
437 return index
437 return index
438 return None
438 return None
439
439
440 guard_re = re.compile(r'\s?#([-+][^-+# \t\r\n\f][^# \t\r\n\f]*)')
440 guard_re = re.compile(r'\s?#([-+][^-+# \t\r\n\f][^# \t\r\n\f]*)')
441
441
442 def parseseries(self):
442 def parseseries(self):
443 self.series = []
443 self.series = []
444 self.seriesguards = []
444 self.seriesguards = []
445 for l in self.fullseries:
445 for l in self.fullseries:
446 h = l.find('#')
446 h = l.find('#')
447 if h == -1:
447 if h == -1:
448 patch = l
448 patch = l
449 comment = ''
449 comment = ''
450 elif h == 0:
450 elif h == 0:
451 continue
451 continue
452 else:
452 else:
453 patch = l[:h]
453 patch = l[:h]
454 comment = l[h:]
454 comment = l[h:]
455 patch = patch.strip()
455 patch = patch.strip()
456 if patch:
456 if patch:
457 if patch in self.series:
457 if patch in self.series:
458 raise util.Abort(_('%s appears more than once in %s') %
458 raise util.Abort(_('%s appears more than once in %s') %
459 (patch, self.join(self.seriespath)))
459 (patch, self.join(self.seriespath)))
460 self.series.append(patch)
460 self.series.append(patch)
461 self.seriesguards.append(self.guard_re.findall(comment))
461 self.seriesguards.append(self.guard_re.findall(comment))
462
462
463 def checkguard(self, guard):
463 def checkguard(self, guard):
464 if not guard:
464 if not guard:
465 return _('guard cannot be an empty string')
465 return _('guard cannot be an empty string')
466 bad_chars = '# \t\r\n\f'
466 bad_chars = '# \t\r\n\f'
467 first = guard[0]
467 first = guard[0]
468 if first in '-+':
468 if first in '-+':
469 return (_('guard %r starts with invalid character: %r') %
469 return (_('guard %r starts with invalid character: %r') %
470 (guard, first))
470 (guard, first))
471 for c in bad_chars:
471 for c in bad_chars:
472 if c in guard:
472 if c in guard:
473 return _('invalid character in guard %r: %r') % (guard, c)
473 return _('invalid character in guard %r: %r') % (guard, c)
474
474
475 def setactive(self, guards):
475 def setactive(self, guards):
476 for guard in guards:
476 for guard in guards:
477 bad = self.checkguard(guard)
477 bad = self.checkguard(guard)
478 if bad:
478 if bad:
479 raise util.Abort(bad)
479 raise util.Abort(bad)
480 guards = sorted(set(guards))
480 guards = sorted(set(guards))
481 self.ui.debug('active guards: %s\n' % ' '.join(guards))
481 self.ui.debug('active guards: %s\n' % ' '.join(guards))
482 self.activeguards = guards
482 self.activeguards = guards
483 self.guardsdirty = True
483 self.guardsdirty = True
484
484
485 def active(self):
485 def active(self):
486 if self.activeguards is None:
486 if self.activeguards is None:
487 self.activeguards = []
487 self.activeguards = []
488 try:
488 try:
489 guards = self.opener.read(self.guardspath).split()
489 guards = self.opener.read(self.guardspath).split()
490 except IOError, err:
490 except IOError, err:
491 if err.errno != errno.ENOENT:
491 if err.errno != errno.ENOENT:
492 raise
492 raise
493 guards = []
493 guards = []
494 for i, guard in enumerate(guards):
494 for i, guard in enumerate(guards):
495 bad = self.checkguard(guard)
495 bad = self.checkguard(guard)
496 if bad:
496 if bad:
497 self.ui.warn('%s:%d: %s\n' %
497 self.ui.warn('%s:%d: %s\n' %
498 (self.join(self.guardspath), i + 1, bad))
498 (self.join(self.guardspath), i + 1, bad))
499 else:
499 else:
500 self.activeguards.append(guard)
500 self.activeguards.append(guard)
501 return self.activeguards
501 return self.activeguards
502
502
503 def setguards(self, idx, guards):
503 def setguards(self, idx, guards):
504 for g in guards:
504 for g in guards:
505 if len(g) < 2:
505 if len(g) < 2:
506 raise util.Abort(_('guard %r too short') % g)
506 raise util.Abort(_('guard %r too short') % g)
507 if g[0] not in '-+':
507 if g[0] not in '-+':
508 raise util.Abort(_('guard %r starts with invalid char') % g)
508 raise util.Abort(_('guard %r starts with invalid char') % g)
509 bad = self.checkguard(g[1:])
509 bad = self.checkguard(g[1:])
510 if bad:
510 if bad:
511 raise util.Abort(bad)
511 raise util.Abort(bad)
512 drop = self.guard_re.sub('', self.fullseries[idx])
512 drop = self.guard_re.sub('', self.fullseries[idx])
513 self.fullseries[idx] = drop + ''.join([' #' + g for g in guards])
513 self.fullseries[idx] = drop + ''.join([' #' + g for g in guards])
514 self.parseseries()
514 self.parseseries()
515 self.seriesdirty = True
515 self.seriesdirty = True
516
516
517 def pushable(self, idx):
517 def pushable(self, idx):
518 if isinstance(idx, str):
518 if isinstance(idx, str):
519 idx = self.series.index(idx)
519 idx = self.series.index(idx)
520 patchguards = self.seriesguards[idx]
520 patchguards = self.seriesguards[idx]
521 if not patchguards:
521 if not patchguards:
522 return True, None
522 return True, None
523 guards = self.active()
523 guards = self.active()
524 exactneg = [g for g in patchguards if g[0] == '-' and g[1:] in guards]
524 exactneg = [g for g in patchguards if g[0] == '-' and g[1:] in guards]
525 if exactneg:
525 if exactneg:
526 return False, repr(exactneg[0])
526 return False, repr(exactneg[0])
527 pos = [g for g in patchguards if g[0] == '+']
527 pos = [g for g in patchguards if g[0] == '+']
528 exactpos = [g for g in pos if g[1:] in guards]
528 exactpos = [g for g in pos if g[1:] in guards]
529 if pos:
529 if pos:
530 if exactpos:
530 if exactpos:
531 return True, repr(exactpos[0])
531 return True, repr(exactpos[0])
532 return False, ' '.join(map(repr, pos))
532 return False, ' '.join(map(repr, pos))
533 return True, ''
533 return True, ''
534
534
535 def explainpushable(self, idx, all_patches=False):
535 def explainpushable(self, idx, all_patches=False):
536 write = all_patches and self.ui.write or self.ui.warn
536 write = all_patches and self.ui.write or self.ui.warn
537 if all_patches or self.ui.verbose:
537 if all_patches or self.ui.verbose:
538 if isinstance(idx, str):
538 if isinstance(idx, str):
539 idx = self.series.index(idx)
539 idx = self.series.index(idx)
540 pushable, why = self.pushable(idx)
540 pushable, why = self.pushable(idx)
541 if all_patches and pushable:
541 if all_patches and pushable:
542 if why is None:
542 if why is None:
543 write(_('allowing %s - no guards in effect\n') %
543 write(_('allowing %s - no guards in effect\n') %
544 self.series[idx])
544 self.series[idx])
545 else:
545 else:
546 if not why:
546 if not why:
547 write(_('allowing %s - no matching negative guards\n') %
547 write(_('allowing %s - no matching negative guards\n') %
548 self.series[idx])
548 self.series[idx])
549 else:
549 else:
550 write(_('allowing %s - guarded by %s\n') %
550 write(_('allowing %s - guarded by %s\n') %
551 (self.series[idx], why))
551 (self.series[idx], why))
552 if not pushable:
552 if not pushable:
553 if why:
553 if why:
554 write(_('skipping %s - guarded by %s\n') %
554 write(_('skipping %s - guarded by %s\n') %
555 (self.series[idx], why))
555 (self.series[idx], why))
556 else:
556 else:
557 write(_('skipping %s - no matching guards\n') %
557 write(_('skipping %s - no matching guards\n') %
558 self.series[idx])
558 self.series[idx])
559
559
560 def savedirty(self):
560 def savedirty(self):
561 def writelist(items, path):
561 def writelist(items, path):
562 fp = self.opener(path, 'w')
562 fp = self.opener(path, 'w')
563 for i in items:
563 for i in items:
564 fp.write("%s\n" % i)
564 fp.write("%s\n" % i)
565 fp.close()
565 fp.close()
566 if self.applieddirty:
566 if self.applieddirty:
567 writelist(map(str, self.applied), self.statuspath)
567 writelist(map(str, self.applied), self.statuspath)
568 self.applieddirty = False
568 self.applieddirty = False
569 if self.seriesdirty:
569 if self.seriesdirty:
570 writelist(self.fullseries, self.seriespath)
570 writelist(self.fullseries, self.seriespath)
571 self.seriesdirty = False
571 self.seriesdirty = False
572 if self.guardsdirty:
572 if self.guardsdirty:
573 writelist(self.activeguards, self.guardspath)
573 writelist(self.activeguards, self.guardspath)
574 self.guardsdirty = False
574 self.guardsdirty = False
575 if self.added:
575 if self.added:
576 qrepo = self.qrepo()
576 qrepo = self.qrepo()
577 if qrepo:
577 if qrepo:
578 qrepo[None].add(f for f in self.added if f not in qrepo[None])
578 qrepo[None].add(f for f in self.added if f not in qrepo[None])
579 self.added = []
579 self.added = []
580
580
581 def removeundo(self, repo):
581 def removeundo(self, repo):
582 undo = repo.sjoin('undo')
582 undo = repo.sjoin('undo')
583 if not os.path.exists(undo):
583 if not os.path.exists(undo):
584 return
584 return
585 try:
585 try:
586 os.unlink(undo)
586 os.unlink(undo)
587 except OSError, inst:
587 except OSError, inst:
588 self.ui.warn(_('error removing undo: %s\n') % str(inst))
588 self.ui.warn(_('error removing undo: %s\n') % str(inst))
589
589
590 def backup(self, repo, files, copy=False):
590 def backup(self, repo, files, copy=False):
591 # backup local changes in --force case
591 # backup local changes in --force case
592 for f in sorted(files):
592 for f in sorted(files):
593 absf = repo.wjoin(f)
593 absf = repo.wjoin(f)
594 if os.path.lexists(absf):
594 if os.path.lexists(absf):
595 self.ui.note(_('saving current version of %s as %s\n') %
595 self.ui.note(_('saving current version of %s as %s\n') %
596 (f, f + '.orig'))
596 (f, f + '.orig'))
597 if copy:
597 if copy:
598 util.copyfile(absf, absf + '.orig')
598 util.copyfile(absf, absf + '.orig')
599 else:
599 else:
600 util.rename(absf, absf + '.orig')
600 util.rename(absf, absf + '.orig')
601
601
602 def printdiff(self, repo, diffopts, node1, node2=None, files=None,
602 def printdiff(self, repo, diffopts, node1, node2=None, files=None,
603 fp=None, changes=None, opts={}):
603 fp=None, changes=None, opts={}):
604 stat = opts.get('stat')
604 stat = opts.get('stat')
605 m = scmutil.match(repo[node1], files, opts)
605 m = scmutil.match(repo[node1], files, opts)
606 cmdutil.diffordiffstat(self.ui, repo, diffopts, node1, node2, m,
606 cmdutil.diffordiffstat(self.ui, repo, diffopts, node1, node2, m,
607 changes, stat, fp)
607 changes, stat, fp)
608
608
609 def mergeone(self, repo, mergeq, head, patch, rev, diffopts):
609 def mergeone(self, repo, mergeq, head, patch, rev, diffopts):
610 # first try just applying the patch
610 # first try just applying the patch
611 (err, n) = self.apply(repo, [patch], update_status=False,
611 (err, n) = self.apply(repo, [patch], update_status=False,
612 strict=True, merge=rev)
612 strict=True, merge=rev)
613
613
614 if err == 0:
614 if err == 0:
615 return (err, n)
615 return (err, n)
616
616
617 if n is None:
617 if n is None:
618 raise util.Abort(_("apply failed for patch %s") % patch)
618 raise util.Abort(_("apply failed for patch %s") % patch)
619
619
620 self.ui.warn(_("patch didn't work out, merging %s\n") % patch)
620 self.ui.warn(_("patch didn't work out, merging %s\n") % patch)
621
621
622 # apply failed, strip away that rev and merge.
622 # apply failed, strip away that rev and merge.
623 hg.clean(repo, head)
623 hg.clean(repo, head)
624 strip(self.ui, repo, [n], update=False, backup=False)
624 strip(self.ui, repo, [n], update=False, backup=False)
625
625
626 ctx = repo[rev]
626 ctx = repo[rev]
627 ret = hg.merge(repo, rev)
627 ret = hg.merge(repo, rev)
628 if ret:
628 if ret:
629 raise util.Abort(_("update returned %d") % ret)
629 raise util.Abort(_("update returned %d") % ret)
630 n = newcommit(repo, None, ctx.description(), ctx.user(), force=True)
630 n = newcommit(repo, None, ctx.description(), ctx.user(), force=True)
631 if n is None:
631 if n is None:
632 raise util.Abort(_("repo commit failed"))
632 raise util.Abort(_("repo commit failed"))
633 try:
633 try:
634 ph = patchheader(mergeq.join(patch), self.plainmode)
634 ph = patchheader(mergeq.join(patch), self.plainmode)
635 except Exception:
635 except Exception:
636 raise util.Abort(_("unable to read %s") % patch)
636 raise util.Abort(_("unable to read %s") % patch)
637
637
638 diffopts = self.patchopts(diffopts, patch)
638 diffopts = self.patchopts(diffopts, patch)
639 patchf = self.opener(patch, "w")
639 patchf = self.opener(patch, "w")
640 comments = str(ph)
640 comments = str(ph)
641 if comments:
641 if comments:
642 patchf.write(comments)
642 patchf.write(comments)
643 self.printdiff(repo, diffopts, head, n, fp=patchf)
643 self.printdiff(repo, diffopts, head, n, fp=patchf)
644 patchf.close()
644 patchf.close()
645 self.removeundo(repo)
645 self.removeundo(repo)
646 return (0, n)
646 return (0, n)
647
647
648 def qparents(self, repo, rev=None):
648 def qparents(self, repo, rev=None):
649 """return the mq handled parent or p1
649 """return the mq handled parent or p1
650
650
651 In some case where mq get himself in being the parent of a merge the
651 In some case where mq get himself in being the parent of a merge the
652 appropriate parent may be p2.
652 appropriate parent may be p2.
653 (eg: an in progress merge started with mq disabled)
653 (eg: an in progress merge started with mq disabled)
654
654
655 If no parent are managed by mq, p1 is returned.
655 If no parent are managed by mq, p1 is returned.
656 """
656 """
657 if rev is None:
657 if rev is None:
658 (p1, p2) = repo.dirstate.parents()
658 (p1, p2) = repo.dirstate.parents()
659 if p2 == nullid:
659 if p2 == nullid:
660 return p1
660 return p1
661 if not self.applied:
661 if not self.applied:
662 return None
662 return None
663 return self.applied[-1].node
663 return self.applied[-1].node
664 p1, p2 = repo.changelog.parents(rev)
664 p1, p2 = repo.changelog.parents(rev)
665 if p2 != nullid and p2 in [x.node for x in self.applied]:
665 if p2 != nullid and p2 in [x.node for x in self.applied]:
666 return p2
666 return p2
667 return p1
667 return p1
668
668
669 def mergepatch(self, repo, mergeq, series, diffopts):
669 def mergepatch(self, repo, mergeq, series, diffopts):
670 if not self.applied:
670 if not self.applied:
671 # each of the patches merged in will have two parents. This
671 # each of the patches merged in will have two parents. This
672 # can confuse the qrefresh, qdiff, and strip code because it
672 # can confuse the qrefresh, qdiff, and strip code because it
673 # needs to know which parent is actually in the patch queue.
673 # needs to know which parent is actually in the patch queue.
674 # so, we insert a merge marker with only one parent. This way
674 # so, we insert a merge marker with only one parent. This way
675 # the first patch in the queue is never a merge patch
675 # the first patch in the queue is never a merge patch
676 #
676 #
677 pname = ".hg.patches.merge.marker"
677 pname = ".hg.patches.merge.marker"
678 n = newcommit(repo, None, '[mq]: merge marker', force=True)
678 n = newcommit(repo, None, '[mq]: merge marker', force=True)
679 self.removeundo(repo)
679 self.removeundo(repo)
680 self.applied.append(statusentry(n, pname))
680 self.applied.append(statusentry(n, pname))
681 self.applieddirty = True
681 self.applieddirty = True
682
682
683 head = self.qparents(repo)
683 head = self.qparents(repo)
684
684
685 for patch in series:
685 for patch in series:
686 patch = mergeq.lookup(patch, strict=True)
686 patch = mergeq.lookup(patch, strict=True)
687 if not patch:
687 if not patch:
688 self.ui.warn(_("patch %s does not exist\n") % patch)
688 self.ui.warn(_("patch %s does not exist\n") % patch)
689 return (1, None)
689 return (1, None)
690 pushable, reason = self.pushable(patch)
690 pushable, reason = self.pushable(patch)
691 if not pushable:
691 if not pushable:
692 self.explainpushable(patch, all_patches=True)
692 self.explainpushable(patch, all_patches=True)
693 continue
693 continue
694 info = mergeq.isapplied(patch)
694 info = mergeq.isapplied(patch)
695 if not info:
695 if not info:
696 self.ui.warn(_("patch %s is not applied\n") % patch)
696 self.ui.warn(_("patch %s is not applied\n") % patch)
697 return (1, None)
697 return (1, None)
698 rev = info[1]
698 rev = info[1]
699 err, head = self.mergeone(repo, mergeq, head, patch, rev, diffopts)
699 err, head = self.mergeone(repo, mergeq, head, patch, rev, diffopts)
700 if head:
700 if head:
701 self.applied.append(statusentry(head, patch))
701 self.applied.append(statusentry(head, patch))
702 self.applieddirty = True
702 self.applieddirty = True
703 if err:
703 if err:
704 return (err, head)
704 return (err, head)
705 self.savedirty()
705 self.savedirty()
706 return (0, head)
706 return (0, head)
707
707
708 def patch(self, repo, patchfile):
708 def patch(self, repo, patchfile):
709 '''Apply patchfile to the working directory.
709 '''Apply patchfile to the working directory.
710 patchfile: name of patch file'''
710 patchfile: name of patch file'''
711 files = set()
711 files = set()
712 try:
712 try:
713 fuzz = patchmod.patch(self.ui, repo, patchfile, strip=1,
713 fuzz = patchmod.patch(self.ui, repo, patchfile, strip=1,
714 files=files, eolmode=None)
714 files=files, eolmode=None)
715 return (True, list(files), fuzz)
715 return (True, list(files), fuzz)
716 except Exception, inst:
716 except Exception, inst:
717 self.ui.note(str(inst) + '\n')
717 self.ui.note(str(inst) + '\n')
718 if not self.ui.verbose:
718 if not self.ui.verbose:
719 self.ui.warn(_("patch failed, unable to continue (try -v)\n"))
719 self.ui.warn(_("patch failed, unable to continue (try -v)\n"))
720 self.ui.traceback()
720 self.ui.traceback()
721 return (False, list(files), False)
721 return (False, list(files), False)
722
722
723 def apply(self, repo, series, list=False, update_status=True,
723 def apply(self, repo, series, list=False, update_status=True,
724 strict=False, patchdir=None, merge=None, all_files=None,
724 strict=False, patchdir=None, merge=None, all_files=None,
725 tobackup=None, keepchanges=False):
725 tobackup=None, keepchanges=False):
726 wlock = lock = tr = None
726 wlock = lock = tr = None
727 try:
727 try:
728 wlock = repo.wlock()
728 wlock = repo.wlock()
729 lock = repo.lock()
729 lock = repo.lock()
730 tr = repo.transaction("qpush")
730 tr = repo.transaction("qpush")
731 try:
731 try:
732 ret = self._apply(repo, series, list, update_status,
732 ret = self._apply(repo, series, list, update_status,
733 strict, patchdir, merge, all_files=all_files,
733 strict, patchdir, merge, all_files=all_files,
734 tobackup=tobackup, keepchanges=keepchanges)
734 tobackup=tobackup, keepchanges=keepchanges)
735 tr.close()
735 tr.close()
736 self.savedirty()
736 self.savedirty()
737 return ret
737 return ret
738 except AbortNoCleanup:
738 except AbortNoCleanup:
739 tr.close()
739 tr.close()
740 self.savedirty()
740 self.savedirty()
741 return 2, repo.dirstate.p1()
741 return 2, repo.dirstate.p1()
742 except: # re-raises
742 except: # re-raises
743 try:
743 try:
744 tr.abort()
744 tr.abort()
745 finally:
745 finally:
746 repo.invalidate()
746 repo.invalidate()
747 repo.dirstate.invalidate()
747 repo.dirstate.invalidate()
748 self.invalidate()
748 self.invalidate()
749 raise
749 raise
750 finally:
750 finally:
751 release(tr, lock, wlock)
751 release(tr, lock, wlock)
752 self.removeundo(repo)
752 self.removeundo(repo)
753
753
754 def _apply(self, repo, series, list=False, update_status=True,
754 def _apply(self, repo, series, list=False, update_status=True,
755 strict=False, patchdir=None, merge=None, all_files=None,
755 strict=False, patchdir=None, merge=None, all_files=None,
756 tobackup=None, keepchanges=False):
756 tobackup=None, keepchanges=False):
757 """returns (error, hash)
757 """returns (error, hash)
758
758
759 error = 1 for unable to read, 2 for patch failed, 3 for patch
759 error = 1 for unable to read, 2 for patch failed, 3 for patch
760 fuzz. tobackup is None or a set of files to backup before they
760 fuzz. tobackup is None or a set of files to backup before they
761 are modified by a patch.
761 are modified by a patch.
762 """
762 """
763 # TODO unify with commands.py
763 # TODO unify with commands.py
764 if not patchdir:
764 if not patchdir:
765 patchdir = self.path
765 patchdir = self.path
766 err = 0
766 err = 0
767 n = None
767 n = None
768 for patchname in series:
768 for patchname in series:
769 pushable, reason = self.pushable(patchname)
769 pushable, reason = self.pushable(patchname)
770 if not pushable:
770 if not pushable:
771 self.explainpushable(patchname, all_patches=True)
771 self.explainpushable(patchname, all_patches=True)
772 continue
772 continue
773 self.ui.status(_("applying %s\n") % patchname)
773 self.ui.status(_("applying %s\n") % patchname)
774 pf = os.path.join(patchdir, patchname)
774 pf = os.path.join(patchdir, patchname)
775
775
776 try:
776 try:
777 ph = patchheader(self.join(patchname), self.plainmode)
777 ph = patchheader(self.join(patchname), self.plainmode)
778 except IOError:
778 except IOError:
779 self.ui.warn(_("unable to read %s\n") % patchname)
779 self.ui.warn(_("unable to read %s\n") % patchname)
780 err = 1
780 err = 1
781 break
781 break
782
782
783 message = ph.message
783 message = ph.message
784 if not message:
784 if not message:
785 # The commit message should not be translated
785 # The commit message should not be translated
786 message = "imported patch %s\n" % patchname
786 message = "imported patch %s\n" % patchname
787 else:
787 else:
788 if list:
788 if list:
789 # The commit message should not be translated
789 # The commit message should not be translated
790 message.append("\nimported patch %s" % patchname)
790 message.append("\nimported patch %s" % patchname)
791 message = '\n'.join(message)
791 message = '\n'.join(message)
792
792
793 if ph.haspatch:
793 if ph.haspatch:
794 if tobackup:
794 if tobackup:
795 touched = patchmod.changedfiles(self.ui, repo, pf)
795 touched = patchmod.changedfiles(self.ui, repo, pf)
796 touched = set(touched) & tobackup
796 touched = set(touched) & tobackup
797 if touched and keepchanges:
797 if touched and keepchanges:
798 raise AbortNoCleanup(
798 raise AbortNoCleanup(
799 _("local changes found, refresh first"))
799 _("local changes found, refresh first"))
800 self.backup(repo, touched, copy=True)
800 self.backup(repo, touched, copy=True)
801 tobackup = tobackup - touched
801 tobackup = tobackup - touched
802 (patcherr, files, fuzz) = self.patch(repo, pf)
802 (patcherr, files, fuzz) = self.patch(repo, pf)
803 if all_files is not None:
803 if all_files is not None:
804 all_files.update(files)
804 all_files.update(files)
805 patcherr = not patcherr
805 patcherr = not patcherr
806 else:
806 else:
807 self.ui.warn(_("patch %s is empty\n") % patchname)
807 self.ui.warn(_("patch %s is empty\n") % patchname)
808 patcherr, files, fuzz = 0, [], 0
808 patcherr, files, fuzz = 0, [], 0
809
809
810 if merge and files:
810 if merge and files:
811 # Mark as removed/merged and update dirstate parent info
811 # Mark as removed/merged and update dirstate parent info
812 removed = []
812 removed = []
813 merged = []
813 merged = []
814 for f in files:
814 for f in files:
815 if os.path.lexists(repo.wjoin(f)):
815 if os.path.lexists(repo.wjoin(f)):
816 merged.append(f)
816 merged.append(f)
817 else:
817 else:
818 removed.append(f)
818 removed.append(f)
819 repo.dirstate.beginparentchange()
819 repo.dirstate.beginparentchange()
820 for f in removed:
820 for f in removed:
821 repo.dirstate.remove(f)
821 repo.dirstate.remove(f)
822 for f in merged:
822 for f in merged:
823 repo.dirstate.merge(f)
823 repo.dirstate.merge(f)
824 p1, p2 = repo.dirstate.parents()
824 p1, p2 = repo.dirstate.parents()
825 repo.setparents(p1, merge)
825 repo.setparents(p1, merge)
826 repo.dirstate.endparentchange()
826 repo.dirstate.endparentchange()
827
827
828 if all_files and '.hgsubstate' in all_files:
828 if all_files and '.hgsubstate' in all_files:
829 wctx = repo[None]
829 wctx = repo[None]
830 pctx = repo['.']
830 pctx = repo['.']
831 overwrite = False
831 overwrite = False
832 mergedsubstate = subrepo.submerge(repo, pctx, wctx, wctx,
832 mergedsubstate = subrepo.submerge(repo, pctx, wctx, wctx,
833 overwrite)
833 overwrite)
834 files += mergedsubstate.keys()
834 files += mergedsubstate.keys()
835
835
836 match = scmutil.matchfiles(repo, files or [])
836 match = scmutil.matchfiles(repo, files or [])
837 oldtip = repo['tip']
837 oldtip = repo['tip']
838 n = newcommit(repo, None, message, ph.user, ph.date, match=match,
838 n = newcommit(repo, None, message, ph.user, ph.date, match=match,
839 force=True)
839 force=True)
840 if repo['tip'] == oldtip:
840 if repo['tip'] == oldtip:
841 raise util.Abort(_("qpush exactly duplicates child changeset"))
841 raise util.Abort(_("qpush exactly duplicates child changeset"))
842 if n is None:
842 if n is None:
843 raise util.Abort(_("repository commit failed"))
843 raise util.Abort(_("repository commit failed"))
844
844
845 if update_status:
845 if update_status:
846 self.applied.append(statusentry(n, patchname))
846 self.applied.append(statusentry(n, patchname))
847
847
848 if patcherr:
848 if patcherr:
849 self.ui.warn(_("patch failed, rejects left in working dir\n"))
849 self.ui.warn(_("patch failed, rejects left in working dir\n"))
850 err = 2
850 err = 2
851 break
851 break
852
852
853 if fuzz and strict:
853 if fuzz and strict:
854 self.ui.warn(_("fuzz found when applying patch, stopping\n"))
854 self.ui.warn(_("fuzz found when applying patch, stopping\n"))
855 err = 3
855 err = 3
856 break
856 break
857 return (err, n)
857 return (err, n)
858
858
859 def _cleanup(self, patches, numrevs, keep=False):
859 def _cleanup(self, patches, numrevs, keep=False):
860 if not keep:
860 if not keep:
861 r = self.qrepo()
861 r = self.qrepo()
862 if r:
862 if r:
863 r[None].forget(patches)
863 r[None].forget(patches)
864 for p in patches:
864 for p in patches:
865 try:
865 try:
866 os.unlink(self.join(p))
866 os.unlink(self.join(p))
867 except OSError, inst:
867 except OSError, inst:
868 if inst.errno != errno.ENOENT:
868 if inst.errno != errno.ENOENT:
869 raise
869 raise
870
870
871 qfinished = []
871 qfinished = []
872 if numrevs:
872 if numrevs:
873 qfinished = self.applied[:numrevs]
873 qfinished = self.applied[:numrevs]
874 del self.applied[:numrevs]
874 del self.applied[:numrevs]
875 self.applieddirty = True
875 self.applieddirty = True
876
876
877 unknown = []
877 unknown = []
878
878
879 for (i, p) in sorted([(self.findseries(p), p) for p in patches],
879 for (i, p) in sorted([(self.findseries(p), p) for p in patches],
880 reverse=True):
880 reverse=True):
881 if i is not None:
881 if i is not None:
882 del self.fullseries[i]
882 del self.fullseries[i]
883 else:
883 else:
884 unknown.append(p)
884 unknown.append(p)
885
885
886 if unknown:
886 if unknown:
887 if numrevs:
887 if numrevs:
888 rev = dict((entry.name, entry.node) for entry in qfinished)
888 rev = dict((entry.name, entry.node) for entry in qfinished)
889 for p in unknown:
889 for p in unknown:
890 msg = _('revision %s refers to unknown patches: %s\n')
890 msg = _('revision %s refers to unknown patches: %s\n')
891 self.ui.warn(msg % (short(rev[p]), p))
891 self.ui.warn(msg % (short(rev[p]), p))
892 else:
892 else:
893 msg = _('unknown patches: %s\n')
893 msg = _('unknown patches: %s\n')
894 raise util.Abort(''.join(msg % p for p in unknown))
894 raise util.Abort(''.join(msg % p for p in unknown))
895
895
896 self.parseseries()
896 self.parseseries()
897 self.seriesdirty = True
897 self.seriesdirty = True
898 return [entry.node for entry in qfinished]
898 return [entry.node for entry in qfinished]
899
899
900 def _revpatches(self, repo, revs):
900 def _revpatches(self, repo, revs):
901 firstrev = repo[self.applied[0].node].rev()
901 firstrev = repo[self.applied[0].node].rev()
902 patches = []
902 patches = []
903 for i, rev in enumerate(revs):
903 for i, rev in enumerate(revs):
904
904
905 if rev < firstrev:
905 if rev < firstrev:
906 raise util.Abort(_('revision %d is not managed') % rev)
906 raise util.Abort(_('revision %d is not managed') % rev)
907
907
908 ctx = repo[rev]
908 ctx = repo[rev]
909 base = self.applied[i].node
909 base = self.applied[i].node
910 if ctx.node() != base:
910 if ctx.node() != base:
911 msg = _('cannot delete revision %d above applied patches')
911 msg = _('cannot delete revision %d above applied patches')
912 raise util.Abort(msg % rev)
912 raise util.Abort(msg % rev)
913
913
914 patch = self.applied[i].name
914 patch = self.applied[i].name
915 for fmt in ('[mq]: %s', 'imported patch %s'):
915 for fmt in ('[mq]: %s', 'imported patch %s'):
916 if ctx.description() == fmt % patch:
916 if ctx.description() == fmt % patch:
917 msg = _('patch %s finalized without changeset message\n')
917 msg = _('patch %s finalized without changeset message\n')
918 repo.ui.status(msg % patch)
918 repo.ui.status(msg % patch)
919 break
919 break
920
920
921 patches.append(patch)
921 patches.append(patch)
922 return patches
922 return patches
923
923
924 def finish(self, repo, revs):
924 def finish(self, repo, revs):
925 # Manually trigger phase computation to ensure phasedefaults is
925 # Manually trigger phase computation to ensure phasedefaults is
926 # executed before we remove the patches.
926 # executed before we remove the patches.
927 repo._phasecache
927 repo._phasecache
928 patches = self._revpatches(repo, sorted(revs))
928 patches = self._revpatches(repo, sorted(revs))
929 qfinished = self._cleanup(patches, len(patches))
929 qfinished = self._cleanup(patches, len(patches))
930 if qfinished and repo.ui.configbool('mq', 'secret', False):
930 if qfinished and repo.ui.configbool('mq', 'secret', False):
931 # only use this logic when the secret option is added
931 # only use this logic when the secret option is added
932 oldqbase = repo[qfinished[0]]
932 oldqbase = repo[qfinished[0]]
933 tphase = repo.ui.config('phases', 'new-commit', phases.draft)
933 tphase = repo.ui.config('phases', 'new-commit', phases.draft)
934 if oldqbase.phase() > tphase and oldqbase.p1().phase() <= tphase:
934 if oldqbase.phase() > tphase and oldqbase.p1().phase() <= tphase:
935 tr = repo.transaction('qfinish')
935 tr = repo.transaction('qfinish')
936 try:
936 try:
937 phases.advanceboundary(repo, tr, tphase, qfinished)
937 phases.advanceboundary(repo, tr, tphase, qfinished)
938 tr.close()
938 tr.close()
939 finally:
939 finally:
940 tr.release()
940 tr.release()
941
941
942 def delete(self, repo, patches, opts):
942 def delete(self, repo, patches, opts):
943 if not patches and not opts.get('rev'):
943 if not patches and not opts.get('rev'):
944 raise util.Abort(_('qdelete requires at least one revision or '
944 raise util.Abort(_('qdelete requires at least one revision or '
945 'patch name'))
945 'patch name'))
946
946
947 realpatches = []
947 realpatches = []
948 for patch in patches:
948 for patch in patches:
949 patch = self.lookup(patch, strict=True)
949 patch = self.lookup(patch, strict=True)
950 info = self.isapplied(patch)
950 info = self.isapplied(patch)
951 if info:
951 if info:
952 raise util.Abort(_("cannot delete applied patch %s") % patch)
952 raise util.Abort(_("cannot delete applied patch %s") % patch)
953 if patch not in self.series:
953 if patch not in self.series:
954 raise util.Abort(_("patch %s not in series file") % patch)
954 raise util.Abort(_("patch %s not in series file") % patch)
955 if patch not in realpatches:
955 if patch not in realpatches:
956 realpatches.append(patch)
956 realpatches.append(patch)
957
957
958 numrevs = 0
958 numrevs = 0
959 if opts.get('rev'):
959 if opts.get('rev'):
960 if not self.applied:
960 if not self.applied:
961 raise util.Abort(_('no patches applied'))
961 raise util.Abort(_('no patches applied'))
962 revs = scmutil.revrange(repo, opts.get('rev'))
962 revs = scmutil.revrange(repo, opts.get('rev'))
963 if len(revs) > 1 and revs[0] > revs[1]:
963 if len(revs) > 1 and revs[0] > revs[1]:
964 revs.reverse()
964 revs.reverse()
965 revpatches = self._revpatches(repo, revs)
965 revpatches = self._revpatches(repo, revs)
966 realpatches += revpatches
966 realpatches += revpatches
967 numrevs = len(revpatches)
967 numrevs = len(revpatches)
968
968
969 self._cleanup(realpatches, numrevs, opts.get('keep'))
969 self._cleanup(realpatches, numrevs, opts.get('keep'))
970
970
971 def checktoppatch(self, repo):
971 def checktoppatch(self, repo):
972 '''check that working directory is at qtip'''
972 '''check that working directory is at qtip'''
973 if self.applied:
973 if self.applied:
974 top = self.applied[-1].node
974 top = self.applied[-1].node
975 patch = self.applied[-1].name
975 patch = self.applied[-1].name
976 if repo.dirstate.p1() != top:
976 if repo.dirstate.p1() != top:
977 raise util.Abort(_("working directory revision is not qtip"))
977 raise util.Abort(_("working directory revision is not qtip"))
978 return top, patch
978 return top, patch
979 return None, None
979 return None, None
980
980
981 def putsubstate2changes(self, substatestate, changes):
981 def putsubstate2changes(self, substatestate, changes):
982 for files in changes[:3]:
982 for files in changes[:3]:
983 if '.hgsubstate' in files:
983 if '.hgsubstate' in files:
984 return # already listed up
984 return # already listed up
985 # not yet listed up
985 # not yet listed up
986 if substatestate in 'a?':
986 if substatestate in 'a?':
987 changes[1].append('.hgsubstate')
987 changes[1].append('.hgsubstate')
988 elif substatestate in 'r':
988 elif substatestate in 'r':
989 changes[2].append('.hgsubstate')
989 changes[2].append('.hgsubstate')
990 else: # modified
990 else: # modified
991 changes[0].append('.hgsubstate')
991 changes[0].append('.hgsubstate')
992
992
993 def checklocalchanges(self, repo, force=False, refresh=True):
993 def checklocalchanges(self, repo, force=False, refresh=True):
994 excsuffix = ''
994 excsuffix = ''
995 if refresh:
995 if refresh:
996 excsuffix = ', refresh first'
996 excsuffix = ', refresh first'
997 # plain versions for i18n tool to detect them
997 # plain versions for i18n tool to detect them
998 _("local changes found, refresh first")
998 _("local changes found, refresh first")
999 _("local changed subrepos found, refresh first")
999 _("local changed subrepos found, refresh first")
1000 return checklocalchanges(repo, force, excsuffix)
1000 return checklocalchanges(repo, force, excsuffix)
1001
1001
1002 _reserved = ('series', 'status', 'guards', '.', '..')
1002 _reserved = ('series', 'status', 'guards', '.', '..')
1003 def checkreservedname(self, name):
1003 def checkreservedname(self, name):
1004 if name in self._reserved:
1004 if name in self._reserved:
1005 raise util.Abort(_('"%s" cannot be used as the name of a patch')
1005 raise util.Abort(_('"%s" cannot be used as the name of a patch')
1006 % name)
1006 % name)
1007 for prefix in ('.hg', '.mq'):
1007 for prefix in ('.hg', '.mq'):
1008 if name.startswith(prefix):
1008 if name.startswith(prefix):
1009 raise util.Abort(_('patch name cannot begin with "%s"')
1009 raise util.Abort(_('patch name cannot begin with "%s"')
1010 % prefix)
1010 % prefix)
1011 for c in ('#', ':'):
1011 for c in ('#', ':'):
1012 if c in name:
1012 if c in name:
1013 raise util.Abort(_('"%s" cannot be used in the name of a patch')
1013 raise util.Abort(_('"%s" cannot be used in the name of a patch')
1014 % c)
1014 % c)
1015
1015
1016 def checkpatchname(self, name, force=False):
1016 def checkpatchname(self, name, force=False):
1017 self.checkreservedname(name)
1017 self.checkreservedname(name)
1018 if not force and os.path.exists(self.join(name)):
1018 if not force and os.path.exists(self.join(name)):
1019 if os.path.isdir(self.join(name)):
1019 if os.path.isdir(self.join(name)):
1020 raise util.Abort(_('"%s" already exists as a directory')
1020 raise util.Abort(_('"%s" already exists as a directory')
1021 % name)
1021 % name)
1022 else:
1022 else:
1023 raise util.Abort(_('patch "%s" already exists') % name)
1023 raise util.Abort(_('patch "%s" already exists') % name)
1024
1024
1025 def checkkeepchanges(self, keepchanges, force):
1025 def checkkeepchanges(self, keepchanges, force):
1026 if force and keepchanges:
1026 if force and keepchanges:
1027 raise util.Abort(_('cannot use both --force and --keep-changes'))
1027 raise util.Abort(_('cannot use both --force and --keep-changes'))
1028
1028
1029 def new(self, repo, patchfn, *pats, **opts):
1029 def new(self, repo, patchfn, *pats, **opts):
1030 """options:
1030 """options:
1031 msg: a string or a no-argument function returning a string
1031 msg: a string or a no-argument function returning a string
1032 """
1032 """
1033 msg = opts.get('msg')
1033 msg = opts.get('msg')
1034 edit = opts.get('edit')
1034 edit = opts.get('edit')
1035 editform = opts.get('editform', 'mq.qnew')
1035 editform = opts.get('editform', 'mq.qnew')
1036 user = opts.get('user')
1036 user = opts.get('user')
1037 date = opts.get('date')
1037 date = opts.get('date')
1038 if date:
1038 if date:
1039 date = util.parsedate(date)
1039 date = util.parsedate(date)
1040 diffopts = self.diffopts({'git': opts.get('git')})
1040 diffopts = self.diffopts({'git': opts.get('git')})
1041 if opts.get('checkname', True):
1041 if opts.get('checkname', True):
1042 self.checkpatchname(patchfn)
1042 self.checkpatchname(patchfn)
1043 inclsubs = checksubstate(repo)
1043 inclsubs = checksubstate(repo)
1044 if inclsubs:
1044 if inclsubs:
1045 substatestate = repo.dirstate['.hgsubstate']
1045 substatestate = repo.dirstate['.hgsubstate']
1046 if opts.get('include') or opts.get('exclude') or pats:
1046 if opts.get('include') or opts.get('exclude') or pats:
1047 match = scmutil.match(repo[None], pats, opts)
1047 match = scmutil.match(repo[None], pats, opts)
1048 # detect missing files in pats
1048 # detect missing files in pats
1049 def badfn(f, msg):
1049 def badfn(f, msg):
1050 if f != '.hgsubstate': # .hgsubstate is auto-created
1050 if f != '.hgsubstate': # .hgsubstate is auto-created
1051 raise util.Abort('%s: %s' % (f, msg))
1051 raise util.Abort('%s: %s' % (f, msg))
1052 match.bad = badfn
1052 match.bad = badfn
1053 changes = repo.status(match=match)
1053 changes = repo.status(match=match)
1054 else:
1054 else:
1055 changes = self.checklocalchanges(repo, force=True)
1055 changes = self.checklocalchanges(repo, force=True)
1056 commitfiles = list(inclsubs)
1056 commitfiles = list(inclsubs)
1057 for files in changes[:3]:
1057 for files in changes[:3]:
1058 commitfiles.extend(files)
1058 commitfiles.extend(files)
1059 match = scmutil.matchfiles(repo, commitfiles)
1059 match = scmutil.matchfiles(repo, commitfiles)
1060 if len(repo[None].parents()) > 1:
1060 if len(repo[None].parents()) > 1:
1061 raise util.Abort(_('cannot manage merge changesets'))
1061 raise util.Abort(_('cannot manage merge changesets'))
1062 self.checktoppatch(repo)
1062 self.checktoppatch(repo)
1063 insert = self.fullseriesend()
1063 insert = self.fullseriesend()
1064 wlock = repo.wlock()
1064 wlock = repo.wlock()
1065 try:
1065 try:
1066 try:
1066 try:
1067 # if patch file write fails, abort early
1067 # if patch file write fails, abort early
1068 p = self.opener(patchfn, "w")
1068 p = self.opener(patchfn, "w")
1069 except IOError, e:
1069 except IOError, e:
1070 raise util.Abort(_('cannot write patch "%s": %s')
1070 raise util.Abort(_('cannot write patch "%s": %s')
1071 % (patchfn, e.strerror))
1071 % (patchfn, e.strerror))
1072 try:
1072 try:
1073 if self.plainmode:
1073 if self.plainmode:
1074 if user:
1074 if user:
1075 p.write("From: " + user + "\n")
1075 p.write("From: " + user + "\n")
1076 if date:
1076 if date:
1077 p.write("Date: %d %d\n" % date)
1077 p.write("Date: %d %d\n" % date)
1078 else:
1078 else:
1079 p.write("# HG changeset patch\n")
1079 p.write("# HG changeset patch\n")
1080 p.write("# Parent "
1081 + hex(repo[None].p1().node()) + "\n")
1082 if user:
1080 if user:
1083 p.write("# User " + user + "\n")
1081 p.write("# User " + user + "\n")
1084 if date:
1082 if date:
1085 p.write("# Date %s %s\n" % date)
1083 p.write("# Date %s %s\n" % date)
1084 p.write("# Parent "
1085 + hex(repo[None].p1().node()) + "\n")
1086
1086
1087 defaultmsg = "[mq]: %s" % patchfn
1087 defaultmsg = "[mq]: %s" % patchfn
1088 editor = cmdutil.getcommiteditor(editform=editform)
1088 editor = cmdutil.getcommiteditor(editform=editform)
1089 if edit:
1089 if edit:
1090 def finishdesc(desc):
1090 def finishdesc(desc):
1091 if desc.rstrip():
1091 if desc.rstrip():
1092 return desc
1092 return desc
1093 else:
1093 else:
1094 return defaultmsg
1094 return defaultmsg
1095 # i18n: this message is shown in editor with "HG: " prefix
1095 # i18n: this message is shown in editor with "HG: " prefix
1096 extramsg = _('Leave message empty to use default message.')
1096 extramsg = _('Leave message empty to use default message.')
1097 editor = cmdutil.getcommiteditor(finishdesc=finishdesc,
1097 editor = cmdutil.getcommiteditor(finishdesc=finishdesc,
1098 extramsg=extramsg,
1098 extramsg=extramsg,
1099 editform=editform)
1099 editform=editform)
1100 commitmsg = msg
1100 commitmsg = msg
1101 else:
1101 else:
1102 commitmsg = msg or defaultmsg
1102 commitmsg = msg or defaultmsg
1103
1103
1104 n = newcommit(repo, None, commitmsg, user, date, match=match,
1104 n = newcommit(repo, None, commitmsg, user, date, match=match,
1105 force=True, editor=editor)
1105 force=True, editor=editor)
1106 if n is None:
1106 if n is None:
1107 raise util.Abort(_("repo commit failed"))
1107 raise util.Abort(_("repo commit failed"))
1108 try:
1108 try:
1109 self.fullseries[insert:insert] = [patchfn]
1109 self.fullseries[insert:insert] = [patchfn]
1110 self.applied.append(statusentry(n, patchfn))
1110 self.applied.append(statusentry(n, patchfn))
1111 self.parseseries()
1111 self.parseseries()
1112 self.seriesdirty = True
1112 self.seriesdirty = True
1113 self.applieddirty = True
1113 self.applieddirty = True
1114 nctx = repo[n]
1114 nctx = repo[n]
1115 if nctx.description() != defaultmsg.rstrip():
1115 if nctx.description() != defaultmsg.rstrip():
1116 msg = nctx.description() + "\n\n"
1116 msg = nctx.description() + "\n\n"
1117 p.write(msg)
1117 p.write(msg)
1118 elif not self.plainmode or date or user:
1118 elif not self.plainmode or date or user:
1119 p.write('\n')
1119 p.write('\n')
1120 if commitfiles:
1120 if commitfiles:
1121 parent = self.qparents(repo, n)
1121 parent = self.qparents(repo, n)
1122 if inclsubs:
1122 if inclsubs:
1123 self.putsubstate2changes(substatestate, changes)
1123 self.putsubstate2changes(substatestate, changes)
1124 chunks = patchmod.diff(repo, node1=parent, node2=n,
1124 chunks = patchmod.diff(repo, node1=parent, node2=n,
1125 changes=changes, opts=diffopts)
1125 changes=changes, opts=diffopts)
1126 for chunk in chunks:
1126 for chunk in chunks:
1127 p.write(chunk)
1127 p.write(chunk)
1128 p.close()
1128 p.close()
1129 r = self.qrepo()
1129 r = self.qrepo()
1130 if r:
1130 if r:
1131 r[None].add([patchfn])
1131 r[None].add([patchfn])
1132 except: # re-raises
1132 except: # re-raises
1133 repo.rollback()
1133 repo.rollback()
1134 raise
1134 raise
1135 except Exception:
1135 except Exception:
1136 patchpath = self.join(patchfn)
1136 patchpath = self.join(patchfn)
1137 try:
1137 try:
1138 os.unlink(patchpath)
1138 os.unlink(patchpath)
1139 except OSError:
1139 except OSError:
1140 self.ui.warn(_('error unlinking %s\n') % patchpath)
1140 self.ui.warn(_('error unlinking %s\n') % patchpath)
1141 raise
1141 raise
1142 self.removeundo(repo)
1142 self.removeundo(repo)
1143 finally:
1143 finally:
1144 release(wlock)
1144 release(wlock)
1145
1145
1146 def isapplied(self, patch):
1146 def isapplied(self, patch):
1147 """returns (index, rev, patch)"""
1147 """returns (index, rev, patch)"""
1148 for i, a in enumerate(self.applied):
1148 for i, a in enumerate(self.applied):
1149 if a.name == patch:
1149 if a.name == patch:
1150 return (i, a.node, a.name)
1150 return (i, a.node, a.name)
1151 return None
1151 return None
1152
1152
1153 # if the exact patch name does not exist, we try a few
1153 # if the exact patch name does not exist, we try a few
1154 # variations. If strict is passed, we try only #1
1154 # variations. If strict is passed, we try only #1
1155 #
1155 #
1156 # 1) a number (as string) to indicate an offset in the series file
1156 # 1) a number (as string) to indicate an offset in the series file
1157 # 2) a unique substring of the patch name was given
1157 # 2) a unique substring of the patch name was given
1158 # 3) patchname[-+]num to indicate an offset in the series file
1158 # 3) patchname[-+]num to indicate an offset in the series file
1159 def lookup(self, patch, strict=False):
1159 def lookup(self, patch, strict=False):
1160 def partialname(s):
1160 def partialname(s):
1161 if s in self.series:
1161 if s in self.series:
1162 return s
1162 return s
1163 matches = [x for x in self.series if s in x]
1163 matches = [x for x in self.series if s in x]
1164 if len(matches) > 1:
1164 if len(matches) > 1:
1165 self.ui.warn(_('patch name "%s" is ambiguous:\n') % s)
1165 self.ui.warn(_('patch name "%s" is ambiguous:\n') % s)
1166 for m in matches:
1166 for m in matches:
1167 self.ui.warn(' %s\n' % m)
1167 self.ui.warn(' %s\n' % m)
1168 return None
1168 return None
1169 if matches:
1169 if matches:
1170 return matches[0]
1170 return matches[0]
1171 if self.series and self.applied:
1171 if self.series and self.applied:
1172 if s == 'qtip':
1172 if s == 'qtip':
1173 return self.series[self.seriesend(True) - 1]
1173 return self.series[self.seriesend(True) - 1]
1174 if s == 'qbase':
1174 if s == 'qbase':
1175 return self.series[0]
1175 return self.series[0]
1176 return None
1176 return None
1177
1177
1178 if patch in self.series:
1178 if patch in self.series:
1179 return patch
1179 return patch
1180
1180
1181 if not os.path.isfile(self.join(patch)):
1181 if not os.path.isfile(self.join(patch)):
1182 try:
1182 try:
1183 sno = int(patch)
1183 sno = int(patch)
1184 except (ValueError, OverflowError):
1184 except (ValueError, OverflowError):
1185 pass
1185 pass
1186 else:
1186 else:
1187 if -len(self.series) <= sno < len(self.series):
1187 if -len(self.series) <= sno < len(self.series):
1188 return self.series[sno]
1188 return self.series[sno]
1189
1189
1190 if not strict:
1190 if not strict:
1191 res = partialname(patch)
1191 res = partialname(patch)
1192 if res:
1192 if res:
1193 return res
1193 return res
1194 minus = patch.rfind('-')
1194 minus = patch.rfind('-')
1195 if minus >= 0:
1195 if minus >= 0:
1196 res = partialname(patch[:minus])
1196 res = partialname(patch[:minus])
1197 if res:
1197 if res:
1198 i = self.series.index(res)
1198 i = self.series.index(res)
1199 try:
1199 try:
1200 off = int(patch[minus + 1:] or 1)
1200 off = int(patch[minus + 1:] or 1)
1201 except (ValueError, OverflowError):
1201 except (ValueError, OverflowError):
1202 pass
1202 pass
1203 else:
1203 else:
1204 if i - off >= 0:
1204 if i - off >= 0:
1205 return self.series[i - off]
1205 return self.series[i - off]
1206 plus = patch.rfind('+')
1206 plus = patch.rfind('+')
1207 if plus >= 0:
1207 if plus >= 0:
1208 res = partialname(patch[:plus])
1208 res = partialname(patch[:plus])
1209 if res:
1209 if res:
1210 i = self.series.index(res)
1210 i = self.series.index(res)
1211 try:
1211 try:
1212 off = int(patch[plus + 1:] or 1)
1212 off = int(patch[plus + 1:] or 1)
1213 except (ValueError, OverflowError):
1213 except (ValueError, OverflowError):
1214 pass
1214 pass
1215 else:
1215 else:
1216 if i + off < len(self.series):
1216 if i + off < len(self.series):
1217 return self.series[i + off]
1217 return self.series[i + off]
1218 raise util.Abort(_("patch %s not in series") % patch)
1218 raise util.Abort(_("patch %s not in series") % patch)
1219
1219
1220 def push(self, repo, patch=None, force=False, list=False, mergeq=None,
1220 def push(self, repo, patch=None, force=False, list=False, mergeq=None,
1221 all=False, move=False, exact=False, nobackup=False,
1221 all=False, move=False, exact=False, nobackup=False,
1222 keepchanges=False):
1222 keepchanges=False):
1223 self.checkkeepchanges(keepchanges, force)
1223 self.checkkeepchanges(keepchanges, force)
1224 diffopts = self.diffopts()
1224 diffopts = self.diffopts()
1225 wlock = repo.wlock()
1225 wlock = repo.wlock()
1226 try:
1226 try:
1227 heads = []
1227 heads = []
1228 for hs in repo.branchmap().itervalues():
1228 for hs in repo.branchmap().itervalues():
1229 heads.extend(hs)
1229 heads.extend(hs)
1230 if not heads:
1230 if not heads:
1231 heads = [nullid]
1231 heads = [nullid]
1232 if repo.dirstate.p1() not in heads and not exact:
1232 if repo.dirstate.p1() not in heads and not exact:
1233 self.ui.status(_("(working directory not at a head)\n"))
1233 self.ui.status(_("(working directory not at a head)\n"))
1234
1234
1235 if not self.series:
1235 if not self.series:
1236 self.ui.warn(_('no patches in series\n'))
1236 self.ui.warn(_('no patches in series\n'))
1237 return 0
1237 return 0
1238
1238
1239 # Suppose our series file is: A B C and the current 'top'
1239 # Suppose our series file is: A B C and the current 'top'
1240 # patch is B. qpush C should be performed (moving forward)
1240 # patch is B. qpush C should be performed (moving forward)
1241 # qpush B is a NOP (no change) qpush A is an error (can't
1241 # qpush B is a NOP (no change) qpush A is an error (can't
1242 # go backwards with qpush)
1242 # go backwards with qpush)
1243 if patch:
1243 if patch:
1244 patch = self.lookup(patch)
1244 patch = self.lookup(patch)
1245 info = self.isapplied(patch)
1245 info = self.isapplied(patch)
1246 if info and info[0] >= len(self.applied) - 1:
1246 if info and info[0] >= len(self.applied) - 1:
1247 self.ui.warn(
1247 self.ui.warn(
1248 _('qpush: %s is already at the top\n') % patch)
1248 _('qpush: %s is already at the top\n') % patch)
1249 return 0
1249 return 0
1250
1250
1251 pushable, reason = self.pushable(patch)
1251 pushable, reason = self.pushable(patch)
1252 if pushable:
1252 if pushable:
1253 if self.series.index(patch) < self.seriesend():
1253 if self.series.index(patch) < self.seriesend():
1254 raise util.Abort(
1254 raise util.Abort(
1255 _("cannot push to a previous patch: %s") % patch)
1255 _("cannot push to a previous patch: %s") % patch)
1256 else:
1256 else:
1257 if reason:
1257 if reason:
1258 reason = _('guarded by %s') % reason
1258 reason = _('guarded by %s') % reason
1259 else:
1259 else:
1260 reason = _('no matching guards')
1260 reason = _('no matching guards')
1261 self.ui.warn(_("cannot push '%s' - %s\n") % (patch, reason))
1261 self.ui.warn(_("cannot push '%s' - %s\n") % (patch, reason))
1262 return 1
1262 return 1
1263 elif all:
1263 elif all:
1264 patch = self.series[-1]
1264 patch = self.series[-1]
1265 if self.isapplied(patch):
1265 if self.isapplied(patch):
1266 self.ui.warn(_('all patches are currently applied\n'))
1266 self.ui.warn(_('all patches are currently applied\n'))
1267 return 0
1267 return 0
1268
1268
1269 # Following the above example, starting at 'top' of B:
1269 # Following the above example, starting at 'top' of B:
1270 # qpush should be performed (pushes C), but a subsequent
1270 # qpush should be performed (pushes C), but a subsequent
1271 # qpush without an argument is an error (nothing to
1271 # qpush without an argument is an error (nothing to
1272 # apply). This allows a loop of "...while hg qpush..." to
1272 # apply). This allows a loop of "...while hg qpush..." to
1273 # work as it detects an error when done
1273 # work as it detects an error when done
1274 start = self.seriesend()
1274 start = self.seriesend()
1275 if start == len(self.series):
1275 if start == len(self.series):
1276 self.ui.warn(_('patch series already fully applied\n'))
1276 self.ui.warn(_('patch series already fully applied\n'))
1277 return 1
1277 return 1
1278 if not force and not keepchanges:
1278 if not force and not keepchanges:
1279 self.checklocalchanges(repo, refresh=self.applied)
1279 self.checklocalchanges(repo, refresh=self.applied)
1280
1280
1281 if exact:
1281 if exact:
1282 if keepchanges:
1282 if keepchanges:
1283 raise util.Abort(
1283 raise util.Abort(
1284 _("cannot use --exact and --keep-changes together"))
1284 _("cannot use --exact and --keep-changes together"))
1285 if move:
1285 if move:
1286 raise util.Abort(_('cannot use --exact and --move '
1286 raise util.Abort(_('cannot use --exact and --move '
1287 'together'))
1287 'together'))
1288 if self.applied:
1288 if self.applied:
1289 raise util.Abort(_('cannot push --exact with applied '
1289 raise util.Abort(_('cannot push --exact with applied '
1290 'patches'))
1290 'patches'))
1291 root = self.series[start]
1291 root = self.series[start]
1292 target = patchheader(self.join(root), self.plainmode).parent
1292 target = patchheader(self.join(root), self.plainmode).parent
1293 if not target:
1293 if not target:
1294 raise util.Abort(
1294 raise util.Abort(
1295 _("%s does not have a parent recorded") % root)
1295 _("%s does not have a parent recorded") % root)
1296 if not repo[target] == repo['.']:
1296 if not repo[target] == repo['.']:
1297 hg.update(repo, target)
1297 hg.update(repo, target)
1298
1298
1299 if move:
1299 if move:
1300 if not patch:
1300 if not patch:
1301 raise util.Abort(_("please specify the patch to move"))
1301 raise util.Abort(_("please specify the patch to move"))
1302 for fullstart, rpn in enumerate(self.fullseries):
1302 for fullstart, rpn in enumerate(self.fullseries):
1303 # strip markers for patch guards
1303 # strip markers for patch guards
1304 if self.guard_re.split(rpn, 1)[0] == self.series[start]:
1304 if self.guard_re.split(rpn, 1)[0] == self.series[start]:
1305 break
1305 break
1306 for i, rpn in enumerate(self.fullseries[fullstart:]):
1306 for i, rpn in enumerate(self.fullseries[fullstart:]):
1307 # strip markers for patch guards
1307 # strip markers for patch guards
1308 if self.guard_re.split(rpn, 1)[0] == patch:
1308 if self.guard_re.split(rpn, 1)[0] == patch:
1309 break
1309 break
1310 index = fullstart + i
1310 index = fullstart + i
1311 assert index < len(self.fullseries)
1311 assert index < len(self.fullseries)
1312 fullpatch = self.fullseries[index]
1312 fullpatch = self.fullseries[index]
1313 del self.fullseries[index]
1313 del self.fullseries[index]
1314 self.fullseries.insert(fullstart, fullpatch)
1314 self.fullseries.insert(fullstart, fullpatch)
1315 self.parseseries()
1315 self.parseseries()
1316 self.seriesdirty = True
1316 self.seriesdirty = True
1317
1317
1318 self.applieddirty = True
1318 self.applieddirty = True
1319 if start > 0:
1319 if start > 0:
1320 self.checktoppatch(repo)
1320 self.checktoppatch(repo)
1321 if not patch:
1321 if not patch:
1322 patch = self.series[start]
1322 patch = self.series[start]
1323 end = start + 1
1323 end = start + 1
1324 else:
1324 else:
1325 end = self.series.index(patch, start) + 1
1325 end = self.series.index(patch, start) + 1
1326
1326
1327 tobackup = set()
1327 tobackup = set()
1328 if (not nobackup and force) or keepchanges:
1328 if (not nobackup and force) or keepchanges:
1329 m, a, r, d = self.checklocalchanges(repo, force=True)
1329 m, a, r, d = self.checklocalchanges(repo, force=True)
1330 if keepchanges:
1330 if keepchanges:
1331 tobackup.update(m + a + r + d)
1331 tobackup.update(m + a + r + d)
1332 else:
1332 else:
1333 tobackup.update(m + a)
1333 tobackup.update(m + a)
1334
1334
1335 s = self.series[start:end]
1335 s = self.series[start:end]
1336 all_files = set()
1336 all_files = set()
1337 try:
1337 try:
1338 if mergeq:
1338 if mergeq:
1339 ret = self.mergepatch(repo, mergeq, s, diffopts)
1339 ret = self.mergepatch(repo, mergeq, s, diffopts)
1340 else:
1340 else:
1341 ret = self.apply(repo, s, list, all_files=all_files,
1341 ret = self.apply(repo, s, list, all_files=all_files,
1342 tobackup=tobackup, keepchanges=keepchanges)
1342 tobackup=tobackup, keepchanges=keepchanges)
1343 except: # re-raises
1343 except: # re-raises
1344 self.ui.warn(_('cleaning up working directory...'))
1344 self.ui.warn(_('cleaning up working directory...'))
1345 node = repo.dirstate.p1()
1345 node = repo.dirstate.p1()
1346 hg.revert(repo, node, None)
1346 hg.revert(repo, node, None)
1347 # only remove unknown files that we know we touched or
1347 # only remove unknown files that we know we touched or
1348 # created while patching
1348 # created while patching
1349 for f in all_files:
1349 for f in all_files:
1350 if f not in repo.dirstate:
1350 if f not in repo.dirstate:
1351 util.unlinkpath(repo.wjoin(f), ignoremissing=True)
1351 util.unlinkpath(repo.wjoin(f), ignoremissing=True)
1352 self.ui.warn(_('done\n'))
1352 self.ui.warn(_('done\n'))
1353 raise
1353 raise
1354
1354
1355 if not self.applied:
1355 if not self.applied:
1356 return ret[0]
1356 return ret[0]
1357 top = self.applied[-1].name
1357 top = self.applied[-1].name
1358 if ret[0] and ret[0] > 1:
1358 if ret[0] and ret[0] > 1:
1359 msg = _("errors during apply, please fix and refresh %s\n")
1359 msg = _("errors during apply, please fix and refresh %s\n")
1360 self.ui.write(msg % top)
1360 self.ui.write(msg % top)
1361 else:
1361 else:
1362 self.ui.write(_("now at: %s\n") % top)
1362 self.ui.write(_("now at: %s\n") % top)
1363 return ret[0]
1363 return ret[0]
1364
1364
1365 finally:
1365 finally:
1366 wlock.release()
1366 wlock.release()
1367
1367
1368 def pop(self, repo, patch=None, force=False, update=True, all=False,
1368 def pop(self, repo, patch=None, force=False, update=True, all=False,
1369 nobackup=False, keepchanges=False):
1369 nobackup=False, keepchanges=False):
1370 self.checkkeepchanges(keepchanges, force)
1370 self.checkkeepchanges(keepchanges, force)
1371 wlock = repo.wlock()
1371 wlock = repo.wlock()
1372 try:
1372 try:
1373 if patch:
1373 if patch:
1374 # index, rev, patch
1374 # index, rev, patch
1375 info = self.isapplied(patch)
1375 info = self.isapplied(patch)
1376 if not info:
1376 if not info:
1377 patch = self.lookup(patch)
1377 patch = self.lookup(patch)
1378 info = self.isapplied(patch)
1378 info = self.isapplied(patch)
1379 if not info:
1379 if not info:
1380 raise util.Abort(_("patch %s is not applied") % patch)
1380 raise util.Abort(_("patch %s is not applied") % patch)
1381
1381
1382 if not self.applied:
1382 if not self.applied:
1383 # Allow qpop -a to work repeatedly,
1383 # Allow qpop -a to work repeatedly,
1384 # but not qpop without an argument
1384 # but not qpop without an argument
1385 self.ui.warn(_("no patches applied\n"))
1385 self.ui.warn(_("no patches applied\n"))
1386 return not all
1386 return not all
1387
1387
1388 if all:
1388 if all:
1389 start = 0
1389 start = 0
1390 elif patch:
1390 elif patch:
1391 start = info[0] + 1
1391 start = info[0] + 1
1392 else:
1392 else:
1393 start = len(self.applied) - 1
1393 start = len(self.applied) - 1
1394
1394
1395 if start >= len(self.applied):
1395 if start >= len(self.applied):
1396 self.ui.warn(_("qpop: %s is already at the top\n") % patch)
1396 self.ui.warn(_("qpop: %s is already at the top\n") % patch)
1397 return
1397 return
1398
1398
1399 if not update:
1399 if not update:
1400 parents = repo.dirstate.parents()
1400 parents = repo.dirstate.parents()
1401 rr = [x.node for x in self.applied]
1401 rr = [x.node for x in self.applied]
1402 for p in parents:
1402 for p in parents:
1403 if p in rr:
1403 if p in rr:
1404 self.ui.warn(_("qpop: forcing dirstate update\n"))
1404 self.ui.warn(_("qpop: forcing dirstate update\n"))
1405 update = True
1405 update = True
1406 else:
1406 else:
1407 parents = [p.node() for p in repo[None].parents()]
1407 parents = [p.node() for p in repo[None].parents()]
1408 needupdate = False
1408 needupdate = False
1409 for entry in self.applied[start:]:
1409 for entry in self.applied[start:]:
1410 if entry.node in parents:
1410 if entry.node in parents:
1411 needupdate = True
1411 needupdate = True
1412 break
1412 break
1413 update = needupdate
1413 update = needupdate
1414
1414
1415 tobackup = set()
1415 tobackup = set()
1416 if update:
1416 if update:
1417 m, a, r, d = self.checklocalchanges(
1417 m, a, r, d = self.checklocalchanges(
1418 repo, force=force or keepchanges)
1418 repo, force=force or keepchanges)
1419 if force:
1419 if force:
1420 if not nobackup:
1420 if not nobackup:
1421 tobackup.update(m + a)
1421 tobackup.update(m + a)
1422 elif keepchanges:
1422 elif keepchanges:
1423 tobackup.update(m + a + r + d)
1423 tobackup.update(m + a + r + d)
1424
1424
1425 self.applieddirty = True
1425 self.applieddirty = True
1426 end = len(self.applied)
1426 end = len(self.applied)
1427 rev = self.applied[start].node
1427 rev = self.applied[start].node
1428
1428
1429 try:
1429 try:
1430 heads = repo.changelog.heads(rev)
1430 heads = repo.changelog.heads(rev)
1431 except error.LookupError:
1431 except error.LookupError:
1432 node = short(rev)
1432 node = short(rev)
1433 raise util.Abort(_('trying to pop unknown node %s') % node)
1433 raise util.Abort(_('trying to pop unknown node %s') % node)
1434
1434
1435 if heads != [self.applied[-1].node]:
1435 if heads != [self.applied[-1].node]:
1436 raise util.Abort(_("popping would remove a revision not "
1436 raise util.Abort(_("popping would remove a revision not "
1437 "managed by this patch queue"))
1437 "managed by this patch queue"))
1438 if not repo[self.applied[-1].node].mutable():
1438 if not repo[self.applied[-1].node].mutable():
1439 raise util.Abort(
1439 raise util.Abort(
1440 _("popping would remove an immutable revision"),
1440 _("popping would remove an immutable revision"),
1441 hint=_('see "hg help phases" for details'))
1441 hint=_('see "hg help phases" for details'))
1442
1442
1443 # we know there are no local changes, so we can make a simplified
1443 # we know there are no local changes, so we can make a simplified
1444 # form of hg.update.
1444 # form of hg.update.
1445 if update:
1445 if update:
1446 qp = self.qparents(repo, rev)
1446 qp = self.qparents(repo, rev)
1447 ctx = repo[qp]
1447 ctx = repo[qp]
1448 m, a, r, d = repo.status(qp, '.')[:4]
1448 m, a, r, d = repo.status(qp, '.')[:4]
1449 if d:
1449 if d:
1450 raise util.Abort(_("deletions found between repo revs"))
1450 raise util.Abort(_("deletions found between repo revs"))
1451
1451
1452 tobackup = set(a + m + r) & tobackup
1452 tobackup = set(a + m + r) & tobackup
1453 if keepchanges and tobackup:
1453 if keepchanges and tobackup:
1454 raise util.Abort(_("local changes found, refresh first"))
1454 raise util.Abort(_("local changes found, refresh first"))
1455 self.backup(repo, tobackup)
1455 self.backup(repo, tobackup)
1456 repo.dirstate.beginparentchange()
1456 repo.dirstate.beginparentchange()
1457 for f in a:
1457 for f in a:
1458 util.unlinkpath(repo.wjoin(f), ignoremissing=True)
1458 util.unlinkpath(repo.wjoin(f), ignoremissing=True)
1459 repo.dirstate.drop(f)
1459 repo.dirstate.drop(f)
1460 for f in m + r:
1460 for f in m + r:
1461 fctx = ctx[f]
1461 fctx = ctx[f]
1462 repo.wwrite(f, fctx.data(), fctx.flags())
1462 repo.wwrite(f, fctx.data(), fctx.flags())
1463 repo.dirstate.normal(f)
1463 repo.dirstate.normal(f)
1464 repo.setparents(qp, nullid)
1464 repo.setparents(qp, nullid)
1465 repo.dirstate.endparentchange()
1465 repo.dirstate.endparentchange()
1466 for patch in reversed(self.applied[start:end]):
1466 for patch in reversed(self.applied[start:end]):
1467 self.ui.status(_("popping %s\n") % patch.name)
1467 self.ui.status(_("popping %s\n") % patch.name)
1468 del self.applied[start:end]
1468 del self.applied[start:end]
1469 strip(self.ui, repo, [rev], update=False, backup=False)
1469 strip(self.ui, repo, [rev], update=False, backup=False)
1470 for s, state in repo['.'].substate.items():
1470 for s, state in repo['.'].substate.items():
1471 repo['.'].sub(s).get(state)
1471 repo['.'].sub(s).get(state)
1472 if self.applied:
1472 if self.applied:
1473 self.ui.write(_("now at: %s\n") % self.applied[-1].name)
1473 self.ui.write(_("now at: %s\n") % self.applied[-1].name)
1474 else:
1474 else:
1475 self.ui.write(_("patch queue now empty\n"))
1475 self.ui.write(_("patch queue now empty\n"))
1476 finally:
1476 finally:
1477 wlock.release()
1477 wlock.release()
1478
1478
1479 def diff(self, repo, pats, opts):
1479 def diff(self, repo, pats, opts):
1480 top, patch = self.checktoppatch(repo)
1480 top, patch = self.checktoppatch(repo)
1481 if not top:
1481 if not top:
1482 self.ui.write(_("no patches applied\n"))
1482 self.ui.write(_("no patches applied\n"))
1483 return
1483 return
1484 qp = self.qparents(repo, top)
1484 qp = self.qparents(repo, top)
1485 if opts.get('reverse'):
1485 if opts.get('reverse'):
1486 node1, node2 = None, qp
1486 node1, node2 = None, qp
1487 else:
1487 else:
1488 node1, node2 = qp, None
1488 node1, node2 = qp, None
1489 diffopts = self.diffopts(opts, patch)
1489 diffopts = self.diffopts(opts, patch)
1490 self.printdiff(repo, diffopts, node1, node2, files=pats, opts=opts)
1490 self.printdiff(repo, diffopts, node1, node2, files=pats, opts=opts)
1491
1491
1492 def refresh(self, repo, pats=None, **opts):
1492 def refresh(self, repo, pats=None, **opts):
1493 if not self.applied:
1493 if not self.applied:
1494 self.ui.write(_("no patches applied\n"))
1494 self.ui.write(_("no patches applied\n"))
1495 return 1
1495 return 1
1496 msg = opts.get('msg', '').rstrip()
1496 msg = opts.get('msg', '').rstrip()
1497 edit = opts.get('edit')
1497 edit = opts.get('edit')
1498 editform = opts.get('editform', 'mq.qrefresh')
1498 editform = opts.get('editform', 'mq.qrefresh')
1499 newuser = opts.get('user')
1499 newuser = opts.get('user')
1500 newdate = opts.get('date')
1500 newdate = opts.get('date')
1501 if newdate:
1501 if newdate:
1502 newdate = '%d %d' % util.parsedate(newdate)
1502 newdate = '%d %d' % util.parsedate(newdate)
1503 wlock = repo.wlock()
1503 wlock = repo.wlock()
1504
1504
1505 try:
1505 try:
1506 self.checktoppatch(repo)
1506 self.checktoppatch(repo)
1507 (top, patchfn) = (self.applied[-1].node, self.applied[-1].name)
1507 (top, patchfn) = (self.applied[-1].node, self.applied[-1].name)
1508 if repo.changelog.heads(top) != [top]:
1508 if repo.changelog.heads(top) != [top]:
1509 raise util.Abort(_("cannot refresh a revision with children"))
1509 raise util.Abort(_("cannot refresh a revision with children"))
1510 if not repo[top].mutable():
1510 if not repo[top].mutable():
1511 raise util.Abort(_("cannot refresh immutable revision"),
1511 raise util.Abort(_("cannot refresh immutable revision"),
1512 hint=_('see "hg help phases" for details'))
1512 hint=_('see "hg help phases" for details'))
1513
1513
1514 cparents = repo.changelog.parents(top)
1514 cparents = repo.changelog.parents(top)
1515 patchparent = self.qparents(repo, top)
1515 patchparent = self.qparents(repo, top)
1516
1516
1517 inclsubs = checksubstate(repo, hex(patchparent))
1517 inclsubs = checksubstate(repo, hex(patchparent))
1518 if inclsubs:
1518 if inclsubs:
1519 substatestate = repo.dirstate['.hgsubstate']
1519 substatestate = repo.dirstate['.hgsubstate']
1520
1520
1521 ph = patchheader(self.join(patchfn), self.plainmode)
1521 ph = patchheader(self.join(patchfn), self.plainmode)
1522 diffopts = self.diffopts({'git': opts.get('git')}, patchfn)
1522 diffopts = self.diffopts({'git': opts.get('git')}, patchfn)
1523 if newuser:
1523 if newuser:
1524 ph.setuser(newuser)
1524 ph.setuser(newuser)
1525 if newdate:
1525 if newdate:
1526 ph.setdate(newdate)
1526 ph.setdate(newdate)
1527 ph.setparent(hex(patchparent))
1527 ph.setparent(hex(patchparent))
1528
1528
1529 # only commit new patch when write is complete
1529 # only commit new patch when write is complete
1530 patchf = self.opener(patchfn, 'w', atomictemp=True)
1530 patchf = self.opener(patchfn, 'w', atomictemp=True)
1531
1531
1532 # update the dirstate in place, strip off the qtip commit
1532 # update the dirstate in place, strip off the qtip commit
1533 # and then commit.
1533 # and then commit.
1534 #
1534 #
1535 # this should really read:
1535 # this should really read:
1536 # mm, dd, aa = repo.status(top, patchparent)[:3]
1536 # mm, dd, aa = repo.status(top, patchparent)[:3]
1537 # but we do it backwards to take advantage of manifest/changelog
1537 # but we do it backwards to take advantage of manifest/changelog
1538 # caching against the next repo.status call
1538 # caching against the next repo.status call
1539 mm, aa, dd = repo.status(patchparent, top)[:3]
1539 mm, aa, dd = repo.status(patchparent, top)[:3]
1540 changes = repo.changelog.read(top)
1540 changes = repo.changelog.read(top)
1541 man = repo.manifest.read(changes[0])
1541 man = repo.manifest.read(changes[0])
1542 aaa = aa[:]
1542 aaa = aa[:]
1543 matchfn = scmutil.match(repo[None], pats, opts)
1543 matchfn = scmutil.match(repo[None], pats, opts)
1544 # in short mode, we only diff the files included in the
1544 # in short mode, we only diff the files included in the
1545 # patch already plus specified files
1545 # patch already plus specified files
1546 if opts.get('short'):
1546 if opts.get('short'):
1547 # if amending a patch, we start with existing
1547 # if amending a patch, we start with existing
1548 # files plus specified files - unfiltered
1548 # files plus specified files - unfiltered
1549 match = scmutil.matchfiles(repo, mm + aa + dd + matchfn.files())
1549 match = scmutil.matchfiles(repo, mm + aa + dd + matchfn.files())
1550 # filter with include/exclude options
1550 # filter with include/exclude options
1551 matchfn = scmutil.match(repo[None], opts=opts)
1551 matchfn = scmutil.match(repo[None], opts=opts)
1552 else:
1552 else:
1553 match = scmutil.matchall(repo)
1553 match = scmutil.matchall(repo)
1554 m, a, r, d = repo.status(match=match)[:4]
1554 m, a, r, d = repo.status(match=match)[:4]
1555 mm = set(mm)
1555 mm = set(mm)
1556 aa = set(aa)
1556 aa = set(aa)
1557 dd = set(dd)
1557 dd = set(dd)
1558
1558
1559 # we might end up with files that were added between
1559 # we might end up with files that were added between
1560 # qtip and the dirstate parent, but then changed in the
1560 # qtip and the dirstate parent, but then changed in the
1561 # local dirstate. in this case, we want them to only
1561 # local dirstate. in this case, we want them to only
1562 # show up in the added section
1562 # show up in the added section
1563 for x in m:
1563 for x in m:
1564 if x not in aa:
1564 if x not in aa:
1565 mm.add(x)
1565 mm.add(x)
1566 # we might end up with files added by the local dirstate that
1566 # we might end up with files added by the local dirstate that
1567 # were deleted by the patch. In this case, they should only
1567 # were deleted by the patch. In this case, they should only
1568 # show up in the changed section.
1568 # show up in the changed section.
1569 for x in a:
1569 for x in a:
1570 if x in dd:
1570 if x in dd:
1571 dd.remove(x)
1571 dd.remove(x)
1572 mm.add(x)
1572 mm.add(x)
1573 else:
1573 else:
1574 aa.add(x)
1574 aa.add(x)
1575 # make sure any files deleted in the local dirstate
1575 # make sure any files deleted in the local dirstate
1576 # are not in the add or change column of the patch
1576 # are not in the add or change column of the patch
1577 forget = []
1577 forget = []
1578 for x in d + r:
1578 for x in d + r:
1579 if x in aa:
1579 if x in aa:
1580 aa.remove(x)
1580 aa.remove(x)
1581 forget.append(x)
1581 forget.append(x)
1582 continue
1582 continue
1583 else:
1583 else:
1584 mm.discard(x)
1584 mm.discard(x)
1585 dd.add(x)
1585 dd.add(x)
1586
1586
1587 m = list(mm)
1587 m = list(mm)
1588 r = list(dd)
1588 r = list(dd)
1589 a = list(aa)
1589 a = list(aa)
1590
1590
1591 # create 'match' that includes the files to be recommitted.
1591 # create 'match' that includes the files to be recommitted.
1592 # apply matchfn via repo.status to ensure correct case handling.
1592 # apply matchfn via repo.status to ensure correct case handling.
1593 cm, ca, cr, cd = repo.status(patchparent, match=matchfn)[:4]
1593 cm, ca, cr, cd = repo.status(patchparent, match=matchfn)[:4]
1594 allmatches = set(cm + ca + cr + cd)
1594 allmatches = set(cm + ca + cr + cd)
1595 refreshchanges = [x.intersection(allmatches) for x in (mm, aa, dd)]
1595 refreshchanges = [x.intersection(allmatches) for x in (mm, aa, dd)]
1596
1596
1597 files = set(inclsubs)
1597 files = set(inclsubs)
1598 for x in refreshchanges:
1598 for x in refreshchanges:
1599 files.update(x)
1599 files.update(x)
1600 match = scmutil.matchfiles(repo, files)
1600 match = scmutil.matchfiles(repo, files)
1601
1601
1602 bmlist = repo[top].bookmarks()
1602 bmlist = repo[top].bookmarks()
1603
1603
1604 try:
1604 try:
1605 repo.dirstate.beginparentchange()
1605 repo.dirstate.beginparentchange()
1606 if diffopts.git or diffopts.upgrade:
1606 if diffopts.git or diffopts.upgrade:
1607 copies = {}
1607 copies = {}
1608 for dst in a:
1608 for dst in a:
1609 src = repo.dirstate.copied(dst)
1609 src = repo.dirstate.copied(dst)
1610 # during qfold, the source file for copies may
1610 # during qfold, the source file for copies may
1611 # be removed. Treat this as a simple add.
1611 # be removed. Treat this as a simple add.
1612 if src is not None and src in repo.dirstate:
1612 if src is not None and src in repo.dirstate:
1613 copies.setdefault(src, []).append(dst)
1613 copies.setdefault(src, []).append(dst)
1614 repo.dirstate.add(dst)
1614 repo.dirstate.add(dst)
1615 # remember the copies between patchparent and qtip
1615 # remember the copies between patchparent and qtip
1616 for dst in aaa:
1616 for dst in aaa:
1617 f = repo.file(dst)
1617 f = repo.file(dst)
1618 src = f.renamed(man[dst])
1618 src = f.renamed(man[dst])
1619 if src:
1619 if src:
1620 copies.setdefault(src[0], []).extend(
1620 copies.setdefault(src[0], []).extend(
1621 copies.get(dst, []))
1621 copies.get(dst, []))
1622 if dst in a:
1622 if dst in a:
1623 copies[src[0]].append(dst)
1623 copies[src[0]].append(dst)
1624 # we can't copy a file created by the patch itself
1624 # we can't copy a file created by the patch itself
1625 if dst in copies:
1625 if dst in copies:
1626 del copies[dst]
1626 del copies[dst]
1627 for src, dsts in copies.iteritems():
1627 for src, dsts in copies.iteritems():
1628 for dst in dsts:
1628 for dst in dsts:
1629 repo.dirstate.copy(src, dst)
1629 repo.dirstate.copy(src, dst)
1630 else:
1630 else:
1631 for dst in a:
1631 for dst in a:
1632 repo.dirstate.add(dst)
1632 repo.dirstate.add(dst)
1633 # Drop useless copy information
1633 # Drop useless copy information
1634 for f in list(repo.dirstate.copies()):
1634 for f in list(repo.dirstate.copies()):
1635 repo.dirstate.copy(None, f)
1635 repo.dirstate.copy(None, f)
1636 for f in r:
1636 for f in r:
1637 repo.dirstate.remove(f)
1637 repo.dirstate.remove(f)
1638 # if the patch excludes a modified file, mark that
1638 # if the patch excludes a modified file, mark that
1639 # file with mtime=0 so status can see it.
1639 # file with mtime=0 so status can see it.
1640 mm = []
1640 mm = []
1641 for i in xrange(len(m) - 1, -1, -1):
1641 for i in xrange(len(m) - 1, -1, -1):
1642 if not matchfn(m[i]):
1642 if not matchfn(m[i]):
1643 mm.append(m[i])
1643 mm.append(m[i])
1644 del m[i]
1644 del m[i]
1645 for f in m:
1645 for f in m:
1646 repo.dirstate.normal(f)
1646 repo.dirstate.normal(f)
1647 for f in mm:
1647 for f in mm:
1648 repo.dirstate.normallookup(f)
1648 repo.dirstate.normallookup(f)
1649 for f in forget:
1649 for f in forget:
1650 repo.dirstate.drop(f)
1650 repo.dirstate.drop(f)
1651
1651
1652 user = ph.user or changes[1]
1652 user = ph.user or changes[1]
1653
1653
1654 oldphase = repo[top].phase()
1654 oldphase = repo[top].phase()
1655
1655
1656 # assumes strip can roll itself back if interrupted
1656 # assumes strip can roll itself back if interrupted
1657 repo.setparents(*cparents)
1657 repo.setparents(*cparents)
1658 repo.dirstate.endparentchange()
1658 repo.dirstate.endparentchange()
1659 self.applied.pop()
1659 self.applied.pop()
1660 self.applieddirty = True
1660 self.applieddirty = True
1661 strip(self.ui, repo, [top], update=False, backup=False)
1661 strip(self.ui, repo, [top], update=False, backup=False)
1662 except: # re-raises
1662 except: # re-raises
1663 repo.dirstate.invalidate()
1663 repo.dirstate.invalidate()
1664 raise
1664 raise
1665
1665
1666 try:
1666 try:
1667 # might be nice to attempt to roll back strip after this
1667 # might be nice to attempt to roll back strip after this
1668
1668
1669 defaultmsg = "[mq]: %s" % patchfn
1669 defaultmsg = "[mq]: %s" % patchfn
1670 editor = cmdutil.getcommiteditor(editform=editform)
1670 editor = cmdutil.getcommiteditor(editform=editform)
1671 if edit:
1671 if edit:
1672 def finishdesc(desc):
1672 def finishdesc(desc):
1673 if desc.rstrip():
1673 if desc.rstrip():
1674 ph.setmessage(desc)
1674 ph.setmessage(desc)
1675 return desc
1675 return desc
1676 return defaultmsg
1676 return defaultmsg
1677 # i18n: this message is shown in editor with "HG: " prefix
1677 # i18n: this message is shown in editor with "HG: " prefix
1678 extramsg = _('Leave message empty to use default message.')
1678 extramsg = _('Leave message empty to use default message.')
1679 editor = cmdutil.getcommiteditor(finishdesc=finishdesc,
1679 editor = cmdutil.getcommiteditor(finishdesc=finishdesc,
1680 extramsg=extramsg,
1680 extramsg=extramsg,
1681 editform=editform)
1681 editform=editform)
1682 message = msg or "\n".join(ph.message)
1682 message = msg or "\n".join(ph.message)
1683 elif not msg:
1683 elif not msg:
1684 if not ph.message:
1684 if not ph.message:
1685 message = defaultmsg
1685 message = defaultmsg
1686 else:
1686 else:
1687 message = "\n".join(ph.message)
1687 message = "\n".join(ph.message)
1688 else:
1688 else:
1689 message = msg
1689 message = msg
1690 ph.setmessage(msg)
1690 ph.setmessage(msg)
1691
1691
1692 # Ensure we create a new changeset in the same phase than
1692 # Ensure we create a new changeset in the same phase than
1693 # the old one.
1693 # the old one.
1694 n = newcommit(repo, oldphase, message, user, ph.date,
1694 n = newcommit(repo, oldphase, message, user, ph.date,
1695 match=match, force=True, editor=editor)
1695 match=match, force=True, editor=editor)
1696 # only write patch after a successful commit
1696 # only write patch after a successful commit
1697 c = [list(x) for x in refreshchanges]
1697 c = [list(x) for x in refreshchanges]
1698 if inclsubs:
1698 if inclsubs:
1699 self.putsubstate2changes(substatestate, c)
1699 self.putsubstate2changes(substatestate, c)
1700 chunks = patchmod.diff(repo, patchparent,
1700 chunks = patchmod.diff(repo, patchparent,
1701 changes=c, opts=diffopts)
1701 changes=c, opts=diffopts)
1702 comments = str(ph)
1702 comments = str(ph)
1703 if comments:
1703 if comments:
1704 patchf.write(comments)
1704 patchf.write(comments)
1705 for chunk in chunks:
1705 for chunk in chunks:
1706 patchf.write(chunk)
1706 patchf.write(chunk)
1707 patchf.close()
1707 patchf.close()
1708
1708
1709 marks = repo._bookmarks
1709 marks = repo._bookmarks
1710 for bm in bmlist:
1710 for bm in bmlist:
1711 marks[bm] = n
1711 marks[bm] = n
1712 marks.write()
1712 marks.write()
1713
1713
1714 self.applied.append(statusentry(n, patchfn))
1714 self.applied.append(statusentry(n, patchfn))
1715 except: # re-raises
1715 except: # re-raises
1716 ctx = repo[cparents[0]]
1716 ctx = repo[cparents[0]]
1717 repo.dirstate.rebuild(ctx.node(), ctx.manifest())
1717 repo.dirstate.rebuild(ctx.node(), ctx.manifest())
1718 self.savedirty()
1718 self.savedirty()
1719 self.ui.warn(_('refresh interrupted while patch was popped! '
1719 self.ui.warn(_('refresh interrupted while patch was popped! '
1720 '(revert --all, qpush to recover)\n'))
1720 '(revert --all, qpush to recover)\n'))
1721 raise
1721 raise
1722 finally:
1722 finally:
1723 wlock.release()
1723 wlock.release()
1724 self.removeundo(repo)
1724 self.removeundo(repo)
1725
1725
1726 def init(self, repo, create=False):
1726 def init(self, repo, create=False):
1727 if not create and os.path.isdir(self.path):
1727 if not create and os.path.isdir(self.path):
1728 raise util.Abort(_("patch queue directory already exists"))
1728 raise util.Abort(_("patch queue directory already exists"))
1729 try:
1729 try:
1730 os.mkdir(self.path)
1730 os.mkdir(self.path)
1731 except OSError, inst:
1731 except OSError, inst:
1732 if inst.errno != errno.EEXIST or not create:
1732 if inst.errno != errno.EEXIST or not create:
1733 raise
1733 raise
1734 if create:
1734 if create:
1735 return self.qrepo(create=True)
1735 return self.qrepo(create=True)
1736
1736
1737 def unapplied(self, repo, patch=None):
1737 def unapplied(self, repo, patch=None):
1738 if patch and patch not in self.series:
1738 if patch and patch not in self.series:
1739 raise util.Abort(_("patch %s is not in series file") % patch)
1739 raise util.Abort(_("patch %s is not in series file") % patch)
1740 if not patch:
1740 if not patch:
1741 start = self.seriesend()
1741 start = self.seriesend()
1742 else:
1742 else:
1743 start = self.series.index(patch) + 1
1743 start = self.series.index(patch) + 1
1744 unapplied = []
1744 unapplied = []
1745 for i in xrange(start, len(self.series)):
1745 for i in xrange(start, len(self.series)):
1746 pushable, reason = self.pushable(i)
1746 pushable, reason = self.pushable(i)
1747 if pushable:
1747 if pushable:
1748 unapplied.append((i, self.series[i]))
1748 unapplied.append((i, self.series[i]))
1749 self.explainpushable(i)
1749 self.explainpushable(i)
1750 return unapplied
1750 return unapplied
1751
1751
1752 def qseries(self, repo, missing=None, start=0, length=None, status=None,
1752 def qseries(self, repo, missing=None, start=0, length=None, status=None,
1753 summary=False):
1753 summary=False):
1754 def displayname(pfx, patchname, state):
1754 def displayname(pfx, patchname, state):
1755 if pfx:
1755 if pfx:
1756 self.ui.write(pfx)
1756 self.ui.write(pfx)
1757 if summary:
1757 if summary:
1758 ph = patchheader(self.join(patchname), self.plainmode)
1758 ph = patchheader(self.join(patchname), self.plainmode)
1759 msg = ph.message and ph.message[0] or ''
1759 msg = ph.message and ph.message[0] or ''
1760 if self.ui.formatted():
1760 if self.ui.formatted():
1761 width = self.ui.termwidth() - len(pfx) - len(patchname) - 2
1761 width = self.ui.termwidth() - len(pfx) - len(patchname) - 2
1762 if width > 0:
1762 if width > 0:
1763 msg = util.ellipsis(msg, width)
1763 msg = util.ellipsis(msg, width)
1764 else:
1764 else:
1765 msg = ''
1765 msg = ''
1766 self.ui.write(patchname, label='qseries.' + state)
1766 self.ui.write(patchname, label='qseries.' + state)
1767 self.ui.write(': ')
1767 self.ui.write(': ')
1768 self.ui.write(msg, label='qseries.message.' + state)
1768 self.ui.write(msg, label='qseries.message.' + state)
1769 else:
1769 else:
1770 self.ui.write(patchname, label='qseries.' + state)
1770 self.ui.write(patchname, label='qseries.' + state)
1771 self.ui.write('\n')
1771 self.ui.write('\n')
1772
1772
1773 applied = set([p.name for p in self.applied])
1773 applied = set([p.name for p in self.applied])
1774 if length is None:
1774 if length is None:
1775 length = len(self.series) - start
1775 length = len(self.series) - start
1776 if not missing:
1776 if not missing:
1777 if self.ui.verbose:
1777 if self.ui.verbose:
1778 idxwidth = len(str(start + length - 1))
1778 idxwidth = len(str(start + length - 1))
1779 for i in xrange(start, start + length):
1779 for i in xrange(start, start + length):
1780 patch = self.series[i]
1780 patch = self.series[i]
1781 if patch in applied:
1781 if patch in applied:
1782 char, state = 'A', 'applied'
1782 char, state = 'A', 'applied'
1783 elif self.pushable(i)[0]:
1783 elif self.pushable(i)[0]:
1784 char, state = 'U', 'unapplied'
1784 char, state = 'U', 'unapplied'
1785 else:
1785 else:
1786 char, state = 'G', 'guarded'
1786 char, state = 'G', 'guarded'
1787 pfx = ''
1787 pfx = ''
1788 if self.ui.verbose:
1788 if self.ui.verbose:
1789 pfx = '%*d %s ' % (idxwidth, i, char)
1789 pfx = '%*d %s ' % (idxwidth, i, char)
1790 elif status and status != char:
1790 elif status and status != char:
1791 continue
1791 continue
1792 displayname(pfx, patch, state)
1792 displayname(pfx, patch, state)
1793 else:
1793 else:
1794 msng_list = []
1794 msng_list = []
1795 for root, dirs, files in os.walk(self.path):
1795 for root, dirs, files in os.walk(self.path):
1796 d = root[len(self.path) + 1:]
1796 d = root[len(self.path) + 1:]
1797 for f in files:
1797 for f in files:
1798 fl = os.path.join(d, f)
1798 fl = os.path.join(d, f)
1799 if (fl not in self.series and
1799 if (fl not in self.series and
1800 fl not in (self.statuspath, self.seriespath,
1800 fl not in (self.statuspath, self.seriespath,
1801 self.guardspath)
1801 self.guardspath)
1802 and not fl.startswith('.')):
1802 and not fl.startswith('.')):
1803 msng_list.append(fl)
1803 msng_list.append(fl)
1804 for x in sorted(msng_list):
1804 for x in sorted(msng_list):
1805 pfx = self.ui.verbose and ('D ') or ''
1805 pfx = self.ui.verbose and ('D ') or ''
1806 displayname(pfx, x, 'missing')
1806 displayname(pfx, x, 'missing')
1807
1807
1808 def issaveline(self, l):
1808 def issaveline(self, l):
1809 if l.name == '.hg.patches.save.line':
1809 if l.name == '.hg.patches.save.line':
1810 return True
1810 return True
1811
1811
1812 def qrepo(self, create=False):
1812 def qrepo(self, create=False):
1813 ui = self.baseui.copy()
1813 ui = self.baseui.copy()
1814 if create or os.path.isdir(self.join(".hg")):
1814 if create or os.path.isdir(self.join(".hg")):
1815 return hg.repository(ui, path=self.path, create=create)
1815 return hg.repository(ui, path=self.path, create=create)
1816
1816
1817 def restore(self, repo, rev, delete=None, qupdate=None):
1817 def restore(self, repo, rev, delete=None, qupdate=None):
1818 desc = repo[rev].description().strip()
1818 desc = repo[rev].description().strip()
1819 lines = desc.splitlines()
1819 lines = desc.splitlines()
1820 i = 0
1820 i = 0
1821 datastart = None
1821 datastart = None
1822 series = []
1822 series = []
1823 applied = []
1823 applied = []
1824 qpp = None
1824 qpp = None
1825 for i, line in enumerate(lines):
1825 for i, line in enumerate(lines):
1826 if line == 'Patch Data:':
1826 if line == 'Patch Data:':
1827 datastart = i + 1
1827 datastart = i + 1
1828 elif line.startswith('Dirstate:'):
1828 elif line.startswith('Dirstate:'):
1829 l = line.rstrip()
1829 l = line.rstrip()
1830 l = l[10:].split(' ')
1830 l = l[10:].split(' ')
1831 qpp = [bin(x) for x in l]
1831 qpp = [bin(x) for x in l]
1832 elif datastart is not None:
1832 elif datastart is not None:
1833 l = line.rstrip()
1833 l = line.rstrip()
1834 n, name = l.split(':', 1)
1834 n, name = l.split(':', 1)
1835 if n:
1835 if n:
1836 applied.append(statusentry(bin(n), name))
1836 applied.append(statusentry(bin(n), name))
1837 else:
1837 else:
1838 series.append(l)
1838 series.append(l)
1839 if datastart is None:
1839 if datastart is None:
1840 self.ui.warn(_("no saved patch data found\n"))
1840 self.ui.warn(_("no saved patch data found\n"))
1841 return 1
1841 return 1
1842 self.ui.warn(_("restoring status: %s\n") % lines[0])
1842 self.ui.warn(_("restoring status: %s\n") % lines[0])
1843 self.fullseries = series
1843 self.fullseries = series
1844 self.applied = applied
1844 self.applied = applied
1845 self.parseseries()
1845 self.parseseries()
1846 self.seriesdirty = True
1846 self.seriesdirty = True
1847 self.applieddirty = True
1847 self.applieddirty = True
1848 heads = repo.changelog.heads()
1848 heads = repo.changelog.heads()
1849 if delete:
1849 if delete:
1850 if rev not in heads:
1850 if rev not in heads:
1851 self.ui.warn(_("save entry has children, leaving it alone\n"))
1851 self.ui.warn(_("save entry has children, leaving it alone\n"))
1852 else:
1852 else:
1853 self.ui.warn(_("removing save entry %s\n") % short(rev))
1853 self.ui.warn(_("removing save entry %s\n") % short(rev))
1854 pp = repo.dirstate.parents()
1854 pp = repo.dirstate.parents()
1855 if rev in pp:
1855 if rev in pp:
1856 update = True
1856 update = True
1857 else:
1857 else:
1858 update = False
1858 update = False
1859 strip(self.ui, repo, [rev], update=update, backup=False)
1859 strip(self.ui, repo, [rev], update=update, backup=False)
1860 if qpp:
1860 if qpp:
1861 self.ui.warn(_("saved queue repository parents: %s %s\n") %
1861 self.ui.warn(_("saved queue repository parents: %s %s\n") %
1862 (short(qpp[0]), short(qpp[1])))
1862 (short(qpp[0]), short(qpp[1])))
1863 if qupdate:
1863 if qupdate:
1864 self.ui.status(_("updating queue directory\n"))
1864 self.ui.status(_("updating queue directory\n"))
1865 r = self.qrepo()
1865 r = self.qrepo()
1866 if not r:
1866 if not r:
1867 self.ui.warn(_("unable to load queue repository\n"))
1867 self.ui.warn(_("unable to load queue repository\n"))
1868 return 1
1868 return 1
1869 hg.clean(r, qpp[0])
1869 hg.clean(r, qpp[0])
1870
1870
1871 def save(self, repo, msg=None):
1871 def save(self, repo, msg=None):
1872 if not self.applied:
1872 if not self.applied:
1873 self.ui.warn(_("save: no patches applied, exiting\n"))
1873 self.ui.warn(_("save: no patches applied, exiting\n"))
1874 return 1
1874 return 1
1875 if self.issaveline(self.applied[-1]):
1875 if self.issaveline(self.applied[-1]):
1876 self.ui.warn(_("status is already saved\n"))
1876 self.ui.warn(_("status is already saved\n"))
1877 return 1
1877 return 1
1878
1878
1879 if not msg:
1879 if not msg:
1880 msg = _("hg patches saved state")
1880 msg = _("hg patches saved state")
1881 else:
1881 else:
1882 msg = "hg patches: " + msg.rstrip('\r\n')
1882 msg = "hg patches: " + msg.rstrip('\r\n')
1883 r = self.qrepo()
1883 r = self.qrepo()
1884 if r:
1884 if r:
1885 pp = r.dirstate.parents()
1885 pp = r.dirstate.parents()
1886 msg += "\nDirstate: %s %s" % (hex(pp[0]), hex(pp[1]))
1886 msg += "\nDirstate: %s %s" % (hex(pp[0]), hex(pp[1]))
1887 msg += "\n\nPatch Data:\n"
1887 msg += "\n\nPatch Data:\n"
1888 msg += ''.join('%s\n' % x for x in self.applied)
1888 msg += ''.join('%s\n' % x for x in self.applied)
1889 msg += ''.join(':%s\n' % x for x in self.fullseries)
1889 msg += ''.join(':%s\n' % x for x in self.fullseries)
1890 n = repo.commit(msg, force=True)
1890 n = repo.commit(msg, force=True)
1891 if not n:
1891 if not n:
1892 self.ui.warn(_("repo commit failed\n"))
1892 self.ui.warn(_("repo commit failed\n"))
1893 return 1
1893 return 1
1894 self.applied.append(statusentry(n, '.hg.patches.save.line'))
1894 self.applied.append(statusentry(n, '.hg.patches.save.line'))
1895 self.applieddirty = True
1895 self.applieddirty = True
1896 self.removeundo(repo)
1896 self.removeundo(repo)
1897
1897
1898 def fullseriesend(self):
1898 def fullseriesend(self):
1899 if self.applied:
1899 if self.applied:
1900 p = self.applied[-1].name
1900 p = self.applied[-1].name
1901 end = self.findseries(p)
1901 end = self.findseries(p)
1902 if end is None:
1902 if end is None:
1903 return len(self.fullseries)
1903 return len(self.fullseries)
1904 return end + 1
1904 return end + 1
1905 return 0
1905 return 0
1906
1906
1907 def seriesend(self, all_patches=False):
1907 def seriesend(self, all_patches=False):
1908 """If all_patches is False, return the index of the next pushable patch
1908 """If all_patches is False, return the index of the next pushable patch
1909 in the series, or the series length. If all_patches is True, return the
1909 in the series, or the series length. If all_patches is True, return the
1910 index of the first patch past the last applied one.
1910 index of the first patch past the last applied one.
1911 """
1911 """
1912 end = 0
1912 end = 0
1913 def nextpatch(start):
1913 def nextpatch(start):
1914 if all_patches or start >= len(self.series):
1914 if all_patches or start >= len(self.series):
1915 return start
1915 return start
1916 for i in xrange(start, len(self.series)):
1916 for i in xrange(start, len(self.series)):
1917 p, reason = self.pushable(i)
1917 p, reason = self.pushable(i)
1918 if p:
1918 if p:
1919 return i
1919 return i
1920 self.explainpushable(i)
1920 self.explainpushable(i)
1921 return len(self.series)
1921 return len(self.series)
1922 if self.applied:
1922 if self.applied:
1923 p = self.applied[-1].name
1923 p = self.applied[-1].name
1924 try:
1924 try:
1925 end = self.series.index(p)
1925 end = self.series.index(p)
1926 except ValueError:
1926 except ValueError:
1927 return 0
1927 return 0
1928 return nextpatch(end + 1)
1928 return nextpatch(end + 1)
1929 return nextpatch(end)
1929 return nextpatch(end)
1930
1930
1931 def appliedname(self, index):
1931 def appliedname(self, index):
1932 pname = self.applied[index].name
1932 pname = self.applied[index].name
1933 if not self.ui.verbose:
1933 if not self.ui.verbose:
1934 p = pname
1934 p = pname
1935 else:
1935 else:
1936 p = str(self.series.index(pname)) + " " + pname
1936 p = str(self.series.index(pname)) + " " + pname
1937 return p
1937 return p
1938
1938
1939 def qimport(self, repo, files, patchname=None, rev=None, existing=None,
1939 def qimport(self, repo, files, patchname=None, rev=None, existing=None,
1940 force=None, git=False):
1940 force=None, git=False):
1941 def checkseries(patchname):
1941 def checkseries(patchname):
1942 if patchname in self.series:
1942 if patchname in self.series:
1943 raise util.Abort(_('patch %s is already in the series file')
1943 raise util.Abort(_('patch %s is already in the series file')
1944 % patchname)
1944 % patchname)
1945
1945
1946 if rev:
1946 if rev:
1947 if files:
1947 if files:
1948 raise util.Abort(_('option "-r" not valid when importing '
1948 raise util.Abort(_('option "-r" not valid when importing '
1949 'files'))
1949 'files'))
1950 rev = scmutil.revrange(repo, rev)
1950 rev = scmutil.revrange(repo, rev)
1951 rev.sort(reverse=True)
1951 rev.sort(reverse=True)
1952 elif not files:
1952 elif not files:
1953 raise util.Abort(_('no files or revisions specified'))
1953 raise util.Abort(_('no files or revisions specified'))
1954 if (len(files) > 1 or len(rev) > 1) and patchname:
1954 if (len(files) > 1 or len(rev) > 1) and patchname:
1955 raise util.Abort(_('option "-n" not valid when importing multiple '
1955 raise util.Abort(_('option "-n" not valid when importing multiple '
1956 'patches'))
1956 'patches'))
1957 imported = []
1957 imported = []
1958 if rev:
1958 if rev:
1959 # If mq patches are applied, we can only import revisions
1959 # If mq patches are applied, we can only import revisions
1960 # that form a linear path to qbase.
1960 # that form a linear path to qbase.
1961 # Otherwise, they should form a linear path to a head.
1961 # Otherwise, they should form a linear path to a head.
1962 heads = repo.changelog.heads(repo.changelog.node(rev[-1]))
1962 heads = repo.changelog.heads(repo.changelog.node(rev[-1]))
1963 if len(heads) > 1:
1963 if len(heads) > 1:
1964 raise util.Abort(_('revision %d is the root of more than one '
1964 raise util.Abort(_('revision %d is the root of more than one '
1965 'branch') % rev[-1])
1965 'branch') % rev[-1])
1966 if self.applied:
1966 if self.applied:
1967 base = repo.changelog.node(rev[0])
1967 base = repo.changelog.node(rev[0])
1968 if base in [n.node for n in self.applied]:
1968 if base in [n.node for n in self.applied]:
1969 raise util.Abort(_('revision %d is already managed')
1969 raise util.Abort(_('revision %d is already managed')
1970 % rev[0])
1970 % rev[0])
1971 if heads != [self.applied[-1].node]:
1971 if heads != [self.applied[-1].node]:
1972 raise util.Abort(_('revision %d is not the parent of '
1972 raise util.Abort(_('revision %d is not the parent of '
1973 'the queue') % rev[0])
1973 'the queue') % rev[0])
1974 base = repo.changelog.rev(self.applied[0].node)
1974 base = repo.changelog.rev(self.applied[0].node)
1975 lastparent = repo.changelog.parentrevs(base)[0]
1975 lastparent = repo.changelog.parentrevs(base)[0]
1976 else:
1976 else:
1977 if heads != [repo.changelog.node(rev[0])]:
1977 if heads != [repo.changelog.node(rev[0])]:
1978 raise util.Abort(_('revision %d has unmanaged children')
1978 raise util.Abort(_('revision %d has unmanaged children')
1979 % rev[0])
1979 % rev[0])
1980 lastparent = None
1980 lastparent = None
1981
1981
1982 diffopts = self.diffopts({'git': git})
1982 diffopts = self.diffopts({'git': git})
1983 tr = repo.transaction('qimport')
1983 tr = repo.transaction('qimport')
1984 try:
1984 try:
1985 for r in rev:
1985 for r in rev:
1986 if not repo[r].mutable():
1986 if not repo[r].mutable():
1987 raise util.Abort(_('revision %d is not mutable') % r,
1987 raise util.Abort(_('revision %d is not mutable') % r,
1988 hint=_('see "hg help phases" '
1988 hint=_('see "hg help phases" '
1989 'for details'))
1989 'for details'))
1990 p1, p2 = repo.changelog.parentrevs(r)
1990 p1, p2 = repo.changelog.parentrevs(r)
1991 n = repo.changelog.node(r)
1991 n = repo.changelog.node(r)
1992 if p2 != nullrev:
1992 if p2 != nullrev:
1993 raise util.Abort(_('cannot import merge revision %d')
1993 raise util.Abort(_('cannot import merge revision %d')
1994 % r)
1994 % r)
1995 if lastparent and lastparent != r:
1995 if lastparent and lastparent != r:
1996 raise util.Abort(_('revision %d is not the parent of '
1996 raise util.Abort(_('revision %d is not the parent of '
1997 '%d')
1997 '%d')
1998 % (r, lastparent))
1998 % (r, lastparent))
1999 lastparent = p1
1999 lastparent = p1
2000
2000
2001 if not patchname:
2001 if not patchname:
2002 patchname = normname('%d.diff' % r)
2002 patchname = normname('%d.diff' % r)
2003 checkseries(patchname)
2003 checkseries(patchname)
2004 self.checkpatchname(patchname, force)
2004 self.checkpatchname(patchname, force)
2005 self.fullseries.insert(0, patchname)
2005 self.fullseries.insert(0, patchname)
2006
2006
2007 patchf = self.opener(patchname, "w")
2007 patchf = self.opener(patchname, "w")
2008 cmdutil.export(repo, [n], fp=patchf, opts=diffopts)
2008 cmdutil.export(repo, [n], fp=patchf, opts=diffopts)
2009 patchf.close()
2009 patchf.close()
2010
2010
2011 se = statusentry(n, patchname)
2011 se = statusentry(n, patchname)
2012 self.applied.insert(0, se)
2012 self.applied.insert(0, se)
2013
2013
2014 self.added.append(patchname)
2014 self.added.append(patchname)
2015 imported.append(patchname)
2015 imported.append(patchname)
2016 patchname = None
2016 patchname = None
2017 if rev and repo.ui.configbool('mq', 'secret', False):
2017 if rev and repo.ui.configbool('mq', 'secret', False):
2018 # if we added anything with --rev, move the secret root
2018 # if we added anything with --rev, move the secret root
2019 phases.retractboundary(repo, tr, phases.secret, [n])
2019 phases.retractboundary(repo, tr, phases.secret, [n])
2020 self.parseseries()
2020 self.parseseries()
2021 self.applieddirty = True
2021 self.applieddirty = True
2022 self.seriesdirty = True
2022 self.seriesdirty = True
2023 tr.close()
2023 tr.close()
2024 finally:
2024 finally:
2025 tr.release()
2025 tr.release()
2026
2026
2027 for i, filename in enumerate(files):
2027 for i, filename in enumerate(files):
2028 if existing:
2028 if existing:
2029 if filename == '-':
2029 if filename == '-':
2030 raise util.Abort(_('-e is incompatible with import from -'))
2030 raise util.Abort(_('-e is incompatible with import from -'))
2031 filename = normname(filename)
2031 filename = normname(filename)
2032 self.checkreservedname(filename)
2032 self.checkreservedname(filename)
2033 if util.url(filename).islocal():
2033 if util.url(filename).islocal():
2034 originpath = self.join(filename)
2034 originpath = self.join(filename)
2035 if not os.path.isfile(originpath):
2035 if not os.path.isfile(originpath):
2036 raise util.Abort(
2036 raise util.Abort(
2037 _("patch %s does not exist") % filename)
2037 _("patch %s does not exist") % filename)
2038
2038
2039 if patchname:
2039 if patchname:
2040 self.checkpatchname(patchname, force)
2040 self.checkpatchname(patchname, force)
2041
2041
2042 self.ui.write(_('renaming %s to %s\n')
2042 self.ui.write(_('renaming %s to %s\n')
2043 % (filename, patchname))
2043 % (filename, patchname))
2044 util.rename(originpath, self.join(patchname))
2044 util.rename(originpath, self.join(patchname))
2045 else:
2045 else:
2046 patchname = filename
2046 patchname = filename
2047
2047
2048 else:
2048 else:
2049 if filename == '-' and not patchname:
2049 if filename == '-' and not patchname:
2050 raise util.Abort(_('need --name to import a patch from -'))
2050 raise util.Abort(_('need --name to import a patch from -'))
2051 elif not patchname:
2051 elif not patchname:
2052 patchname = normname(os.path.basename(filename.rstrip('/')))
2052 patchname = normname(os.path.basename(filename.rstrip('/')))
2053 self.checkpatchname(patchname, force)
2053 self.checkpatchname(patchname, force)
2054 try:
2054 try:
2055 if filename == '-':
2055 if filename == '-':
2056 text = self.ui.fin.read()
2056 text = self.ui.fin.read()
2057 else:
2057 else:
2058 fp = hg.openpath(self.ui, filename)
2058 fp = hg.openpath(self.ui, filename)
2059 text = fp.read()
2059 text = fp.read()
2060 fp.close()
2060 fp.close()
2061 except (OSError, IOError):
2061 except (OSError, IOError):
2062 raise util.Abort(_("unable to read file %s") % filename)
2062 raise util.Abort(_("unable to read file %s") % filename)
2063 patchf = self.opener(patchname, "w")
2063 patchf = self.opener(patchname, "w")
2064 patchf.write(text)
2064 patchf.write(text)
2065 patchf.close()
2065 patchf.close()
2066 if not force:
2066 if not force:
2067 checkseries(patchname)
2067 checkseries(patchname)
2068 if patchname not in self.series:
2068 if patchname not in self.series:
2069 index = self.fullseriesend() + i
2069 index = self.fullseriesend() + i
2070 self.fullseries[index:index] = [patchname]
2070 self.fullseries[index:index] = [patchname]
2071 self.parseseries()
2071 self.parseseries()
2072 self.seriesdirty = True
2072 self.seriesdirty = True
2073 self.ui.warn(_("adding %s to series file\n") % patchname)
2073 self.ui.warn(_("adding %s to series file\n") % patchname)
2074 self.added.append(patchname)
2074 self.added.append(patchname)
2075 imported.append(patchname)
2075 imported.append(patchname)
2076 patchname = None
2076 patchname = None
2077
2077
2078 self.removeundo(repo)
2078 self.removeundo(repo)
2079 return imported
2079 return imported
2080
2080
2081 def fixkeepchangesopts(ui, opts):
2081 def fixkeepchangesopts(ui, opts):
2082 if (not ui.configbool('mq', 'keepchanges') or opts.get('force')
2082 if (not ui.configbool('mq', 'keepchanges') or opts.get('force')
2083 or opts.get('exact')):
2083 or opts.get('exact')):
2084 return opts
2084 return opts
2085 opts = dict(opts)
2085 opts = dict(opts)
2086 opts['keep_changes'] = True
2086 opts['keep_changes'] = True
2087 return opts
2087 return opts
2088
2088
2089 @command("qdelete|qremove|qrm",
2089 @command("qdelete|qremove|qrm",
2090 [('k', 'keep', None, _('keep patch file')),
2090 [('k', 'keep', None, _('keep patch file')),
2091 ('r', 'rev', [],
2091 ('r', 'rev', [],
2092 _('stop managing a revision (DEPRECATED)'), _('REV'))],
2092 _('stop managing a revision (DEPRECATED)'), _('REV'))],
2093 _('hg qdelete [-k] [PATCH]...'))
2093 _('hg qdelete [-k] [PATCH]...'))
2094 def delete(ui, repo, *patches, **opts):
2094 def delete(ui, repo, *patches, **opts):
2095 """remove patches from queue
2095 """remove patches from queue
2096
2096
2097 The patches must not be applied, and at least one patch is required. Exact
2097 The patches must not be applied, and at least one patch is required. Exact
2098 patch identifiers must be given. With -k/--keep, the patch files are
2098 patch identifiers must be given. With -k/--keep, the patch files are
2099 preserved in the patch directory.
2099 preserved in the patch directory.
2100
2100
2101 To stop managing a patch and move it into permanent history,
2101 To stop managing a patch and move it into permanent history,
2102 use the :hg:`qfinish` command."""
2102 use the :hg:`qfinish` command."""
2103 q = repo.mq
2103 q = repo.mq
2104 q.delete(repo, patches, opts)
2104 q.delete(repo, patches, opts)
2105 q.savedirty()
2105 q.savedirty()
2106 return 0
2106 return 0
2107
2107
2108 @command("qapplied",
2108 @command("qapplied",
2109 [('1', 'last', None, _('show only the preceding applied patch'))
2109 [('1', 'last', None, _('show only the preceding applied patch'))
2110 ] + seriesopts,
2110 ] + seriesopts,
2111 _('hg qapplied [-1] [-s] [PATCH]'))
2111 _('hg qapplied [-1] [-s] [PATCH]'))
2112 def applied(ui, repo, patch=None, **opts):
2112 def applied(ui, repo, patch=None, **opts):
2113 """print the patches already applied
2113 """print the patches already applied
2114
2114
2115 Returns 0 on success."""
2115 Returns 0 on success."""
2116
2116
2117 q = repo.mq
2117 q = repo.mq
2118
2118
2119 if patch:
2119 if patch:
2120 if patch not in q.series:
2120 if patch not in q.series:
2121 raise util.Abort(_("patch %s is not in series file") % patch)
2121 raise util.Abort(_("patch %s is not in series file") % patch)
2122 end = q.series.index(patch) + 1
2122 end = q.series.index(patch) + 1
2123 else:
2123 else:
2124 end = q.seriesend(True)
2124 end = q.seriesend(True)
2125
2125
2126 if opts.get('last') and not end:
2126 if opts.get('last') and not end:
2127 ui.write(_("no patches applied\n"))
2127 ui.write(_("no patches applied\n"))
2128 return 1
2128 return 1
2129 elif opts.get('last') and end == 1:
2129 elif opts.get('last') and end == 1:
2130 ui.write(_("only one patch applied\n"))
2130 ui.write(_("only one patch applied\n"))
2131 return 1
2131 return 1
2132 elif opts.get('last'):
2132 elif opts.get('last'):
2133 start = end - 2
2133 start = end - 2
2134 end = 1
2134 end = 1
2135 else:
2135 else:
2136 start = 0
2136 start = 0
2137
2137
2138 q.qseries(repo, length=end, start=start, status='A',
2138 q.qseries(repo, length=end, start=start, status='A',
2139 summary=opts.get('summary'))
2139 summary=opts.get('summary'))
2140
2140
2141
2141
2142 @command("qunapplied",
2142 @command("qunapplied",
2143 [('1', 'first', None, _('show only the first patch'))] + seriesopts,
2143 [('1', 'first', None, _('show only the first patch'))] + seriesopts,
2144 _('hg qunapplied [-1] [-s] [PATCH]'))
2144 _('hg qunapplied [-1] [-s] [PATCH]'))
2145 def unapplied(ui, repo, patch=None, **opts):
2145 def unapplied(ui, repo, patch=None, **opts):
2146 """print the patches not yet applied
2146 """print the patches not yet applied
2147
2147
2148 Returns 0 on success."""
2148 Returns 0 on success."""
2149
2149
2150 q = repo.mq
2150 q = repo.mq
2151 if patch:
2151 if patch:
2152 if patch not in q.series:
2152 if patch not in q.series:
2153 raise util.Abort(_("patch %s is not in series file") % patch)
2153 raise util.Abort(_("patch %s is not in series file") % patch)
2154 start = q.series.index(patch) + 1
2154 start = q.series.index(patch) + 1
2155 else:
2155 else:
2156 start = q.seriesend(True)
2156 start = q.seriesend(True)
2157
2157
2158 if start == len(q.series) and opts.get('first'):
2158 if start == len(q.series) and opts.get('first'):
2159 ui.write(_("all patches applied\n"))
2159 ui.write(_("all patches applied\n"))
2160 return 1
2160 return 1
2161
2161
2162 length = opts.get('first') and 1 or None
2162 length = opts.get('first') and 1 or None
2163 q.qseries(repo, start=start, length=length, status='U',
2163 q.qseries(repo, start=start, length=length, status='U',
2164 summary=opts.get('summary'))
2164 summary=opts.get('summary'))
2165
2165
2166 @command("qimport",
2166 @command("qimport",
2167 [('e', 'existing', None, _('import file in patch directory')),
2167 [('e', 'existing', None, _('import file in patch directory')),
2168 ('n', 'name', '',
2168 ('n', 'name', '',
2169 _('name of patch file'), _('NAME')),
2169 _('name of patch file'), _('NAME')),
2170 ('f', 'force', None, _('overwrite existing files')),
2170 ('f', 'force', None, _('overwrite existing files')),
2171 ('r', 'rev', [],
2171 ('r', 'rev', [],
2172 _('place existing revisions under mq control'), _('REV')),
2172 _('place existing revisions under mq control'), _('REV')),
2173 ('g', 'git', None, _('use git extended diff format')),
2173 ('g', 'git', None, _('use git extended diff format')),
2174 ('P', 'push', None, _('qpush after importing'))],
2174 ('P', 'push', None, _('qpush after importing'))],
2175 _('hg qimport [-e] [-n NAME] [-f] [-g] [-P] [-r REV]... [FILE]...'))
2175 _('hg qimport [-e] [-n NAME] [-f] [-g] [-P] [-r REV]... [FILE]...'))
2176 def qimport(ui, repo, *filename, **opts):
2176 def qimport(ui, repo, *filename, **opts):
2177 """import a patch or existing changeset
2177 """import a patch or existing changeset
2178
2178
2179 The patch is inserted into the series after the last applied
2179 The patch is inserted into the series after the last applied
2180 patch. If no patches have been applied, qimport prepends the patch
2180 patch. If no patches have been applied, qimport prepends the patch
2181 to the series.
2181 to the series.
2182
2182
2183 The patch will have the same name as its source file unless you
2183 The patch will have the same name as its source file unless you
2184 give it a new one with -n/--name.
2184 give it a new one with -n/--name.
2185
2185
2186 You can register an existing patch inside the patch directory with
2186 You can register an existing patch inside the patch directory with
2187 the -e/--existing flag.
2187 the -e/--existing flag.
2188
2188
2189 With -f/--force, an existing patch of the same name will be
2189 With -f/--force, an existing patch of the same name will be
2190 overwritten.
2190 overwritten.
2191
2191
2192 An existing changeset may be placed under mq control with -r/--rev
2192 An existing changeset may be placed under mq control with -r/--rev
2193 (e.g. qimport --rev . -n patch will place the current revision
2193 (e.g. qimport --rev . -n patch will place the current revision
2194 under mq control). With -g/--git, patches imported with --rev will
2194 under mq control). With -g/--git, patches imported with --rev will
2195 use the git diff format. See the diffs help topic for information
2195 use the git diff format. See the diffs help topic for information
2196 on why this is important for preserving rename/copy information
2196 on why this is important for preserving rename/copy information
2197 and permission changes. Use :hg:`qfinish` to remove changesets
2197 and permission changes. Use :hg:`qfinish` to remove changesets
2198 from mq control.
2198 from mq control.
2199
2199
2200 To import a patch from standard input, pass - as the patch file.
2200 To import a patch from standard input, pass - as the patch file.
2201 When importing from standard input, a patch name must be specified
2201 When importing from standard input, a patch name must be specified
2202 using the --name flag.
2202 using the --name flag.
2203
2203
2204 To import an existing patch while renaming it::
2204 To import an existing patch while renaming it::
2205
2205
2206 hg qimport -e existing-patch -n new-name
2206 hg qimport -e existing-patch -n new-name
2207
2207
2208 Returns 0 if import succeeded.
2208 Returns 0 if import succeeded.
2209 """
2209 """
2210 lock = repo.lock() # cause this may move phase
2210 lock = repo.lock() # cause this may move phase
2211 try:
2211 try:
2212 q = repo.mq
2212 q = repo.mq
2213 try:
2213 try:
2214 imported = q.qimport(
2214 imported = q.qimport(
2215 repo, filename, patchname=opts.get('name'),
2215 repo, filename, patchname=opts.get('name'),
2216 existing=opts.get('existing'), force=opts.get('force'),
2216 existing=opts.get('existing'), force=opts.get('force'),
2217 rev=opts.get('rev'), git=opts.get('git'))
2217 rev=opts.get('rev'), git=opts.get('git'))
2218 finally:
2218 finally:
2219 q.savedirty()
2219 q.savedirty()
2220 finally:
2220 finally:
2221 lock.release()
2221 lock.release()
2222
2222
2223 if imported and opts.get('push') and not opts.get('rev'):
2223 if imported and opts.get('push') and not opts.get('rev'):
2224 return q.push(repo, imported[-1])
2224 return q.push(repo, imported[-1])
2225 return 0
2225 return 0
2226
2226
2227 def qinit(ui, repo, create):
2227 def qinit(ui, repo, create):
2228 """initialize a new queue repository
2228 """initialize a new queue repository
2229
2229
2230 This command also creates a series file for ordering patches, and
2230 This command also creates a series file for ordering patches, and
2231 an mq-specific .hgignore file in the queue repository, to exclude
2231 an mq-specific .hgignore file in the queue repository, to exclude
2232 the status and guards files (these contain mostly transient state).
2232 the status and guards files (these contain mostly transient state).
2233
2233
2234 Returns 0 if initialization succeeded."""
2234 Returns 0 if initialization succeeded."""
2235 q = repo.mq
2235 q = repo.mq
2236 r = q.init(repo, create)
2236 r = q.init(repo, create)
2237 q.savedirty()
2237 q.savedirty()
2238 if r:
2238 if r:
2239 if not os.path.exists(r.wjoin('.hgignore')):
2239 if not os.path.exists(r.wjoin('.hgignore')):
2240 fp = r.wopener('.hgignore', 'w')
2240 fp = r.wopener('.hgignore', 'w')
2241 fp.write('^\\.hg\n')
2241 fp.write('^\\.hg\n')
2242 fp.write('^\\.mq\n')
2242 fp.write('^\\.mq\n')
2243 fp.write('syntax: glob\n')
2243 fp.write('syntax: glob\n')
2244 fp.write('status\n')
2244 fp.write('status\n')
2245 fp.write('guards\n')
2245 fp.write('guards\n')
2246 fp.close()
2246 fp.close()
2247 if not os.path.exists(r.wjoin('series')):
2247 if not os.path.exists(r.wjoin('series')):
2248 r.wopener('series', 'w').close()
2248 r.wopener('series', 'w').close()
2249 r[None].add(['.hgignore', 'series'])
2249 r[None].add(['.hgignore', 'series'])
2250 commands.add(ui, r)
2250 commands.add(ui, r)
2251 return 0
2251 return 0
2252
2252
2253 @command("^qinit",
2253 @command("^qinit",
2254 [('c', 'create-repo', None, _('create queue repository'))],
2254 [('c', 'create-repo', None, _('create queue repository'))],
2255 _('hg qinit [-c]'))
2255 _('hg qinit [-c]'))
2256 def init(ui, repo, **opts):
2256 def init(ui, repo, **opts):
2257 """init a new queue repository (DEPRECATED)
2257 """init a new queue repository (DEPRECATED)
2258
2258
2259 The queue repository is unversioned by default. If
2259 The queue repository is unversioned by default. If
2260 -c/--create-repo is specified, qinit will create a separate nested
2260 -c/--create-repo is specified, qinit will create a separate nested
2261 repository for patches (qinit -c may also be run later to convert
2261 repository for patches (qinit -c may also be run later to convert
2262 an unversioned patch repository into a versioned one). You can use
2262 an unversioned patch repository into a versioned one). You can use
2263 qcommit to commit changes to this queue repository.
2263 qcommit to commit changes to this queue repository.
2264
2264
2265 This command is deprecated. Without -c, it's implied by other relevant
2265 This command is deprecated. Without -c, it's implied by other relevant
2266 commands. With -c, use :hg:`init --mq` instead."""
2266 commands. With -c, use :hg:`init --mq` instead."""
2267 return qinit(ui, repo, create=opts.get('create_repo'))
2267 return qinit(ui, repo, create=opts.get('create_repo'))
2268
2268
2269 @command("qclone",
2269 @command("qclone",
2270 [('', 'pull', None, _('use pull protocol to copy metadata')),
2270 [('', 'pull', None, _('use pull protocol to copy metadata')),
2271 ('U', 'noupdate', None,
2271 ('U', 'noupdate', None,
2272 _('do not update the new working directories')),
2272 _('do not update the new working directories')),
2273 ('', 'uncompressed', None,
2273 ('', 'uncompressed', None,
2274 _('use uncompressed transfer (fast over LAN)')),
2274 _('use uncompressed transfer (fast over LAN)')),
2275 ('p', 'patches', '',
2275 ('p', 'patches', '',
2276 _('location of source patch repository'), _('REPO')),
2276 _('location of source patch repository'), _('REPO')),
2277 ] + commands.remoteopts,
2277 ] + commands.remoteopts,
2278 _('hg qclone [OPTION]... SOURCE [DEST]'),
2278 _('hg qclone [OPTION]... SOURCE [DEST]'),
2279 norepo=True)
2279 norepo=True)
2280 def clone(ui, source, dest=None, **opts):
2280 def clone(ui, source, dest=None, **opts):
2281 '''clone main and patch repository at same time
2281 '''clone main and patch repository at same time
2282
2282
2283 If source is local, destination will have no patches applied. If
2283 If source is local, destination will have no patches applied. If
2284 source is remote, this command can not check if patches are
2284 source is remote, this command can not check if patches are
2285 applied in source, so cannot guarantee that patches are not
2285 applied in source, so cannot guarantee that patches are not
2286 applied in destination. If you clone remote repository, be sure
2286 applied in destination. If you clone remote repository, be sure
2287 before that it has no patches applied.
2287 before that it has no patches applied.
2288
2288
2289 Source patch repository is looked for in <src>/.hg/patches by
2289 Source patch repository is looked for in <src>/.hg/patches by
2290 default. Use -p <url> to change.
2290 default. Use -p <url> to change.
2291
2291
2292 The patch directory must be a nested Mercurial repository, as
2292 The patch directory must be a nested Mercurial repository, as
2293 would be created by :hg:`init --mq`.
2293 would be created by :hg:`init --mq`.
2294
2294
2295 Return 0 on success.
2295 Return 0 on success.
2296 '''
2296 '''
2297 def patchdir(repo):
2297 def patchdir(repo):
2298 """compute a patch repo url from a repo object"""
2298 """compute a patch repo url from a repo object"""
2299 url = repo.url()
2299 url = repo.url()
2300 if url.endswith('/'):
2300 if url.endswith('/'):
2301 url = url[:-1]
2301 url = url[:-1]
2302 return url + '/.hg/patches'
2302 return url + '/.hg/patches'
2303
2303
2304 # main repo (destination and sources)
2304 # main repo (destination and sources)
2305 if dest is None:
2305 if dest is None:
2306 dest = hg.defaultdest(source)
2306 dest = hg.defaultdest(source)
2307 sr = hg.peer(ui, opts, ui.expandpath(source))
2307 sr = hg.peer(ui, opts, ui.expandpath(source))
2308
2308
2309 # patches repo (source only)
2309 # patches repo (source only)
2310 if opts.get('patches'):
2310 if opts.get('patches'):
2311 patchespath = ui.expandpath(opts.get('patches'))
2311 patchespath = ui.expandpath(opts.get('patches'))
2312 else:
2312 else:
2313 patchespath = patchdir(sr)
2313 patchespath = patchdir(sr)
2314 try:
2314 try:
2315 hg.peer(ui, opts, patchespath)
2315 hg.peer(ui, opts, patchespath)
2316 except error.RepoError:
2316 except error.RepoError:
2317 raise util.Abort(_('versioned patch repository not found'
2317 raise util.Abort(_('versioned patch repository not found'
2318 ' (see init --mq)'))
2318 ' (see init --mq)'))
2319 qbase, destrev = None, None
2319 qbase, destrev = None, None
2320 if sr.local():
2320 if sr.local():
2321 repo = sr.local()
2321 repo = sr.local()
2322 if repo.mq.applied and repo[qbase].phase() != phases.secret:
2322 if repo.mq.applied and repo[qbase].phase() != phases.secret:
2323 qbase = repo.mq.applied[0].node
2323 qbase = repo.mq.applied[0].node
2324 if not hg.islocal(dest):
2324 if not hg.islocal(dest):
2325 heads = set(repo.heads())
2325 heads = set(repo.heads())
2326 destrev = list(heads.difference(repo.heads(qbase)))
2326 destrev = list(heads.difference(repo.heads(qbase)))
2327 destrev.append(repo.changelog.parents(qbase)[0])
2327 destrev.append(repo.changelog.parents(qbase)[0])
2328 elif sr.capable('lookup'):
2328 elif sr.capable('lookup'):
2329 try:
2329 try:
2330 qbase = sr.lookup('qbase')
2330 qbase = sr.lookup('qbase')
2331 except error.RepoError:
2331 except error.RepoError:
2332 pass
2332 pass
2333
2333
2334 ui.note(_('cloning main repository\n'))
2334 ui.note(_('cloning main repository\n'))
2335 sr, dr = hg.clone(ui, opts, sr.url(), dest,
2335 sr, dr = hg.clone(ui, opts, sr.url(), dest,
2336 pull=opts.get('pull'),
2336 pull=opts.get('pull'),
2337 rev=destrev,
2337 rev=destrev,
2338 update=False,
2338 update=False,
2339 stream=opts.get('uncompressed'))
2339 stream=opts.get('uncompressed'))
2340
2340
2341 ui.note(_('cloning patch repository\n'))
2341 ui.note(_('cloning patch repository\n'))
2342 hg.clone(ui, opts, opts.get('patches') or patchdir(sr), patchdir(dr),
2342 hg.clone(ui, opts, opts.get('patches') or patchdir(sr), patchdir(dr),
2343 pull=opts.get('pull'), update=not opts.get('noupdate'),
2343 pull=opts.get('pull'), update=not opts.get('noupdate'),
2344 stream=opts.get('uncompressed'))
2344 stream=opts.get('uncompressed'))
2345
2345
2346 if dr.local():
2346 if dr.local():
2347 repo = dr.local()
2347 repo = dr.local()
2348 if qbase:
2348 if qbase:
2349 ui.note(_('stripping applied patches from destination '
2349 ui.note(_('stripping applied patches from destination '
2350 'repository\n'))
2350 'repository\n'))
2351 strip(ui, repo, [qbase], update=False, backup=None)
2351 strip(ui, repo, [qbase], update=False, backup=None)
2352 if not opts.get('noupdate'):
2352 if not opts.get('noupdate'):
2353 ui.note(_('updating destination repository\n'))
2353 ui.note(_('updating destination repository\n'))
2354 hg.update(repo, repo.changelog.tip())
2354 hg.update(repo, repo.changelog.tip())
2355
2355
2356 @command("qcommit|qci",
2356 @command("qcommit|qci",
2357 commands.table["^commit|ci"][1],
2357 commands.table["^commit|ci"][1],
2358 _('hg qcommit [OPTION]... [FILE]...'),
2358 _('hg qcommit [OPTION]... [FILE]...'),
2359 inferrepo=True)
2359 inferrepo=True)
2360 def commit(ui, repo, *pats, **opts):
2360 def commit(ui, repo, *pats, **opts):
2361 """commit changes in the queue repository (DEPRECATED)
2361 """commit changes in the queue repository (DEPRECATED)
2362
2362
2363 This command is deprecated; use :hg:`commit --mq` instead."""
2363 This command is deprecated; use :hg:`commit --mq` instead."""
2364 q = repo.mq
2364 q = repo.mq
2365 r = q.qrepo()
2365 r = q.qrepo()
2366 if not r:
2366 if not r:
2367 raise util.Abort('no queue repository')
2367 raise util.Abort('no queue repository')
2368 commands.commit(r.ui, r, *pats, **opts)
2368 commands.commit(r.ui, r, *pats, **opts)
2369
2369
2370 @command("qseries",
2370 @command("qseries",
2371 [('m', 'missing', None, _('print patches not in series')),
2371 [('m', 'missing', None, _('print patches not in series')),
2372 ] + seriesopts,
2372 ] + seriesopts,
2373 _('hg qseries [-ms]'))
2373 _('hg qseries [-ms]'))
2374 def series(ui, repo, **opts):
2374 def series(ui, repo, **opts):
2375 """print the entire series file
2375 """print the entire series file
2376
2376
2377 Returns 0 on success."""
2377 Returns 0 on success."""
2378 repo.mq.qseries(repo, missing=opts.get('missing'),
2378 repo.mq.qseries(repo, missing=opts.get('missing'),
2379 summary=opts.get('summary'))
2379 summary=opts.get('summary'))
2380 return 0
2380 return 0
2381
2381
2382 @command("qtop", seriesopts, _('hg qtop [-s]'))
2382 @command("qtop", seriesopts, _('hg qtop [-s]'))
2383 def top(ui, repo, **opts):
2383 def top(ui, repo, **opts):
2384 """print the name of the current patch
2384 """print the name of the current patch
2385
2385
2386 Returns 0 on success."""
2386 Returns 0 on success."""
2387 q = repo.mq
2387 q = repo.mq
2388 t = q.applied and q.seriesend(True) or 0
2388 t = q.applied and q.seriesend(True) or 0
2389 if t:
2389 if t:
2390 q.qseries(repo, start=t - 1, length=1, status='A',
2390 q.qseries(repo, start=t - 1, length=1, status='A',
2391 summary=opts.get('summary'))
2391 summary=opts.get('summary'))
2392 else:
2392 else:
2393 ui.write(_("no patches applied\n"))
2393 ui.write(_("no patches applied\n"))
2394 return 1
2394 return 1
2395
2395
2396 @command("qnext", seriesopts, _('hg qnext [-s]'))
2396 @command("qnext", seriesopts, _('hg qnext [-s]'))
2397 def next(ui, repo, **opts):
2397 def next(ui, repo, **opts):
2398 """print the name of the next pushable patch
2398 """print the name of the next pushable patch
2399
2399
2400 Returns 0 on success."""
2400 Returns 0 on success."""
2401 q = repo.mq
2401 q = repo.mq
2402 end = q.seriesend()
2402 end = q.seriesend()
2403 if end == len(q.series):
2403 if end == len(q.series):
2404 ui.write(_("all patches applied\n"))
2404 ui.write(_("all patches applied\n"))
2405 return 1
2405 return 1
2406 q.qseries(repo, start=end, length=1, summary=opts.get('summary'))
2406 q.qseries(repo, start=end, length=1, summary=opts.get('summary'))
2407
2407
2408 @command("qprev", seriesopts, _('hg qprev [-s]'))
2408 @command("qprev", seriesopts, _('hg qprev [-s]'))
2409 def prev(ui, repo, **opts):
2409 def prev(ui, repo, **opts):
2410 """print the name of the preceding applied patch
2410 """print the name of the preceding applied patch
2411
2411
2412 Returns 0 on success."""
2412 Returns 0 on success."""
2413 q = repo.mq
2413 q = repo.mq
2414 l = len(q.applied)
2414 l = len(q.applied)
2415 if l == 1:
2415 if l == 1:
2416 ui.write(_("only one patch applied\n"))
2416 ui.write(_("only one patch applied\n"))
2417 return 1
2417 return 1
2418 if not l:
2418 if not l:
2419 ui.write(_("no patches applied\n"))
2419 ui.write(_("no patches applied\n"))
2420 return 1
2420 return 1
2421 idx = q.series.index(q.applied[-2].name)
2421 idx = q.series.index(q.applied[-2].name)
2422 q.qseries(repo, start=idx, length=1, status='A',
2422 q.qseries(repo, start=idx, length=1, status='A',
2423 summary=opts.get('summary'))
2423 summary=opts.get('summary'))
2424
2424
2425 def setupheaderopts(ui, opts):
2425 def setupheaderopts(ui, opts):
2426 if not opts.get('user') and opts.get('currentuser'):
2426 if not opts.get('user') and opts.get('currentuser'):
2427 opts['user'] = ui.username()
2427 opts['user'] = ui.username()
2428 if not opts.get('date') and opts.get('currentdate'):
2428 if not opts.get('date') and opts.get('currentdate'):
2429 opts['date'] = "%d %d" % util.makedate()
2429 opts['date'] = "%d %d" % util.makedate()
2430
2430
2431 @command("^qnew",
2431 @command("^qnew",
2432 [('e', 'edit', None, _('invoke editor on commit messages')),
2432 [('e', 'edit', None, _('invoke editor on commit messages')),
2433 ('f', 'force', None, _('import uncommitted changes (DEPRECATED)')),
2433 ('f', 'force', None, _('import uncommitted changes (DEPRECATED)')),
2434 ('g', 'git', None, _('use git extended diff format')),
2434 ('g', 'git', None, _('use git extended diff format')),
2435 ('U', 'currentuser', None, _('add "From: <current user>" to patch')),
2435 ('U', 'currentuser', None, _('add "From: <current user>" to patch')),
2436 ('u', 'user', '',
2436 ('u', 'user', '',
2437 _('add "From: <USER>" to patch'), _('USER')),
2437 _('add "From: <USER>" to patch'), _('USER')),
2438 ('D', 'currentdate', None, _('add "Date: <current date>" to patch')),
2438 ('D', 'currentdate', None, _('add "Date: <current date>" to patch')),
2439 ('d', 'date', '',
2439 ('d', 'date', '',
2440 _('add "Date: <DATE>" to patch'), _('DATE'))
2440 _('add "Date: <DATE>" to patch'), _('DATE'))
2441 ] + commands.walkopts + commands.commitopts,
2441 ] + commands.walkopts + commands.commitopts,
2442 _('hg qnew [-e] [-m TEXT] [-l FILE] PATCH [FILE]...'),
2442 _('hg qnew [-e] [-m TEXT] [-l FILE] PATCH [FILE]...'),
2443 inferrepo=True)
2443 inferrepo=True)
2444 def new(ui, repo, patch, *args, **opts):
2444 def new(ui, repo, patch, *args, **opts):
2445 """create a new patch
2445 """create a new patch
2446
2446
2447 qnew creates a new patch on top of the currently-applied patch (if
2447 qnew creates a new patch on top of the currently-applied patch (if
2448 any). The patch will be initialized with any outstanding changes
2448 any). The patch will be initialized with any outstanding changes
2449 in the working directory. You may also use -I/--include,
2449 in the working directory. You may also use -I/--include,
2450 -X/--exclude, and/or a list of files after the patch name to add
2450 -X/--exclude, and/or a list of files after the patch name to add
2451 only changes to matching files to the new patch, leaving the rest
2451 only changes to matching files to the new patch, leaving the rest
2452 as uncommitted modifications.
2452 as uncommitted modifications.
2453
2453
2454 -u/--user and -d/--date can be used to set the (given) user and
2454 -u/--user and -d/--date can be used to set the (given) user and
2455 date, respectively. -U/--currentuser and -D/--currentdate set user
2455 date, respectively. -U/--currentuser and -D/--currentdate set user
2456 to current user and date to current date.
2456 to current user and date to current date.
2457
2457
2458 -e/--edit, -m/--message or -l/--logfile set the patch header as
2458 -e/--edit, -m/--message or -l/--logfile set the patch header as
2459 well as the commit message. If none is specified, the header is
2459 well as the commit message. If none is specified, the header is
2460 empty and the commit message is '[mq]: PATCH'.
2460 empty and the commit message is '[mq]: PATCH'.
2461
2461
2462 Use the -g/--git option to keep the patch in the git extended diff
2462 Use the -g/--git option to keep the patch in the git extended diff
2463 format. Read the diffs help topic for more information on why this
2463 format. Read the diffs help topic for more information on why this
2464 is important for preserving permission changes and copy/rename
2464 is important for preserving permission changes and copy/rename
2465 information.
2465 information.
2466
2466
2467 Returns 0 on successful creation of a new patch.
2467 Returns 0 on successful creation of a new patch.
2468 """
2468 """
2469 msg = cmdutil.logmessage(ui, opts)
2469 msg = cmdutil.logmessage(ui, opts)
2470 q = repo.mq
2470 q = repo.mq
2471 opts['msg'] = msg
2471 opts['msg'] = msg
2472 setupheaderopts(ui, opts)
2472 setupheaderopts(ui, opts)
2473 q.new(repo, patch, *args, **opts)
2473 q.new(repo, patch, *args, **opts)
2474 q.savedirty()
2474 q.savedirty()
2475 return 0
2475 return 0
2476
2476
2477 @command("^qrefresh",
2477 @command("^qrefresh",
2478 [('e', 'edit', None, _('invoke editor on commit messages')),
2478 [('e', 'edit', None, _('invoke editor on commit messages')),
2479 ('g', 'git', None, _('use git extended diff format')),
2479 ('g', 'git', None, _('use git extended diff format')),
2480 ('s', 'short', None,
2480 ('s', 'short', None,
2481 _('refresh only files already in the patch and specified files')),
2481 _('refresh only files already in the patch and specified files')),
2482 ('U', 'currentuser', None,
2482 ('U', 'currentuser', None,
2483 _('add/update author field in patch with current user')),
2483 _('add/update author field in patch with current user')),
2484 ('u', 'user', '',
2484 ('u', 'user', '',
2485 _('add/update author field in patch with given user'), _('USER')),
2485 _('add/update author field in patch with given user'), _('USER')),
2486 ('D', 'currentdate', None,
2486 ('D', 'currentdate', None,
2487 _('add/update date field in patch with current date')),
2487 _('add/update date field in patch with current date')),
2488 ('d', 'date', '',
2488 ('d', 'date', '',
2489 _('add/update date field in patch with given date'), _('DATE'))
2489 _('add/update date field in patch with given date'), _('DATE'))
2490 ] + commands.walkopts + commands.commitopts,
2490 ] + commands.walkopts + commands.commitopts,
2491 _('hg qrefresh [-I] [-X] [-e] [-m TEXT] [-l FILE] [-s] [FILE]...'),
2491 _('hg qrefresh [-I] [-X] [-e] [-m TEXT] [-l FILE] [-s] [FILE]...'),
2492 inferrepo=True)
2492 inferrepo=True)
2493 def refresh(ui, repo, *pats, **opts):
2493 def refresh(ui, repo, *pats, **opts):
2494 """update the current patch
2494 """update the current patch
2495
2495
2496 If any file patterns are provided, the refreshed patch will
2496 If any file patterns are provided, the refreshed patch will
2497 contain only the modifications that match those patterns; the
2497 contain only the modifications that match those patterns; the
2498 remaining modifications will remain in the working directory.
2498 remaining modifications will remain in the working directory.
2499
2499
2500 If -s/--short is specified, files currently included in the patch
2500 If -s/--short is specified, files currently included in the patch
2501 will be refreshed just like matched files and remain in the patch.
2501 will be refreshed just like matched files and remain in the patch.
2502
2502
2503 If -e/--edit is specified, Mercurial will start your configured editor for
2503 If -e/--edit is specified, Mercurial will start your configured editor for
2504 you to enter a message. In case qrefresh fails, you will find a backup of
2504 you to enter a message. In case qrefresh fails, you will find a backup of
2505 your message in ``.hg/last-message.txt``.
2505 your message in ``.hg/last-message.txt``.
2506
2506
2507 hg add/remove/copy/rename work as usual, though you might want to
2507 hg add/remove/copy/rename work as usual, though you might want to
2508 use git-style patches (-g/--git or [diff] git=1) to track copies
2508 use git-style patches (-g/--git or [diff] git=1) to track copies
2509 and renames. See the diffs help topic for more information on the
2509 and renames. See the diffs help topic for more information on the
2510 git diff format.
2510 git diff format.
2511
2511
2512 Returns 0 on success.
2512 Returns 0 on success.
2513 """
2513 """
2514 q = repo.mq
2514 q = repo.mq
2515 message = cmdutil.logmessage(ui, opts)
2515 message = cmdutil.logmessage(ui, opts)
2516 setupheaderopts(ui, opts)
2516 setupheaderopts(ui, opts)
2517 wlock = repo.wlock()
2517 wlock = repo.wlock()
2518 try:
2518 try:
2519 ret = q.refresh(repo, pats, msg=message, **opts)
2519 ret = q.refresh(repo, pats, msg=message, **opts)
2520 q.savedirty()
2520 q.savedirty()
2521 return ret
2521 return ret
2522 finally:
2522 finally:
2523 wlock.release()
2523 wlock.release()
2524
2524
2525 @command("^qdiff",
2525 @command("^qdiff",
2526 commands.diffopts + commands.diffopts2 + commands.walkopts,
2526 commands.diffopts + commands.diffopts2 + commands.walkopts,
2527 _('hg qdiff [OPTION]... [FILE]...'),
2527 _('hg qdiff [OPTION]... [FILE]...'),
2528 inferrepo=True)
2528 inferrepo=True)
2529 def diff(ui, repo, *pats, **opts):
2529 def diff(ui, repo, *pats, **opts):
2530 """diff of the current patch and subsequent modifications
2530 """diff of the current patch and subsequent modifications
2531
2531
2532 Shows a diff which includes the current patch as well as any
2532 Shows a diff which includes the current patch as well as any
2533 changes which have been made in the working directory since the
2533 changes which have been made in the working directory since the
2534 last refresh (thus showing what the current patch would become
2534 last refresh (thus showing what the current patch would become
2535 after a qrefresh).
2535 after a qrefresh).
2536
2536
2537 Use :hg:`diff` if you only want to see the changes made since the
2537 Use :hg:`diff` if you only want to see the changes made since the
2538 last qrefresh, or :hg:`export qtip` if you want to see changes
2538 last qrefresh, or :hg:`export qtip` if you want to see changes
2539 made by the current patch without including changes made since the
2539 made by the current patch without including changes made since the
2540 qrefresh.
2540 qrefresh.
2541
2541
2542 Returns 0 on success.
2542 Returns 0 on success.
2543 """
2543 """
2544 repo.mq.diff(repo, pats, opts)
2544 repo.mq.diff(repo, pats, opts)
2545 return 0
2545 return 0
2546
2546
2547 @command('qfold',
2547 @command('qfold',
2548 [('e', 'edit', None, _('invoke editor on commit messages')),
2548 [('e', 'edit', None, _('invoke editor on commit messages')),
2549 ('k', 'keep', None, _('keep folded patch files')),
2549 ('k', 'keep', None, _('keep folded patch files')),
2550 ] + commands.commitopts,
2550 ] + commands.commitopts,
2551 _('hg qfold [-e] [-k] [-m TEXT] [-l FILE] PATCH...'))
2551 _('hg qfold [-e] [-k] [-m TEXT] [-l FILE] PATCH...'))
2552 def fold(ui, repo, *files, **opts):
2552 def fold(ui, repo, *files, **opts):
2553 """fold the named patches into the current patch
2553 """fold the named patches into the current patch
2554
2554
2555 Patches must not yet be applied. Each patch will be successively
2555 Patches must not yet be applied. Each patch will be successively
2556 applied to the current patch in the order given. If all the
2556 applied to the current patch in the order given. If all the
2557 patches apply successfully, the current patch will be refreshed
2557 patches apply successfully, the current patch will be refreshed
2558 with the new cumulative patch, and the folded patches will be
2558 with the new cumulative patch, and the folded patches will be
2559 deleted. With -k/--keep, the folded patch files will not be
2559 deleted. With -k/--keep, the folded patch files will not be
2560 removed afterwards.
2560 removed afterwards.
2561
2561
2562 The header for each folded patch will be concatenated with the
2562 The header for each folded patch will be concatenated with the
2563 current patch header, separated by a line of ``* * *``.
2563 current patch header, separated by a line of ``* * *``.
2564
2564
2565 Returns 0 on success."""
2565 Returns 0 on success."""
2566 q = repo.mq
2566 q = repo.mq
2567 if not files:
2567 if not files:
2568 raise util.Abort(_('qfold requires at least one patch name'))
2568 raise util.Abort(_('qfold requires at least one patch name'))
2569 if not q.checktoppatch(repo)[0]:
2569 if not q.checktoppatch(repo)[0]:
2570 raise util.Abort(_('no patches applied'))
2570 raise util.Abort(_('no patches applied'))
2571 q.checklocalchanges(repo)
2571 q.checklocalchanges(repo)
2572
2572
2573 message = cmdutil.logmessage(ui, opts)
2573 message = cmdutil.logmessage(ui, opts)
2574
2574
2575 parent = q.lookup('qtip')
2575 parent = q.lookup('qtip')
2576 patches = []
2576 patches = []
2577 messages = []
2577 messages = []
2578 for f in files:
2578 for f in files:
2579 p = q.lookup(f)
2579 p = q.lookup(f)
2580 if p in patches or p == parent:
2580 if p in patches or p == parent:
2581 ui.warn(_('skipping already folded patch %s\n') % p)
2581 ui.warn(_('skipping already folded patch %s\n') % p)
2582 if q.isapplied(p):
2582 if q.isapplied(p):
2583 raise util.Abort(_('qfold cannot fold already applied patch %s')
2583 raise util.Abort(_('qfold cannot fold already applied patch %s')
2584 % p)
2584 % p)
2585 patches.append(p)
2585 patches.append(p)
2586
2586
2587 for p in patches:
2587 for p in patches:
2588 if not message:
2588 if not message:
2589 ph = patchheader(q.join(p), q.plainmode)
2589 ph = patchheader(q.join(p), q.plainmode)
2590 if ph.message:
2590 if ph.message:
2591 messages.append(ph.message)
2591 messages.append(ph.message)
2592 pf = q.join(p)
2592 pf = q.join(p)
2593 (patchsuccess, files, fuzz) = q.patch(repo, pf)
2593 (patchsuccess, files, fuzz) = q.patch(repo, pf)
2594 if not patchsuccess:
2594 if not patchsuccess:
2595 raise util.Abort(_('error folding patch %s') % p)
2595 raise util.Abort(_('error folding patch %s') % p)
2596
2596
2597 if not message:
2597 if not message:
2598 ph = patchheader(q.join(parent), q.plainmode)
2598 ph = patchheader(q.join(parent), q.plainmode)
2599 message = ph.message
2599 message = ph.message
2600 for msg in messages:
2600 for msg in messages:
2601 if msg:
2601 if msg:
2602 if message:
2602 if message:
2603 message.append('* * *')
2603 message.append('* * *')
2604 message.extend(msg)
2604 message.extend(msg)
2605 message = '\n'.join(message)
2605 message = '\n'.join(message)
2606
2606
2607 diffopts = q.patchopts(q.diffopts(), *patches)
2607 diffopts = q.patchopts(q.diffopts(), *patches)
2608 wlock = repo.wlock()
2608 wlock = repo.wlock()
2609 try:
2609 try:
2610 q.refresh(repo, msg=message, git=diffopts.git, edit=opts.get('edit'),
2610 q.refresh(repo, msg=message, git=diffopts.git, edit=opts.get('edit'),
2611 editform='mq.qfold')
2611 editform='mq.qfold')
2612 q.delete(repo, patches, opts)
2612 q.delete(repo, patches, opts)
2613 q.savedirty()
2613 q.savedirty()
2614 finally:
2614 finally:
2615 wlock.release()
2615 wlock.release()
2616
2616
2617 @command("qgoto",
2617 @command("qgoto",
2618 [('', 'keep-changes', None,
2618 [('', 'keep-changes', None,
2619 _('tolerate non-conflicting local changes')),
2619 _('tolerate non-conflicting local changes')),
2620 ('f', 'force', None, _('overwrite any local changes')),
2620 ('f', 'force', None, _('overwrite any local changes')),
2621 ('', 'no-backup', None, _('do not save backup copies of files'))],
2621 ('', 'no-backup', None, _('do not save backup copies of files'))],
2622 _('hg qgoto [OPTION]... PATCH'))
2622 _('hg qgoto [OPTION]... PATCH'))
2623 def goto(ui, repo, patch, **opts):
2623 def goto(ui, repo, patch, **opts):
2624 '''push or pop patches until named patch is at top of stack
2624 '''push or pop patches until named patch is at top of stack
2625
2625
2626 Returns 0 on success.'''
2626 Returns 0 on success.'''
2627 opts = fixkeepchangesopts(ui, opts)
2627 opts = fixkeepchangesopts(ui, opts)
2628 q = repo.mq
2628 q = repo.mq
2629 patch = q.lookup(patch)
2629 patch = q.lookup(patch)
2630 nobackup = opts.get('no_backup')
2630 nobackup = opts.get('no_backup')
2631 keepchanges = opts.get('keep_changes')
2631 keepchanges = opts.get('keep_changes')
2632 if q.isapplied(patch):
2632 if q.isapplied(patch):
2633 ret = q.pop(repo, patch, force=opts.get('force'), nobackup=nobackup,
2633 ret = q.pop(repo, patch, force=opts.get('force'), nobackup=nobackup,
2634 keepchanges=keepchanges)
2634 keepchanges=keepchanges)
2635 else:
2635 else:
2636 ret = q.push(repo, patch, force=opts.get('force'), nobackup=nobackup,
2636 ret = q.push(repo, patch, force=opts.get('force'), nobackup=nobackup,
2637 keepchanges=keepchanges)
2637 keepchanges=keepchanges)
2638 q.savedirty()
2638 q.savedirty()
2639 return ret
2639 return ret
2640
2640
2641 @command("qguard",
2641 @command("qguard",
2642 [('l', 'list', None, _('list all patches and guards')),
2642 [('l', 'list', None, _('list all patches and guards')),
2643 ('n', 'none', None, _('drop all guards'))],
2643 ('n', 'none', None, _('drop all guards'))],
2644 _('hg qguard [-l] [-n] [PATCH] [-- [+GUARD]... [-GUARD]...]'))
2644 _('hg qguard [-l] [-n] [PATCH] [-- [+GUARD]... [-GUARD]...]'))
2645 def guard(ui, repo, *args, **opts):
2645 def guard(ui, repo, *args, **opts):
2646 '''set or print guards for a patch
2646 '''set or print guards for a patch
2647
2647
2648 Guards control whether a patch can be pushed. A patch with no
2648 Guards control whether a patch can be pushed. A patch with no
2649 guards is always pushed. A patch with a positive guard ("+foo") is
2649 guards is always pushed. A patch with a positive guard ("+foo") is
2650 pushed only if the :hg:`qselect` command has activated it. A patch with
2650 pushed only if the :hg:`qselect` command has activated it. A patch with
2651 a negative guard ("-foo") is never pushed if the :hg:`qselect` command
2651 a negative guard ("-foo") is never pushed if the :hg:`qselect` command
2652 has activated it.
2652 has activated it.
2653
2653
2654 With no arguments, print the currently active guards.
2654 With no arguments, print the currently active guards.
2655 With arguments, set guards for the named patch.
2655 With arguments, set guards for the named patch.
2656
2656
2657 .. note::
2657 .. note::
2658
2658
2659 Specifying negative guards now requires '--'.
2659 Specifying negative guards now requires '--'.
2660
2660
2661 To set guards on another patch::
2661 To set guards on another patch::
2662
2662
2663 hg qguard other.patch -- +2.6.17 -stable
2663 hg qguard other.patch -- +2.6.17 -stable
2664
2664
2665 Returns 0 on success.
2665 Returns 0 on success.
2666 '''
2666 '''
2667 def status(idx):
2667 def status(idx):
2668 guards = q.seriesguards[idx] or ['unguarded']
2668 guards = q.seriesguards[idx] or ['unguarded']
2669 if q.series[idx] in applied:
2669 if q.series[idx] in applied:
2670 state = 'applied'
2670 state = 'applied'
2671 elif q.pushable(idx)[0]:
2671 elif q.pushable(idx)[0]:
2672 state = 'unapplied'
2672 state = 'unapplied'
2673 else:
2673 else:
2674 state = 'guarded'
2674 state = 'guarded'
2675 label = 'qguard.patch qguard.%s qseries.%s' % (state, state)
2675 label = 'qguard.patch qguard.%s qseries.%s' % (state, state)
2676 ui.write('%s: ' % ui.label(q.series[idx], label))
2676 ui.write('%s: ' % ui.label(q.series[idx], label))
2677
2677
2678 for i, guard in enumerate(guards):
2678 for i, guard in enumerate(guards):
2679 if guard.startswith('+'):
2679 if guard.startswith('+'):
2680 ui.write(guard, label='qguard.positive')
2680 ui.write(guard, label='qguard.positive')
2681 elif guard.startswith('-'):
2681 elif guard.startswith('-'):
2682 ui.write(guard, label='qguard.negative')
2682 ui.write(guard, label='qguard.negative')
2683 else:
2683 else:
2684 ui.write(guard, label='qguard.unguarded')
2684 ui.write(guard, label='qguard.unguarded')
2685 if i != len(guards) - 1:
2685 if i != len(guards) - 1:
2686 ui.write(' ')
2686 ui.write(' ')
2687 ui.write('\n')
2687 ui.write('\n')
2688 q = repo.mq
2688 q = repo.mq
2689 applied = set(p.name for p in q.applied)
2689 applied = set(p.name for p in q.applied)
2690 patch = None
2690 patch = None
2691 args = list(args)
2691 args = list(args)
2692 if opts.get('list'):
2692 if opts.get('list'):
2693 if args or opts.get('none'):
2693 if args or opts.get('none'):
2694 raise util.Abort(_('cannot mix -l/--list with options or '
2694 raise util.Abort(_('cannot mix -l/--list with options or '
2695 'arguments'))
2695 'arguments'))
2696 for i in xrange(len(q.series)):
2696 for i in xrange(len(q.series)):
2697 status(i)
2697 status(i)
2698 return
2698 return
2699 if not args or args[0][0:1] in '-+':
2699 if not args or args[0][0:1] in '-+':
2700 if not q.applied:
2700 if not q.applied:
2701 raise util.Abort(_('no patches applied'))
2701 raise util.Abort(_('no patches applied'))
2702 patch = q.applied[-1].name
2702 patch = q.applied[-1].name
2703 if patch is None and args[0][0:1] not in '-+':
2703 if patch is None and args[0][0:1] not in '-+':
2704 patch = args.pop(0)
2704 patch = args.pop(0)
2705 if patch is None:
2705 if patch is None:
2706 raise util.Abort(_('no patch to work with'))
2706 raise util.Abort(_('no patch to work with'))
2707 if args or opts.get('none'):
2707 if args or opts.get('none'):
2708 idx = q.findseries(patch)
2708 idx = q.findseries(patch)
2709 if idx is None:
2709 if idx is None:
2710 raise util.Abort(_('no patch named %s') % patch)
2710 raise util.Abort(_('no patch named %s') % patch)
2711 q.setguards(idx, args)
2711 q.setguards(idx, args)
2712 q.savedirty()
2712 q.savedirty()
2713 else:
2713 else:
2714 status(q.series.index(q.lookup(patch)))
2714 status(q.series.index(q.lookup(patch)))
2715
2715
2716 @command("qheader", [], _('hg qheader [PATCH]'))
2716 @command("qheader", [], _('hg qheader [PATCH]'))
2717 def header(ui, repo, patch=None):
2717 def header(ui, repo, patch=None):
2718 """print the header of the topmost or specified patch
2718 """print the header of the topmost or specified patch
2719
2719
2720 Returns 0 on success."""
2720 Returns 0 on success."""
2721 q = repo.mq
2721 q = repo.mq
2722
2722
2723 if patch:
2723 if patch:
2724 patch = q.lookup(patch)
2724 patch = q.lookup(patch)
2725 else:
2725 else:
2726 if not q.applied:
2726 if not q.applied:
2727 ui.write(_('no patches applied\n'))
2727 ui.write(_('no patches applied\n'))
2728 return 1
2728 return 1
2729 patch = q.lookup('qtip')
2729 patch = q.lookup('qtip')
2730 ph = patchheader(q.join(patch), q.plainmode)
2730 ph = patchheader(q.join(patch), q.plainmode)
2731
2731
2732 ui.write('\n'.join(ph.message) + '\n')
2732 ui.write('\n'.join(ph.message) + '\n')
2733
2733
2734 def lastsavename(path):
2734 def lastsavename(path):
2735 (directory, base) = os.path.split(path)
2735 (directory, base) = os.path.split(path)
2736 names = os.listdir(directory)
2736 names = os.listdir(directory)
2737 namere = re.compile("%s.([0-9]+)" % base)
2737 namere = re.compile("%s.([0-9]+)" % base)
2738 maxindex = None
2738 maxindex = None
2739 maxname = None
2739 maxname = None
2740 for f in names:
2740 for f in names:
2741 m = namere.match(f)
2741 m = namere.match(f)
2742 if m:
2742 if m:
2743 index = int(m.group(1))
2743 index = int(m.group(1))
2744 if maxindex is None or index > maxindex:
2744 if maxindex is None or index > maxindex:
2745 maxindex = index
2745 maxindex = index
2746 maxname = f
2746 maxname = f
2747 if maxname:
2747 if maxname:
2748 return (os.path.join(directory, maxname), maxindex)
2748 return (os.path.join(directory, maxname), maxindex)
2749 return (None, None)
2749 return (None, None)
2750
2750
2751 def savename(path):
2751 def savename(path):
2752 (last, index) = lastsavename(path)
2752 (last, index) = lastsavename(path)
2753 if last is None:
2753 if last is None:
2754 index = 0
2754 index = 0
2755 newpath = path + ".%d" % (index + 1)
2755 newpath = path + ".%d" % (index + 1)
2756 return newpath
2756 return newpath
2757
2757
2758 @command("^qpush",
2758 @command("^qpush",
2759 [('', 'keep-changes', None,
2759 [('', 'keep-changes', None,
2760 _('tolerate non-conflicting local changes')),
2760 _('tolerate non-conflicting local changes')),
2761 ('f', 'force', None, _('apply on top of local changes')),
2761 ('f', 'force', None, _('apply on top of local changes')),
2762 ('e', 'exact', None,
2762 ('e', 'exact', None,
2763 _('apply the target patch to its recorded parent')),
2763 _('apply the target patch to its recorded parent')),
2764 ('l', 'list', None, _('list patch name in commit text')),
2764 ('l', 'list', None, _('list patch name in commit text')),
2765 ('a', 'all', None, _('apply all patches')),
2765 ('a', 'all', None, _('apply all patches')),
2766 ('m', 'merge', None, _('merge from another queue (DEPRECATED)')),
2766 ('m', 'merge', None, _('merge from another queue (DEPRECATED)')),
2767 ('n', 'name', '',
2767 ('n', 'name', '',
2768 _('merge queue name (DEPRECATED)'), _('NAME')),
2768 _('merge queue name (DEPRECATED)'), _('NAME')),
2769 ('', 'move', None,
2769 ('', 'move', None,
2770 _('reorder patch series and apply only the patch')),
2770 _('reorder patch series and apply only the patch')),
2771 ('', 'no-backup', None, _('do not save backup copies of files'))],
2771 ('', 'no-backup', None, _('do not save backup copies of files'))],
2772 _('hg qpush [-f] [-l] [-a] [--move] [PATCH | INDEX]'))
2772 _('hg qpush [-f] [-l] [-a] [--move] [PATCH | INDEX]'))
2773 def push(ui, repo, patch=None, **opts):
2773 def push(ui, repo, patch=None, **opts):
2774 """push the next patch onto the stack
2774 """push the next patch onto the stack
2775
2775
2776 By default, abort if the working directory contains uncommitted
2776 By default, abort if the working directory contains uncommitted
2777 changes. With --keep-changes, abort only if the uncommitted files
2777 changes. With --keep-changes, abort only if the uncommitted files
2778 overlap with patched files. With -f/--force, backup and patch over
2778 overlap with patched files. With -f/--force, backup and patch over
2779 uncommitted changes.
2779 uncommitted changes.
2780
2780
2781 Return 0 on success.
2781 Return 0 on success.
2782 """
2782 """
2783 q = repo.mq
2783 q = repo.mq
2784 mergeq = None
2784 mergeq = None
2785
2785
2786 opts = fixkeepchangesopts(ui, opts)
2786 opts = fixkeepchangesopts(ui, opts)
2787 if opts.get('merge'):
2787 if opts.get('merge'):
2788 if opts.get('name'):
2788 if opts.get('name'):
2789 newpath = repo.join(opts.get('name'))
2789 newpath = repo.join(opts.get('name'))
2790 else:
2790 else:
2791 newpath, i = lastsavename(q.path)
2791 newpath, i = lastsavename(q.path)
2792 if not newpath:
2792 if not newpath:
2793 ui.warn(_("no saved queues found, please use -n\n"))
2793 ui.warn(_("no saved queues found, please use -n\n"))
2794 return 1
2794 return 1
2795 mergeq = queue(ui, repo.baseui, repo.path, newpath)
2795 mergeq = queue(ui, repo.baseui, repo.path, newpath)
2796 ui.warn(_("merging with queue at: %s\n") % mergeq.path)
2796 ui.warn(_("merging with queue at: %s\n") % mergeq.path)
2797 ret = q.push(repo, patch, force=opts.get('force'), list=opts.get('list'),
2797 ret = q.push(repo, patch, force=opts.get('force'), list=opts.get('list'),
2798 mergeq=mergeq, all=opts.get('all'), move=opts.get('move'),
2798 mergeq=mergeq, all=opts.get('all'), move=opts.get('move'),
2799 exact=opts.get('exact'), nobackup=opts.get('no_backup'),
2799 exact=opts.get('exact'), nobackup=opts.get('no_backup'),
2800 keepchanges=opts.get('keep_changes'))
2800 keepchanges=opts.get('keep_changes'))
2801 return ret
2801 return ret
2802
2802
2803 @command("^qpop",
2803 @command("^qpop",
2804 [('a', 'all', None, _('pop all patches')),
2804 [('a', 'all', None, _('pop all patches')),
2805 ('n', 'name', '',
2805 ('n', 'name', '',
2806 _('queue name to pop (DEPRECATED)'), _('NAME')),
2806 _('queue name to pop (DEPRECATED)'), _('NAME')),
2807 ('', 'keep-changes', None,
2807 ('', 'keep-changes', None,
2808 _('tolerate non-conflicting local changes')),
2808 _('tolerate non-conflicting local changes')),
2809 ('f', 'force', None, _('forget any local changes to patched files')),
2809 ('f', 'force', None, _('forget any local changes to patched files')),
2810 ('', 'no-backup', None, _('do not save backup copies of files'))],
2810 ('', 'no-backup', None, _('do not save backup copies of files'))],
2811 _('hg qpop [-a] [-f] [PATCH | INDEX]'))
2811 _('hg qpop [-a] [-f] [PATCH | INDEX]'))
2812 def pop(ui, repo, patch=None, **opts):
2812 def pop(ui, repo, patch=None, **opts):
2813 """pop the current patch off the stack
2813 """pop the current patch off the stack
2814
2814
2815 Without argument, pops off the top of the patch stack. If given a
2815 Without argument, pops off the top of the patch stack. If given a
2816 patch name, keeps popping off patches until the named patch is at
2816 patch name, keeps popping off patches until the named patch is at
2817 the top of the stack.
2817 the top of the stack.
2818
2818
2819 By default, abort if the working directory contains uncommitted
2819 By default, abort if the working directory contains uncommitted
2820 changes. With --keep-changes, abort only if the uncommitted files
2820 changes. With --keep-changes, abort only if the uncommitted files
2821 overlap with patched files. With -f/--force, backup and discard
2821 overlap with patched files. With -f/--force, backup and discard
2822 changes made to such files.
2822 changes made to such files.
2823
2823
2824 Return 0 on success.
2824 Return 0 on success.
2825 """
2825 """
2826 opts = fixkeepchangesopts(ui, opts)
2826 opts = fixkeepchangesopts(ui, opts)
2827 localupdate = True
2827 localupdate = True
2828 if opts.get('name'):
2828 if opts.get('name'):
2829 q = queue(ui, repo.baseui, repo.path, repo.join(opts.get('name')))
2829 q = queue(ui, repo.baseui, repo.path, repo.join(opts.get('name')))
2830 ui.warn(_('using patch queue: %s\n') % q.path)
2830 ui.warn(_('using patch queue: %s\n') % q.path)
2831 localupdate = False
2831 localupdate = False
2832 else:
2832 else:
2833 q = repo.mq
2833 q = repo.mq
2834 ret = q.pop(repo, patch, force=opts.get('force'), update=localupdate,
2834 ret = q.pop(repo, patch, force=opts.get('force'), update=localupdate,
2835 all=opts.get('all'), nobackup=opts.get('no_backup'),
2835 all=opts.get('all'), nobackup=opts.get('no_backup'),
2836 keepchanges=opts.get('keep_changes'))
2836 keepchanges=opts.get('keep_changes'))
2837 q.savedirty()
2837 q.savedirty()
2838 return ret
2838 return ret
2839
2839
2840 @command("qrename|qmv", [], _('hg qrename PATCH1 [PATCH2]'))
2840 @command("qrename|qmv", [], _('hg qrename PATCH1 [PATCH2]'))
2841 def rename(ui, repo, patch, name=None, **opts):
2841 def rename(ui, repo, patch, name=None, **opts):
2842 """rename a patch
2842 """rename a patch
2843
2843
2844 With one argument, renames the current patch to PATCH1.
2844 With one argument, renames the current patch to PATCH1.
2845 With two arguments, renames PATCH1 to PATCH2.
2845 With two arguments, renames PATCH1 to PATCH2.
2846
2846
2847 Returns 0 on success."""
2847 Returns 0 on success."""
2848 q = repo.mq
2848 q = repo.mq
2849 if not name:
2849 if not name:
2850 name = patch
2850 name = patch
2851 patch = None
2851 patch = None
2852
2852
2853 if patch:
2853 if patch:
2854 patch = q.lookup(patch)
2854 patch = q.lookup(patch)
2855 else:
2855 else:
2856 if not q.applied:
2856 if not q.applied:
2857 ui.write(_('no patches applied\n'))
2857 ui.write(_('no patches applied\n'))
2858 return
2858 return
2859 patch = q.lookup('qtip')
2859 patch = q.lookup('qtip')
2860 absdest = q.join(name)
2860 absdest = q.join(name)
2861 if os.path.isdir(absdest):
2861 if os.path.isdir(absdest):
2862 name = normname(os.path.join(name, os.path.basename(patch)))
2862 name = normname(os.path.join(name, os.path.basename(patch)))
2863 absdest = q.join(name)
2863 absdest = q.join(name)
2864 q.checkpatchname(name)
2864 q.checkpatchname(name)
2865
2865
2866 ui.note(_('renaming %s to %s\n') % (patch, name))
2866 ui.note(_('renaming %s to %s\n') % (patch, name))
2867 i = q.findseries(patch)
2867 i = q.findseries(patch)
2868 guards = q.guard_re.findall(q.fullseries[i])
2868 guards = q.guard_re.findall(q.fullseries[i])
2869 q.fullseries[i] = name + ''.join([' #' + g for g in guards])
2869 q.fullseries[i] = name + ''.join([' #' + g for g in guards])
2870 q.parseseries()
2870 q.parseseries()
2871 q.seriesdirty = True
2871 q.seriesdirty = True
2872
2872
2873 info = q.isapplied(patch)
2873 info = q.isapplied(patch)
2874 if info:
2874 if info:
2875 q.applied[info[0]] = statusentry(info[1], name)
2875 q.applied[info[0]] = statusentry(info[1], name)
2876 q.applieddirty = True
2876 q.applieddirty = True
2877
2877
2878 destdir = os.path.dirname(absdest)
2878 destdir = os.path.dirname(absdest)
2879 if not os.path.isdir(destdir):
2879 if not os.path.isdir(destdir):
2880 os.makedirs(destdir)
2880 os.makedirs(destdir)
2881 util.rename(q.join(patch), absdest)
2881 util.rename(q.join(patch), absdest)
2882 r = q.qrepo()
2882 r = q.qrepo()
2883 if r and patch in r.dirstate:
2883 if r and patch in r.dirstate:
2884 wctx = r[None]
2884 wctx = r[None]
2885 wlock = r.wlock()
2885 wlock = r.wlock()
2886 try:
2886 try:
2887 if r.dirstate[patch] == 'a':
2887 if r.dirstate[patch] == 'a':
2888 r.dirstate.drop(patch)
2888 r.dirstate.drop(patch)
2889 r.dirstate.add(name)
2889 r.dirstate.add(name)
2890 else:
2890 else:
2891 wctx.copy(patch, name)
2891 wctx.copy(patch, name)
2892 wctx.forget([patch])
2892 wctx.forget([patch])
2893 finally:
2893 finally:
2894 wlock.release()
2894 wlock.release()
2895
2895
2896 q.savedirty()
2896 q.savedirty()
2897
2897
2898 @command("qrestore",
2898 @command("qrestore",
2899 [('d', 'delete', None, _('delete save entry')),
2899 [('d', 'delete', None, _('delete save entry')),
2900 ('u', 'update', None, _('update queue working directory'))],
2900 ('u', 'update', None, _('update queue working directory'))],
2901 _('hg qrestore [-d] [-u] REV'))
2901 _('hg qrestore [-d] [-u] REV'))
2902 def restore(ui, repo, rev, **opts):
2902 def restore(ui, repo, rev, **opts):
2903 """restore the queue state saved by a revision (DEPRECATED)
2903 """restore the queue state saved by a revision (DEPRECATED)
2904
2904
2905 This command is deprecated, use :hg:`rebase` instead."""
2905 This command is deprecated, use :hg:`rebase` instead."""
2906 rev = repo.lookup(rev)
2906 rev = repo.lookup(rev)
2907 q = repo.mq
2907 q = repo.mq
2908 q.restore(repo, rev, delete=opts.get('delete'),
2908 q.restore(repo, rev, delete=opts.get('delete'),
2909 qupdate=opts.get('update'))
2909 qupdate=opts.get('update'))
2910 q.savedirty()
2910 q.savedirty()
2911 return 0
2911 return 0
2912
2912
2913 @command("qsave",
2913 @command("qsave",
2914 [('c', 'copy', None, _('copy patch directory')),
2914 [('c', 'copy', None, _('copy patch directory')),
2915 ('n', 'name', '',
2915 ('n', 'name', '',
2916 _('copy directory name'), _('NAME')),
2916 _('copy directory name'), _('NAME')),
2917 ('e', 'empty', None, _('clear queue status file')),
2917 ('e', 'empty', None, _('clear queue status file')),
2918 ('f', 'force', None, _('force copy'))] + commands.commitopts,
2918 ('f', 'force', None, _('force copy'))] + commands.commitopts,
2919 _('hg qsave [-m TEXT] [-l FILE] [-c] [-n NAME] [-e] [-f]'))
2919 _('hg qsave [-m TEXT] [-l FILE] [-c] [-n NAME] [-e] [-f]'))
2920 def save(ui, repo, **opts):
2920 def save(ui, repo, **opts):
2921 """save current queue state (DEPRECATED)
2921 """save current queue state (DEPRECATED)
2922
2922
2923 This command is deprecated, use :hg:`rebase` instead."""
2923 This command is deprecated, use :hg:`rebase` instead."""
2924 q = repo.mq
2924 q = repo.mq
2925 message = cmdutil.logmessage(ui, opts)
2925 message = cmdutil.logmessage(ui, opts)
2926 ret = q.save(repo, msg=message)
2926 ret = q.save(repo, msg=message)
2927 if ret:
2927 if ret:
2928 return ret
2928 return ret
2929 q.savedirty() # save to .hg/patches before copying
2929 q.savedirty() # save to .hg/patches before copying
2930 if opts.get('copy'):
2930 if opts.get('copy'):
2931 path = q.path
2931 path = q.path
2932 if opts.get('name'):
2932 if opts.get('name'):
2933 newpath = os.path.join(q.basepath, opts.get('name'))
2933 newpath = os.path.join(q.basepath, opts.get('name'))
2934 if os.path.exists(newpath):
2934 if os.path.exists(newpath):
2935 if not os.path.isdir(newpath):
2935 if not os.path.isdir(newpath):
2936 raise util.Abort(_('destination %s exists and is not '
2936 raise util.Abort(_('destination %s exists and is not '
2937 'a directory') % newpath)
2937 'a directory') % newpath)
2938 if not opts.get('force'):
2938 if not opts.get('force'):
2939 raise util.Abort(_('destination %s exists, '
2939 raise util.Abort(_('destination %s exists, '
2940 'use -f to force') % newpath)
2940 'use -f to force') % newpath)
2941 else:
2941 else:
2942 newpath = savename(path)
2942 newpath = savename(path)
2943 ui.warn(_("copy %s to %s\n") % (path, newpath))
2943 ui.warn(_("copy %s to %s\n") % (path, newpath))
2944 util.copyfiles(path, newpath)
2944 util.copyfiles(path, newpath)
2945 if opts.get('empty'):
2945 if opts.get('empty'):
2946 del q.applied[:]
2946 del q.applied[:]
2947 q.applieddirty = True
2947 q.applieddirty = True
2948 q.savedirty()
2948 q.savedirty()
2949 return 0
2949 return 0
2950
2950
2951
2951
2952 @command("qselect",
2952 @command("qselect",
2953 [('n', 'none', None, _('disable all guards')),
2953 [('n', 'none', None, _('disable all guards')),
2954 ('s', 'series', None, _('list all guards in series file')),
2954 ('s', 'series', None, _('list all guards in series file')),
2955 ('', 'pop', None, _('pop to before first guarded applied patch')),
2955 ('', 'pop', None, _('pop to before first guarded applied patch')),
2956 ('', 'reapply', None, _('pop, then reapply patches'))],
2956 ('', 'reapply', None, _('pop, then reapply patches'))],
2957 _('hg qselect [OPTION]... [GUARD]...'))
2957 _('hg qselect [OPTION]... [GUARD]...'))
2958 def select(ui, repo, *args, **opts):
2958 def select(ui, repo, *args, **opts):
2959 '''set or print guarded patches to push
2959 '''set or print guarded patches to push
2960
2960
2961 Use the :hg:`qguard` command to set or print guards on patch, then use
2961 Use the :hg:`qguard` command to set or print guards on patch, then use
2962 qselect to tell mq which guards to use. A patch will be pushed if
2962 qselect to tell mq which guards to use. A patch will be pushed if
2963 it has no guards or any positive guards match the currently
2963 it has no guards or any positive guards match the currently
2964 selected guard, but will not be pushed if any negative guards
2964 selected guard, but will not be pushed if any negative guards
2965 match the current guard. For example::
2965 match the current guard. For example::
2966
2966
2967 qguard foo.patch -- -stable (negative guard)
2967 qguard foo.patch -- -stable (negative guard)
2968 qguard bar.patch +stable (positive guard)
2968 qguard bar.patch +stable (positive guard)
2969 qselect stable
2969 qselect stable
2970
2970
2971 This activates the "stable" guard. mq will skip foo.patch (because
2971 This activates the "stable" guard. mq will skip foo.patch (because
2972 it has a negative match) but push bar.patch (because it has a
2972 it has a negative match) but push bar.patch (because it has a
2973 positive match).
2973 positive match).
2974
2974
2975 With no arguments, prints the currently active guards.
2975 With no arguments, prints the currently active guards.
2976 With one argument, sets the active guard.
2976 With one argument, sets the active guard.
2977
2977
2978 Use -n/--none to deactivate guards (no other arguments needed).
2978 Use -n/--none to deactivate guards (no other arguments needed).
2979 When no guards are active, patches with positive guards are
2979 When no guards are active, patches with positive guards are
2980 skipped and patches with negative guards are pushed.
2980 skipped and patches with negative guards are pushed.
2981
2981
2982 qselect can change the guards on applied patches. It does not pop
2982 qselect can change the guards on applied patches. It does not pop
2983 guarded patches by default. Use --pop to pop back to the last
2983 guarded patches by default. Use --pop to pop back to the last
2984 applied patch that is not guarded. Use --reapply (which implies
2984 applied patch that is not guarded. Use --reapply (which implies
2985 --pop) to push back to the current patch afterwards, but skip
2985 --pop) to push back to the current patch afterwards, but skip
2986 guarded patches.
2986 guarded patches.
2987
2987
2988 Use -s/--series to print a list of all guards in the series file
2988 Use -s/--series to print a list of all guards in the series file
2989 (no other arguments needed). Use -v for more information.
2989 (no other arguments needed). Use -v for more information.
2990
2990
2991 Returns 0 on success.'''
2991 Returns 0 on success.'''
2992
2992
2993 q = repo.mq
2993 q = repo.mq
2994 guards = q.active()
2994 guards = q.active()
2995 pushable = lambda i: q.pushable(q.applied[i].name)[0]
2995 pushable = lambda i: q.pushable(q.applied[i].name)[0]
2996 if args or opts.get('none'):
2996 if args or opts.get('none'):
2997 old_unapplied = q.unapplied(repo)
2997 old_unapplied = q.unapplied(repo)
2998 old_guarded = [i for i in xrange(len(q.applied)) if not pushable(i)]
2998 old_guarded = [i for i in xrange(len(q.applied)) if not pushable(i)]
2999 q.setactive(args)
2999 q.setactive(args)
3000 q.savedirty()
3000 q.savedirty()
3001 if not args:
3001 if not args:
3002 ui.status(_('guards deactivated\n'))
3002 ui.status(_('guards deactivated\n'))
3003 if not opts.get('pop') and not opts.get('reapply'):
3003 if not opts.get('pop') and not opts.get('reapply'):
3004 unapplied = q.unapplied(repo)
3004 unapplied = q.unapplied(repo)
3005 guarded = [i for i in xrange(len(q.applied)) if not pushable(i)]
3005 guarded = [i for i in xrange(len(q.applied)) if not pushable(i)]
3006 if len(unapplied) != len(old_unapplied):
3006 if len(unapplied) != len(old_unapplied):
3007 ui.status(_('number of unguarded, unapplied patches has '
3007 ui.status(_('number of unguarded, unapplied patches has '
3008 'changed from %d to %d\n') %
3008 'changed from %d to %d\n') %
3009 (len(old_unapplied), len(unapplied)))
3009 (len(old_unapplied), len(unapplied)))
3010 if len(guarded) != len(old_guarded):
3010 if len(guarded) != len(old_guarded):
3011 ui.status(_('number of guarded, applied patches has changed '
3011 ui.status(_('number of guarded, applied patches has changed '
3012 'from %d to %d\n') %
3012 'from %d to %d\n') %
3013 (len(old_guarded), len(guarded)))
3013 (len(old_guarded), len(guarded)))
3014 elif opts.get('series'):
3014 elif opts.get('series'):
3015 guards = {}
3015 guards = {}
3016 noguards = 0
3016 noguards = 0
3017 for gs in q.seriesguards:
3017 for gs in q.seriesguards:
3018 if not gs:
3018 if not gs:
3019 noguards += 1
3019 noguards += 1
3020 for g in gs:
3020 for g in gs:
3021 guards.setdefault(g, 0)
3021 guards.setdefault(g, 0)
3022 guards[g] += 1
3022 guards[g] += 1
3023 if ui.verbose:
3023 if ui.verbose:
3024 guards['NONE'] = noguards
3024 guards['NONE'] = noguards
3025 guards = guards.items()
3025 guards = guards.items()
3026 guards.sort(key=lambda x: x[0][1:])
3026 guards.sort(key=lambda x: x[0][1:])
3027 if guards:
3027 if guards:
3028 ui.note(_('guards in series file:\n'))
3028 ui.note(_('guards in series file:\n'))
3029 for guard, count in guards:
3029 for guard, count in guards:
3030 ui.note('%2d ' % count)
3030 ui.note('%2d ' % count)
3031 ui.write(guard, '\n')
3031 ui.write(guard, '\n')
3032 else:
3032 else:
3033 ui.note(_('no guards in series file\n'))
3033 ui.note(_('no guards in series file\n'))
3034 else:
3034 else:
3035 if guards:
3035 if guards:
3036 ui.note(_('active guards:\n'))
3036 ui.note(_('active guards:\n'))
3037 for g in guards:
3037 for g in guards:
3038 ui.write(g, '\n')
3038 ui.write(g, '\n')
3039 else:
3039 else:
3040 ui.write(_('no active guards\n'))
3040 ui.write(_('no active guards\n'))
3041 reapply = opts.get('reapply') and q.applied and q.applied[-1].name
3041 reapply = opts.get('reapply') and q.applied and q.applied[-1].name
3042 popped = False
3042 popped = False
3043 if opts.get('pop') or opts.get('reapply'):
3043 if opts.get('pop') or opts.get('reapply'):
3044 for i in xrange(len(q.applied)):
3044 for i in xrange(len(q.applied)):
3045 if not pushable(i):
3045 if not pushable(i):
3046 ui.status(_('popping guarded patches\n'))
3046 ui.status(_('popping guarded patches\n'))
3047 popped = True
3047 popped = True
3048 if i == 0:
3048 if i == 0:
3049 q.pop(repo, all=True)
3049 q.pop(repo, all=True)
3050 else:
3050 else:
3051 q.pop(repo, q.applied[i - 1].name)
3051 q.pop(repo, q.applied[i - 1].name)
3052 break
3052 break
3053 if popped:
3053 if popped:
3054 try:
3054 try:
3055 if reapply:
3055 if reapply:
3056 ui.status(_('reapplying unguarded patches\n'))
3056 ui.status(_('reapplying unguarded patches\n'))
3057 q.push(repo, reapply)
3057 q.push(repo, reapply)
3058 finally:
3058 finally:
3059 q.savedirty()
3059 q.savedirty()
3060
3060
3061 @command("qfinish",
3061 @command("qfinish",
3062 [('a', 'applied', None, _('finish all applied changesets'))],
3062 [('a', 'applied', None, _('finish all applied changesets'))],
3063 _('hg qfinish [-a] [REV]...'))
3063 _('hg qfinish [-a] [REV]...'))
3064 def finish(ui, repo, *revrange, **opts):
3064 def finish(ui, repo, *revrange, **opts):
3065 """move applied patches into repository history
3065 """move applied patches into repository history
3066
3066
3067 Finishes the specified revisions (corresponding to applied
3067 Finishes the specified revisions (corresponding to applied
3068 patches) by moving them out of mq control into regular repository
3068 patches) by moving them out of mq control into regular repository
3069 history.
3069 history.
3070
3070
3071 Accepts a revision range or the -a/--applied option. If --applied
3071 Accepts a revision range or the -a/--applied option. If --applied
3072 is specified, all applied mq revisions are removed from mq
3072 is specified, all applied mq revisions are removed from mq
3073 control. Otherwise, the given revisions must be at the base of the
3073 control. Otherwise, the given revisions must be at the base of the
3074 stack of applied patches.
3074 stack of applied patches.
3075
3075
3076 This can be especially useful if your changes have been applied to
3076 This can be especially useful if your changes have been applied to
3077 an upstream repository, or if you are about to push your changes
3077 an upstream repository, or if you are about to push your changes
3078 to upstream.
3078 to upstream.
3079
3079
3080 Returns 0 on success.
3080 Returns 0 on success.
3081 """
3081 """
3082 if not opts.get('applied') and not revrange:
3082 if not opts.get('applied') and not revrange:
3083 raise util.Abort(_('no revisions specified'))
3083 raise util.Abort(_('no revisions specified'))
3084 elif opts.get('applied'):
3084 elif opts.get('applied'):
3085 revrange = ('qbase::qtip',) + revrange
3085 revrange = ('qbase::qtip',) + revrange
3086
3086
3087 q = repo.mq
3087 q = repo.mq
3088 if not q.applied:
3088 if not q.applied:
3089 ui.status(_('no patches applied\n'))
3089 ui.status(_('no patches applied\n'))
3090 return 0
3090 return 0
3091
3091
3092 revs = scmutil.revrange(repo, revrange)
3092 revs = scmutil.revrange(repo, revrange)
3093 if repo['.'].rev() in revs and repo[None].files():
3093 if repo['.'].rev() in revs and repo[None].files():
3094 ui.warn(_('warning: uncommitted changes in the working directory\n'))
3094 ui.warn(_('warning: uncommitted changes in the working directory\n'))
3095 # queue.finish may changes phases but leave the responsibility to lock the
3095 # queue.finish may changes phases but leave the responsibility to lock the
3096 # repo to the caller to avoid deadlock with wlock. This command code is
3096 # repo to the caller to avoid deadlock with wlock. This command code is
3097 # responsibility for this locking.
3097 # responsibility for this locking.
3098 lock = repo.lock()
3098 lock = repo.lock()
3099 try:
3099 try:
3100 q.finish(repo, revs)
3100 q.finish(repo, revs)
3101 q.savedirty()
3101 q.savedirty()
3102 finally:
3102 finally:
3103 lock.release()
3103 lock.release()
3104 return 0
3104 return 0
3105
3105
3106 @command("qqueue",
3106 @command("qqueue",
3107 [('l', 'list', False, _('list all available queues')),
3107 [('l', 'list', False, _('list all available queues')),
3108 ('', 'active', False, _('print name of active queue')),
3108 ('', 'active', False, _('print name of active queue')),
3109 ('c', 'create', False, _('create new queue')),
3109 ('c', 'create', False, _('create new queue')),
3110 ('', 'rename', False, _('rename active queue')),
3110 ('', 'rename', False, _('rename active queue')),
3111 ('', 'delete', False, _('delete reference to queue')),
3111 ('', 'delete', False, _('delete reference to queue')),
3112 ('', 'purge', False, _('delete queue, and remove patch dir')),
3112 ('', 'purge', False, _('delete queue, and remove patch dir')),
3113 ],
3113 ],
3114 _('[OPTION] [QUEUE]'))
3114 _('[OPTION] [QUEUE]'))
3115 def qqueue(ui, repo, name=None, **opts):
3115 def qqueue(ui, repo, name=None, **opts):
3116 '''manage multiple patch queues
3116 '''manage multiple patch queues
3117
3117
3118 Supports switching between different patch queues, as well as creating
3118 Supports switching between different patch queues, as well as creating
3119 new patch queues and deleting existing ones.
3119 new patch queues and deleting existing ones.
3120
3120
3121 Omitting a queue name or specifying -l/--list will show you the registered
3121 Omitting a queue name or specifying -l/--list will show you the registered
3122 queues - by default the "normal" patches queue is registered. The currently
3122 queues - by default the "normal" patches queue is registered. The currently
3123 active queue will be marked with "(active)". Specifying --active will print
3123 active queue will be marked with "(active)". Specifying --active will print
3124 only the name of the active queue.
3124 only the name of the active queue.
3125
3125
3126 To create a new queue, use -c/--create. The queue is automatically made
3126 To create a new queue, use -c/--create. The queue is automatically made
3127 active, except in the case where there are applied patches from the
3127 active, except in the case where there are applied patches from the
3128 currently active queue in the repository. Then the queue will only be
3128 currently active queue in the repository. Then the queue will only be
3129 created and switching will fail.
3129 created and switching will fail.
3130
3130
3131 To delete an existing queue, use --delete. You cannot delete the currently
3131 To delete an existing queue, use --delete. You cannot delete the currently
3132 active queue.
3132 active queue.
3133
3133
3134 Returns 0 on success.
3134 Returns 0 on success.
3135 '''
3135 '''
3136 q = repo.mq
3136 q = repo.mq
3137 _defaultqueue = 'patches'
3137 _defaultqueue = 'patches'
3138 _allqueues = 'patches.queues'
3138 _allqueues = 'patches.queues'
3139 _activequeue = 'patches.queue'
3139 _activequeue = 'patches.queue'
3140
3140
3141 def _getcurrent():
3141 def _getcurrent():
3142 cur = os.path.basename(q.path)
3142 cur = os.path.basename(q.path)
3143 if cur.startswith('patches-'):
3143 if cur.startswith('patches-'):
3144 cur = cur[8:]
3144 cur = cur[8:]
3145 return cur
3145 return cur
3146
3146
3147 def _noqueues():
3147 def _noqueues():
3148 try:
3148 try:
3149 fh = repo.opener(_allqueues, 'r')
3149 fh = repo.opener(_allqueues, 'r')
3150 fh.close()
3150 fh.close()
3151 except IOError:
3151 except IOError:
3152 return True
3152 return True
3153
3153
3154 return False
3154 return False
3155
3155
3156 def _getqueues():
3156 def _getqueues():
3157 current = _getcurrent()
3157 current = _getcurrent()
3158
3158
3159 try:
3159 try:
3160 fh = repo.opener(_allqueues, 'r')
3160 fh = repo.opener(_allqueues, 'r')
3161 queues = [queue.strip() for queue in fh if queue.strip()]
3161 queues = [queue.strip() for queue in fh if queue.strip()]
3162 fh.close()
3162 fh.close()
3163 if current not in queues:
3163 if current not in queues:
3164 queues.append(current)
3164 queues.append(current)
3165 except IOError:
3165 except IOError:
3166 queues = [_defaultqueue]
3166 queues = [_defaultqueue]
3167
3167
3168 return sorted(queues)
3168 return sorted(queues)
3169
3169
3170 def _setactive(name):
3170 def _setactive(name):
3171 if q.applied:
3171 if q.applied:
3172 raise util.Abort(_('new queue created, but cannot make active '
3172 raise util.Abort(_('new queue created, but cannot make active '
3173 'as patches are applied'))
3173 'as patches are applied'))
3174 _setactivenocheck(name)
3174 _setactivenocheck(name)
3175
3175
3176 def _setactivenocheck(name):
3176 def _setactivenocheck(name):
3177 fh = repo.opener(_activequeue, 'w')
3177 fh = repo.opener(_activequeue, 'w')
3178 if name != 'patches':
3178 if name != 'patches':
3179 fh.write(name)
3179 fh.write(name)
3180 fh.close()
3180 fh.close()
3181
3181
3182 def _addqueue(name):
3182 def _addqueue(name):
3183 fh = repo.opener(_allqueues, 'a')
3183 fh = repo.opener(_allqueues, 'a')
3184 fh.write('%s\n' % (name,))
3184 fh.write('%s\n' % (name,))
3185 fh.close()
3185 fh.close()
3186
3186
3187 def _queuedir(name):
3187 def _queuedir(name):
3188 if name == 'patches':
3188 if name == 'patches':
3189 return repo.join('patches')
3189 return repo.join('patches')
3190 else:
3190 else:
3191 return repo.join('patches-' + name)
3191 return repo.join('patches-' + name)
3192
3192
3193 def _validname(name):
3193 def _validname(name):
3194 for n in name:
3194 for n in name:
3195 if n in ':\\/.':
3195 if n in ':\\/.':
3196 return False
3196 return False
3197 return True
3197 return True
3198
3198
3199 def _delete(name):
3199 def _delete(name):
3200 if name not in existing:
3200 if name not in existing:
3201 raise util.Abort(_('cannot delete queue that does not exist'))
3201 raise util.Abort(_('cannot delete queue that does not exist'))
3202
3202
3203 current = _getcurrent()
3203 current = _getcurrent()
3204
3204
3205 if name == current:
3205 if name == current:
3206 raise util.Abort(_('cannot delete currently active queue'))
3206 raise util.Abort(_('cannot delete currently active queue'))
3207
3207
3208 fh = repo.opener('patches.queues.new', 'w')
3208 fh = repo.opener('patches.queues.new', 'w')
3209 for queue in existing:
3209 for queue in existing:
3210 if queue == name:
3210 if queue == name:
3211 continue
3211 continue
3212 fh.write('%s\n' % (queue,))
3212 fh.write('%s\n' % (queue,))
3213 fh.close()
3213 fh.close()
3214 util.rename(repo.join('patches.queues.new'), repo.join(_allqueues))
3214 util.rename(repo.join('patches.queues.new'), repo.join(_allqueues))
3215
3215
3216 if not name or opts.get('list') or opts.get('active'):
3216 if not name or opts.get('list') or opts.get('active'):
3217 current = _getcurrent()
3217 current = _getcurrent()
3218 if opts.get('active'):
3218 if opts.get('active'):
3219 ui.write('%s\n' % (current,))
3219 ui.write('%s\n' % (current,))
3220 return
3220 return
3221 for queue in _getqueues():
3221 for queue in _getqueues():
3222 ui.write('%s' % (queue,))
3222 ui.write('%s' % (queue,))
3223 if queue == current and not ui.quiet:
3223 if queue == current and not ui.quiet:
3224 ui.write(_(' (active)\n'))
3224 ui.write(_(' (active)\n'))
3225 else:
3225 else:
3226 ui.write('\n')
3226 ui.write('\n')
3227 return
3227 return
3228
3228
3229 if not _validname(name):
3229 if not _validname(name):
3230 raise util.Abort(
3230 raise util.Abort(
3231 _('invalid queue name, may not contain the characters ":\\/."'))
3231 _('invalid queue name, may not contain the characters ":\\/."'))
3232
3232
3233 existing = _getqueues()
3233 existing = _getqueues()
3234
3234
3235 if opts.get('create'):
3235 if opts.get('create'):
3236 if name in existing:
3236 if name in existing:
3237 raise util.Abort(_('queue "%s" already exists') % name)
3237 raise util.Abort(_('queue "%s" already exists') % name)
3238 if _noqueues():
3238 if _noqueues():
3239 _addqueue(_defaultqueue)
3239 _addqueue(_defaultqueue)
3240 _addqueue(name)
3240 _addqueue(name)
3241 _setactive(name)
3241 _setactive(name)
3242 elif opts.get('rename'):
3242 elif opts.get('rename'):
3243 current = _getcurrent()
3243 current = _getcurrent()
3244 if name == current:
3244 if name == current:
3245 raise util.Abort(_('can\'t rename "%s" to its current name') % name)
3245 raise util.Abort(_('can\'t rename "%s" to its current name') % name)
3246 if name in existing:
3246 if name in existing:
3247 raise util.Abort(_('queue "%s" already exists') % name)
3247 raise util.Abort(_('queue "%s" already exists') % name)
3248
3248
3249 olddir = _queuedir(current)
3249 olddir = _queuedir(current)
3250 newdir = _queuedir(name)
3250 newdir = _queuedir(name)
3251
3251
3252 if os.path.exists(newdir):
3252 if os.path.exists(newdir):
3253 raise util.Abort(_('non-queue directory "%s" already exists') %
3253 raise util.Abort(_('non-queue directory "%s" already exists') %
3254 newdir)
3254 newdir)
3255
3255
3256 fh = repo.opener('patches.queues.new', 'w')
3256 fh = repo.opener('patches.queues.new', 'w')
3257 for queue in existing:
3257 for queue in existing:
3258 if queue == current:
3258 if queue == current:
3259 fh.write('%s\n' % (name,))
3259 fh.write('%s\n' % (name,))
3260 if os.path.exists(olddir):
3260 if os.path.exists(olddir):
3261 util.rename(olddir, newdir)
3261 util.rename(olddir, newdir)
3262 else:
3262 else:
3263 fh.write('%s\n' % (queue,))
3263 fh.write('%s\n' % (queue,))
3264 fh.close()
3264 fh.close()
3265 util.rename(repo.join('patches.queues.new'), repo.join(_allqueues))
3265 util.rename(repo.join('patches.queues.new'), repo.join(_allqueues))
3266 _setactivenocheck(name)
3266 _setactivenocheck(name)
3267 elif opts.get('delete'):
3267 elif opts.get('delete'):
3268 _delete(name)
3268 _delete(name)
3269 elif opts.get('purge'):
3269 elif opts.get('purge'):
3270 if name in existing:
3270 if name in existing:
3271 _delete(name)
3271 _delete(name)
3272 qdir = _queuedir(name)
3272 qdir = _queuedir(name)
3273 if os.path.exists(qdir):
3273 if os.path.exists(qdir):
3274 shutil.rmtree(qdir)
3274 shutil.rmtree(qdir)
3275 else:
3275 else:
3276 if name not in existing:
3276 if name not in existing:
3277 raise util.Abort(_('use --create to create a new queue'))
3277 raise util.Abort(_('use --create to create a new queue'))
3278 _setactive(name)
3278 _setactive(name)
3279
3279
3280 def mqphasedefaults(repo, roots):
3280 def mqphasedefaults(repo, roots):
3281 """callback used to set mq changeset as secret when no phase data exists"""
3281 """callback used to set mq changeset as secret when no phase data exists"""
3282 if repo.mq.applied:
3282 if repo.mq.applied:
3283 if repo.ui.configbool('mq', 'secret', False):
3283 if repo.ui.configbool('mq', 'secret', False):
3284 mqphase = phases.secret
3284 mqphase = phases.secret
3285 else:
3285 else:
3286 mqphase = phases.draft
3286 mqphase = phases.draft
3287 qbase = repo[repo.mq.applied[0].node]
3287 qbase = repo[repo.mq.applied[0].node]
3288 roots[mqphase].add(qbase.node())
3288 roots[mqphase].add(qbase.node())
3289 return roots
3289 return roots
3290
3290
3291 def reposetup(ui, repo):
3291 def reposetup(ui, repo):
3292 class mqrepo(repo.__class__):
3292 class mqrepo(repo.__class__):
3293 @localrepo.unfilteredpropertycache
3293 @localrepo.unfilteredpropertycache
3294 def mq(self):
3294 def mq(self):
3295 return queue(self.ui, self.baseui, self.path)
3295 return queue(self.ui, self.baseui, self.path)
3296
3296
3297 def invalidateall(self):
3297 def invalidateall(self):
3298 super(mqrepo, self).invalidateall()
3298 super(mqrepo, self).invalidateall()
3299 if localrepo.hasunfilteredcache(self, 'mq'):
3299 if localrepo.hasunfilteredcache(self, 'mq'):
3300 # recreate mq in case queue path was changed
3300 # recreate mq in case queue path was changed
3301 delattr(self.unfiltered(), 'mq')
3301 delattr(self.unfiltered(), 'mq')
3302
3302
3303 def abortifwdirpatched(self, errmsg, force=False):
3303 def abortifwdirpatched(self, errmsg, force=False):
3304 if self.mq.applied and self.mq.checkapplied and not force:
3304 if self.mq.applied and self.mq.checkapplied and not force:
3305 parents = self.dirstate.parents()
3305 parents = self.dirstate.parents()
3306 patches = [s.node for s in self.mq.applied]
3306 patches = [s.node for s in self.mq.applied]
3307 if parents[0] in patches or parents[1] in patches:
3307 if parents[0] in patches or parents[1] in patches:
3308 raise util.Abort(errmsg)
3308 raise util.Abort(errmsg)
3309
3309
3310 def commit(self, text="", user=None, date=None, match=None,
3310 def commit(self, text="", user=None, date=None, match=None,
3311 force=False, editor=False, extra={}):
3311 force=False, editor=False, extra={}):
3312 self.abortifwdirpatched(
3312 self.abortifwdirpatched(
3313 _('cannot commit over an applied mq patch'),
3313 _('cannot commit over an applied mq patch'),
3314 force)
3314 force)
3315
3315
3316 return super(mqrepo, self).commit(text, user, date, match, force,
3316 return super(mqrepo, self).commit(text, user, date, match, force,
3317 editor, extra)
3317 editor, extra)
3318
3318
3319 def checkpush(self, pushop):
3319 def checkpush(self, pushop):
3320 if self.mq.applied and self.mq.checkapplied and not pushop.force:
3320 if self.mq.applied and self.mq.checkapplied and not pushop.force:
3321 outapplied = [e.node for e in self.mq.applied]
3321 outapplied = [e.node for e in self.mq.applied]
3322 if pushop.revs:
3322 if pushop.revs:
3323 # Assume applied patches have no non-patch descendants and
3323 # Assume applied patches have no non-patch descendants and
3324 # are not on remote already. Filtering any changeset not
3324 # are not on remote already. Filtering any changeset not
3325 # pushed.
3325 # pushed.
3326 heads = set(pushop.revs)
3326 heads = set(pushop.revs)
3327 for node in reversed(outapplied):
3327 for node in reversed(outapplied):
3328 if node in heads:
3328 if node in heads:
3329 break
3329 break
3330 else:
3330 else:
3331 outapplied.pop()
3331 outapplied.pop()
3332 # looking for pushed and shared changeset
3332 # looking for pushed and shared changeset
3333 for node in outapplied:
3333 for node in outapplied:
3334 if self[node].phase() < phases.secret:
3334 if self[node].phase() < phases.secret:
3335 raise util.Abort(_('source has mq patches applied'))
3335 raise util.Abort(_('source has mq patches applied'))
3336 # no non-secret patches pushed
3336 # no non-secret patches pushed
3337 super(mqrepo, self).checkpush(pushop)
3337 super(mqrepo, self).checkpush(pushop)
3338
3338
3339 def _findtags(self):
3339 def _findtags(self):
3340 '''augment tags from base class with patch tags'''
3340 '''augment tags from base class with patch tags'''
3341 result = super(mqrepo, self)._findtags()
3341 result = super(mqrepo, self)._findtags()
3342
3342
3343 q = self.mq
3343 q = self.mq
3344 if not q.applied:
3344 if not q.applied:
3345 return result
3345 return result
3346
3346
3347 mqtags = [(patch.node, patch.name) for patch in q.applied]
3347 mqtags = [(patch.node, patch.name) for patch in q.applied]
3348
3348
3349 try:
3349 try:
3350 # for now ignore filtering business
3350 # for now ignore filtering business
3351 self.unfiltered().changelog.rev(mqtags[-1][0])
3351 self.unfiltered().changelog.rev(mqtags[-1][0])
3352 except error.LookupError:
3352 except error.LookupError:
3353 self.ui.warn(_('mq status file refers to unknown node %s\n')
3353 self.ui.warn(_('mq status file refers to unknown node %s\n')
3354 % short(mqtags[-1][0]))
3354 % short(mqtags[-1][0]))
3355 return result
3355 return result
3356
3356
3357 # do not add fake tags for filtered revisions
3357 # do not add fake tags for filtered revisions
3358 included = self.changelog.hasnode
3358 included = self.changelog.hasnode
3359 mqtags = [mqt for mqt in mqtags if included(mqt[0])]
3359 mqtags = [mqt for mqt in mqtags if included(mqt[0])]
3360 if not mqtags:
3360 if not mqtags:
3361 return result
3361 return result
3362
3362
3363 mqtags.append((mqtags[-1][0], 'qtip'))
3363 mqtags.append((mqtags[-1][0], 'qtip'))
3364 mqtags.append((mqtags[0][0], 'qbase'))
3364 mqtags.append((mqtags[0][0], 'qbase'))
3365 mqtags.append((self.changelog.parents(mqtags[0][0])[0], 'qparent'))
3365 mqtags.append((self.changelog.parents(mqtags[0][0])[0], 'qparent'))
3366 tags = result[0]
3366 tags = result[0]
3367 for patch in mqtags:
3367 for patch in mqtags:
3368 if patch[1] in tags:
3368 if patch[1] in tags:
3369 self.ui.warn(_('tag %s overrides mq patch of the same '
3369 self.ui.warn(_('tag %s overrides mq patch of the same '
3370 'name\n') % patch[1])
3370 'name\n') % patch[1])
3371 else:
3371 else:
3372 tags[patch[1]] = patch[0]
3372 tags[patch[1]] = patch[0]
3373
3373
3374 return result
3374 return result
3375
3375
3376 if repo.local():
3376 if repo.local():
3377 repo.__class__ = mqrepo
3377 repo.__class__ = mqrepo
3378
3378
3379 repo._phasedefaults.append(mqphasedefaults)
3379 repo._phasedefaults.append(mqphasedefaults)
3380
3380
3381 def mqimport(orig, ui, repo, *args, **kwargs):
3381 def mqimport(orig, ui, repo, *args, **kwargs):
3382 if (util.safehasattr(repo, 'abortifwdirpatched')
3382 if (util.safehasattr(repo, 'abortifwdirpatched')
3383 and not kwargs.get('no_commit', False)):
3383 and not kwargs.get('no_commit', False)):
3384 repo.abortifwdirpatched(_('cannot import over an applied patch'),
3384 repo.abortifwdirpatched(_('cannot import over an applied patch'),
3385 kwargs.get('force'))
3385 kwargs.get('force'))
3386 return orig(ui, repo, *args, **kwargs)
3386 return orig(ui, repo, *args, **kwargs)
3387
3387
3388 def mqinit(orig, ui, *args, **kwargs):
3388 def mqinit(orig, ui, *args, **kwargs):
3389 mq = kwargs.pop('mq', None)
3389 mq = kwargs.pop('mq', None)
3390
3390
3391 if not mq:
3391 if not mq:
3392 return orig(ui, *args, **kwargs)
3392 return orig(ui, *args, **kwargs)
3393
3393
3394 if args:
3394 if args:
3395 repopath = args[0]
3395 repopath = args[0]
3396 if not hg.islocal(repopath):
3396 if not hg.islocal(repopath):
3397 raise util.Abort(_('only a local queue repository '
3397 raise util.Abort(_('only a local queue repository '
3398 'may be initialized'))
3398 'may be initialized'))
3399 else:
3399 else:
3400 repopath = cmdutil.findrepo(os.getcwd())
3400 repopath = cmdutil.findrepo(os.getcwd())
3401 if not repopath:
3401 if not repopath:
3402 raise util.Abort(_('there is no Mercurial repository here '
3402 raise util.Abort(_('there is no Mercurial repository here '
3403 '(.hg not found)'))
3403 '(.hg not found)'))
3404 repo = hg.repository(ui, repopath)
3404 repo = hg.repository(ui, repopath)
3405 return qinit(ui, repo, True)
3405 return qinit(ui, repo, True)
3406
3406
3407 def mqcommand(orig, ui, repo, *args, **kwargs):
3407 def mqcommand(orig, ui, repo, *args, **kwargs):
3408 """Add --mq option to operate on patch repository instead of main"""
3408 """Add --mq option to operate on patch repository instead of main"""
3409
3409
3410 # some commands do not like getting unknown options
3410 # some commands do not like getting unknown options
3411 mq = kwargs.pop('mq', None)
3411 mq = kwargs.pop('mq', None)
3412
3412
3413 if not mq:
3413 if not mq:
3414 return orig(ui, repo, *args, **kwargs)
3414 return orig(ui, repo, *args, **kwargs)
3415
3415
3416 q = repo.mq
3416 q = repo.mq
3417 r = q.qrepo()
3417 r = q.qrepo()
3418 if not r:
3418 if not r:
3419 raise util.Abort(_('no queue repository'))
3419 raise util.Abort(_('no queue repository'))
3420 return orig(r.ui, r, *args, **kwargs)
3420 return orig(r.ui, r, *args, **kwargs)
3421
3421
3422 def summaryhook(ui, repo):
3422 def summaryhook(ui, repo):
3423 q = repo.mq
3423 q = repo.mq
3424 m = []
3424 m = []
3425 a, u = len(q.applied), len(q.unapplied(repo))
3425 a, u = len(q.applied), len(q.unapplied(repo))
3426 if a:
3426 if a:
3427 m.append(ui.label(_("%d applied"), 'qseries.applied') % a)
3427 m.append(ui.label(_("%d applied"), 'qseries.applied') % a)
3428 if u:
3428 if u:
3429 m.append(ui.label(_("%d unapplied"), 'qseries.unapplied') % u)
3429 m.append(ui.label(_("%d unapplied"), 'qseries.unapplied') % u)
3430 if m:
3430 if m:
3431 # i18n: column positioning for "hg summary"
3431 # i18n: column positioning for "hg summary"
3432 ui.write(_("mq: %s\n") % ', '.join(m))
3432 ui.write(_("mq: %s\n") % ', '.join(m))
3433 else:
3433 else:
3434 # i18n: column positioning for "hg summary"
3434 # i18n: column positioning for "hg summary"
3435 ui.note(_("mq: (empty queue)\n"))
3435 ui.note(_("mq: (empty queue)\n"))
3436
3436
3437 def revsetmq(repo, subset, x):
3437 def revsetmq(repo, subset, x):
3438 """``mq()``
3438 """``mq()``
3439 Changesets managed by MQ.
3439 Changesets managed by MQ.
3440 """
3440 """
3441 revset.getargs(x, 0, 0, _("mq takes no arguments"))
3441 revset.getargs(x, 0, 0, _("mq takes no arguments"))
3442 applied = set([repo[r.node].rev() for r in repo.mq.applied])
3442 applied = set([repo[r.node].rev() for r in repo.mq.applied])
3443 return revset.baseset([r for r in subset if r in applied])
3443 return revset.baseset([r for r in subset if r in applied])
3444
3444
3445 # tell hggettext to extract docstrings from these functions:
3445 # tell hggettext to extract docstrings from these functions:
3446 i18nfunctions = [revsetmq]
3446 i18nfunctions = [revsetmq]
3447
3447
3448 def extsetup(ui):
3448 def extsetup(ui):
3449 # Ensure mq wrappers are called first, regardless of extension load order by
3449 # Ensure mq wrappers are called first, regardless of extension load order by
3450 # NOT wrapping in uisetup() and instead deferring to init stage two here.
3450 # NOT wrapping in uisetup() and instead deferring to init stage two here.
3451 mqopt = [('', 'mq', None, _("operate on patch repository"))]
3451 mqopt = [('', 'mq', None, _("operate on patch repository"))]
3452
3452
3453 extensions.wrapcommand(commands.table, 'import', mqimport)
3453 extensions.wrapcommand(commands.table, 'import', mqimport)
3454 cmdutil.summaryhooks.add('mq', summaryhook)
3454 cmdutil.summaryhooks.add('mq', summaryhook)
3455
3455
3456 entry = extensions.wrapcommand(commands.table, 'init', mqinit)
3456 entry = extensions.wrapcommand(commands.table, 'init', mqinit)
3457 entry[1].extend(mqopt)
3457 entry[1].extend(mqopt)
3458
3458
3459 nowrap = set(commands.norepo.split(" "))
3459 nowrap = set(commands.norepo.split(" "))
3460
3460
3461 def dotable(cmdtable):
3461 def dotable(cmdtable):
3462 for cmd in cmdtable.keys():
3462 for cmd in cmdtable.keys():
3463 cmd = cmdutil.parsealiases(cmd)[0]
3463 cmd = cmdutil.parsealiases(cmd)[0]
3464 if cmd in nowrap:
3464 if cmd in nowrap:
3465 continue
3465 continue
3466 entry = extensions.wrapcommand(cmdtable, cmd, mqcommand)
3466 entry = extensions.wrapcommand(cmdtable, cmd, mqcommand)
3467 entry[1].extend(mqopt)
3467 entry[1].extend(mqopt)
3468
3468
3469 dotable(commands.table)
3469 dotable(commands.table)
3470
3470
3471 for extname, extmodule in extensions.extensions():
3471 for extname, extmodule in extensions.extensions():
3472 if extmodule.__file__ != __file__:
3472 if extmodule.__file__ != __file__:
3473 dotable(getattr(extmodule, 'cmdtable', {}))
3473 dotable(getattr(extmodule, 'cmdtable', {}))
3474
3474
3475 revset.symbols['mq'] = revsetmq
3475 revset.symbols['mq'] = revsetmq
3476
3476
3477 colortable = {'qguard.negative': 'red',
3477 colortable = {'qguard.negative': 'red',
3478 'qguard.positive': 'yellow',
3478 'qguard.positive': 'yellow',
3479 'qguard.unguarded': 'green',
3479 'qguard.unguarded': 'green',
3480 'qseries.applied': 'blue bold underline',
3480 'qseries.applied': 'blue bold underline',
3481 'qseries.guarded': 'black bold',
3481 'qseries.guarded': 'black bold',
3482 'qseries.missing': 'red bold',
3482 'qseries.missing': 'red bold',
3483 'qseries.unapplied': 'black bold'}
3483 'qseries.unapplied': 'black bold'}
@@ -1,210 +1,210 b''
1 # Test the plumbing of mq.git option
1 # Test the plumbing of mq.git option
2 # Automatic upgrade itself is tested elsewhere.
2 # Automatic upgrade itself is tested elsewhere.
3
3
4 $ echo "[extensions]" >> $HGRCPATH
4 $ echo "[extensions]" >> $HGRCPATH
5 $ echo "mq=" >> $HGRCPATH
5 $ echo "mq=" >> $HGRCPATH
6 $ echo "[diff]" >> $HGRCPATH
6 $ echo "[diff]" >> $HGRCPATH
7 $ echo "nodates=1" >> $HGRCPATH
7 $ echo "nodates=1" >> $HGRCPATH
8
8
9 $ hg init repo-auto
9 $ hg init repo-auto
10 $ cd repo-auto
10 $ cd repo-auto
11
11
12 git=auto: regular patch creation:
12 git=auto: regular patch creation:
13
13
14 $ echo a > a
14 $ echo a > a
15 $ hg add a
15 $ hg add a
16 $ hg qnew -d '0 0' -f adda
16 $ hg qnew -d '0 0' -f adda
17
17
18 $ cat .hg/patches/adda
18 $ cat .hg/patches/adda
19 # HG changeset patch
19 # HG changeset patch
20 # Date 0 0
20 # Parent 0000000000000000000000000000000000000000
21 # Parent 0000000000000000000000000000000000000000
21 # Date 0 0
22
22
23 diff -r 000000000000 -r ef8dafc9fa4c a
23 diff -r 000000000000 -r ef8dafc9fa4c a
24 --- /dev/null
24 --- /dev/null
25 +++ b/a
25 +++ b/a
26 @@ -0,0 +1,1 @@
26 @@ -0,0 +1,1 @@
27 +a
27 +a
28
28
29 git=auto: git patch creation with copy:
29 git=auto: git patch creation with copy:
30
30
31 $ hg cp a b
31 $ hg cp a b
32 $ hg qnew -d '0 0' -f copy
32 $ hg qnew -d '0 0' -f copy
33
33
34 $ cat .hg/patches/copy
34 $ cat .hg/patches/copy
35 # HG changeset patch
35 # HG changeset patch
36 # Date 0 0
36 # Parent ef8dafc9fa4caff80f6e243eb0171bcd60c455b4
37 # Parent ef8dafc9fa4caff80f6e243eb0171bcd60c455b4
37 # Date 0 0
38
38
39 diff --git a/a b/b
39 diff --git a/a b/b
40 copy from a
40 copy from a
41 copy to b
41 copy to b
42
42
43 git=auto: git patch when using --git:
43 git=auto: git patch when using --git:
44
44
45 $ echo regular > regular
45 $ echo regular > regular
46 $ hg add regular
46 $ hg add regular
47 $ hg qnew -d '0 0' --git -f git
47 $ hg qnew -d '0 0' --git -f git
48
48
49 $ cat .hg/patches/git
49 $ cat .hg/patches/git
50 # HG changeset patch
50 # HG changeset patch
51 # Date 0 0
51 # Parent 99586d5f048c399e20f81cee41fbb3809c0e735d
52 # Parent 99586d5f048c399e20f81cee41fbb3809c0e735d
52 # Date 0 0
53
53
54 diff --git a/regular b/regular
54 diff --git a/regular b/regular
55 new file mode 100644
55 new file mode 100644
56 --- /dev/null
56 --- /dev/null
57 +++ b/regular
57 +++ b/regular
58 @@ -0,0 +1,1 @@
58 @@ -0,0 +1,1 @@
59 +regular
59 +regular
60
60
61 git=auto: regular patch after qrefresh without --git:
61 git=auto: regular patch after qrefresh without --git:
62
62
63 $ hg qrefresh -d '0 0'
63 $ hg qrefresh -d '0 0'
64
64
65 $ cat .hg/patches/git
65 $ cat .hg/patches/git
66 # HG changeset patch
66 # HG changeset patch
67 # Date 0 0
67 # Parent 99586d5f048c399e20f81cee41fbb3809c0e735d
68 # Parent 99586d5f048c399e20f81cee41fbb3809c0e735d
68 # Date 0 0
69
69
70 diff -r 99586d5f048c regular
70 diff -r 99586d5f048c regular
71 --- /dev/null
71 --- /dev/null
72 +++ b/regular
72 +++ b/regular
73 @@ -0,0 +1,1 @@
73 @@ -0,0 +1,1 @@
74 +regular
74 +regular
75
75
76 $ cd ..
76 $ cd ..
77
77
78 $ hg init repo-keep
78 $ hg init repo-keep
79 $ cd repo-keep
79 $ cd repo-keep
80 $ echo '[mq]' > .hg/hgrc
80 $ echo '[mq]' > .hg/hgrc
81 $ echo 'git = KEEP' >> .hg/hgrc
81 $ echo 'git = KEEP' >> .hg/hgrc
82
82
83 git=keep: git patch with --git:
83 git=keep: git patch with --git:
84
84
85 $ echo a > a
85 $ echo a > a
86 $ hg add a
86 $ hg add a
87 $ hg qnew -d '0 0' -f --git git
87 $ hg qnew -d '0 0' -f --git git
88
88
89 $ cat .hg/patches/git
89 $ cat .hg/patches/git
90 # HG changeset patch
90 # HG changeset patch
91 # Date 0 0
91 # Parent 0000000000000000000000000000000000000000
92 # Parent 0000000000000000000000000000000000000000
92 # Date 0 0
93
93
94 diff --git a/a b/a
94 diff --git a/a b/a
95 new file mode 100644
95 new file mode 100644
96 --- /dev/null
96 --- /dev/null
97 +++ b/a
97 +++ b/a
98 @@ -0,0 +1,1 @@
98 @@ -0,0 +1,1 @@
99 +a
99 +a
100
100
101 git=keep: git patch after qrefresh without --git:
101 git=keep: git patch after qrefresh without --git:
102
102
103 $ echo a >> a
103 $ echo a >> a
104 $ hg qrefresh -d '0 0'
104 $ hg qrefresh -d '0 0'
105
105
106 $ cat .hg/patches/git
106 $ cat .hg/patches/git
107 # HG changeset patch
107 # HG changeset patch
108 # Date 0 0
108 # Parent 0000000000000000000000000000000000000000
109 # Parent 0000000000000000000000000000000000000000
109 # Date 0 0
110
110
111 diff --git a/a b/a
111 diff --git a/a b/a
112 new file mode 100644
112 new file mode 100644
113 --- /dev/null
113 --- /dev/null
114 +++ b/a
114 +++ b/a
115 @@ -0,0 +1,2 @@
115 @@ -0,0 +1,2 @@
116 +a
116 +a
117 +a
117 +a
118 $ cd ..
118 $ cd ..
119
119
120 $ hg init repo-yes
120 $ hg init repo-yes
121 $ cd repo-yes
121 $ cd repo-yes
122 $ echo '[mq]' > .hg/hgrc
122 $ echo '[mq]' > .hg/hgrc
123 $ echo 'git = yes' >> .hg/hgrc
123 $ echo 'git = yes' >> .hg/hgrc
124
124
125 git=yes: git patch:
125 git=yes: git patch:
126
126
127 $ echo a > a
127 $ echo a > a
128 $ hg add a
128 $ hg add a
129 $ hg qnew -d '0 0' -f git
129 $ hg qnew -d '0 0' -f git
130
130
131 $ cat .hg/patches/git
131 $ cat .hg/patches/git
132 # HG changeset patch
132 # HG changeset patch
133 # Date 0 0
133 # Parent 0000000000000000000000000000000000000000
134 # Parent 0000000000000000000000000000000000000000
134 # Date 0 0
135
135
136 diff --git a/a b/a
136 diff --git a/a b/a
137 new file mode 100644
137 new file mode 100644
138 --- /dev/null
138 --- /dev/null
139 +++ b/a
139 +++ b/a
140 @@ -0,0 +1,1 @@
140 @@ -0,0 +1,1 @@
141 +a
141 +a
142
142
143 git=yes: git patch after qrefresh:
143 git=yes: git patch after qrefresh:
144
144
145 $ echo a >> a
145 $ echo a >> a
146 $ hg qrefresh -d '0 0'
146 $ hg qrefresh -d '0 0'
147
147
148 $ cat .hg/patches/git
148 $ cat .hg/patches/git
149 # HG changeset patch
149 # HG changeset patch
150 # Date 0 0
150 # Parent 0000000000000000000000000000000000000000
151 # Parent 0000000000000000000000000000000000000000
151 # Date 0 0
152
152
153 diff --git a/a b/a
153 diff --git a/a b/a
154 new file mode 100644
154 new file mode 100644
155 --- /dev/null
155 --- /dev/null
156 +++ b/a
156 +++ b/a
157 @@ -0,0 +1,2 @@
157 @@ -0,0 +1,2 @@
158 +a
158 +a
159 +a
159 +a
160 $ cd ..
160 $ cd ..
161
161
162 $ hg init repo-no
162 $ hg init repo-no
163 $ cd repo-no
163 $ cd repo-no
164 $ echo '[diff]' > .hg/hgrc
164 $ echo '[diff]' > .hg/hgrc
165 $ echo 'git = True' >> .hg/hgrc
165 $ echo 'git = True' >> .hg/hgrc
166 $ echo '[mq]' > .hg/hgrc
166 $ echo '[mq]' > .hg/hgrc
167 $ echo 'git = False' >> .hg/hgrc
167 $ echo 'git = False' >> .hg/hgrc
168
168
169 git=no: regular patch with copy:
169 git=no: regular patch with copy:
170
170
171 $ echo a > a
171 $ echo a > a
172 $ hg add a
172 $ hg add a
173 $ hg qnew -d '0 0' -f adda
173 $ hg qnew -d '0 0' -f adda
174 $ hg cp a b
174 $ hg cp a b
175 $ hg qnew -d '0 0' -f regular
175 $ hg qnew -d '0 0' -f regular
176
176
177 $ cat .hg/patches/regular
177 $ cat .hg/patches/regular
178 # HG changeset patch
178 # HG changeset patch
179 # Date 0 0
179 # Parent ef8dafc9fa4caff80f6e243eb0171bcd60c455b4
180 # Parent ef8dafc9fa4caff80f6e243eb0171bcd60c455b4
180 # Date 0 0
181
181
182 diff -r ef8dafc9fa4c -r a70404f79ba3 b
182 diff -r ef8dafc9fa4c -r a70404f79ba3 b
183 --- /dev/null
183 --- /dev/null
184 +++ b/b
184 +++ b/b
185 @@ -0,0 +1,1 @@
185 @@ -0,0 +1,1 @@
186 +a
186 +a
187
187
188 git=no: regular patch after qrefresh with copy:
188 git=no: regular patch after qrefresh with copy:
189
189
190 $ hg cp a c
190 $ hg cp a c
191 $ hg qrefresh -d '0 0'
191 $ hg qrefresh -d '0 0'
192
192
193 $ cat .hg/patches/regular
193 $ cat .hg/patches/regular
194 # HG changeset patch
194 # HG changeset patch
195 # Date 0 0
195 # Parent ef8dafc9fa4caff80f6e243eb0171bcd60c455b4
196 # Parent ef8dafc9fa4caff80f6e243eb0171bcd60c455b4
196 # Date 0 0
197
197
198 diff -r ef8dafc9fa4c b
198 diff -r ef8dafc9fa4c b
199 --- /dev/null
199 --- /dev/null
200 +++ b/b
200 +++ b/b
201 @@ -0,0 +1,1 @@
201 @@ -0,0 +1,1 @@
202 +a
202 +a
203 diff -r ef8dafc9fa4c c
203 diff -r ef8dafc9fa4c c
204 --- /dev/null
204 --- /dev/null
205 +++ b/c
205 +++ b/c
206 @@ -0,0 +1,1 @@
206 @@ -0,0 +1,1 @@
207 +a
207 +a
208
208
209 $ cd ..
209 $ cd ..
210
210
@@ -1,892 +1,892 b''
1
1
2 $ echo "[extensions]" >> $HGRCPATH
2 $ echo "[extensions]" >> $HGRCPATH
3 $ echo "mq=" >> $HGRCPATH
3 $ echo "mq=" >> $HGRCPATH
4 $ echo "[diff]" >> $HGRCPATH
4 $ echo "[diff]" >> $HGRCPATH
5 $ echo "nodates=true" >> $HGRCPATH
5 $ echo "nodates=true" >> $HGRCPATH
6 $ catpatch() {
6 $ catpatch() {
7 > cat .hg/patches/$1.patch | sed -e "s/^diff \-r [0-9a-f]* /diff -r ... /" \
7 > cat .hg/patches/$1.patch | sed -e "s/^diff \-r [0-9a-f]* /diff -r ... /" \
8 > -e "s/^\(# Parent \).*/\1/"
8 > -e "s/^\(# Parent \).*/\1/"
9 > }
9 > }
10 $ catlog() {
10 $ catlog() {
11 > catpatch $1
11 > catpatch $1
12 > hg log --template "{rev}: {desc} - {author}\n"
12 > hg log --template "{rev}: {desc} - {author}\n"
13 > }
13 > }
14 $ catlogd() {
14 $ catlogd() {
15 > catpatch $1
15 > catpatch $1
16 > hg log --template "{rev}: {desc} - {author} - {date}\n"
16 > hg log --template "{rev}: {desc} - {author} - {date}\n"
17 > }
17 > }
18 $ drop() {
18 $ drop() {
19 > hg qpop
19 > hg qpop
20 > hg qdel $1.patch
20 > hg qdel $1.patch
21 > }
21 > }
22 $ runtest() {
22 $ runtest() {
23 > echo ==== init
23 > echo ==== init
24 > hg init a
24 > hg init a
25 > cd a
25 > cd a
26 > hg qinit
26 > hg qinit
27 >
27 >
28 >
28 >
29 > echo ==== qnew -d
29 > echo ==== qnew -d
30 > hg qnew -d '3 0' 1.patch
30 > hg qnew -d '3 0' 1.patch
31 > catlogd 1
31 > catlogd 1
32 >
32 >
33 > echo ==== qref
33 > echo ==== qref
34 > echo "1" >1
34 > echo "1" >1
35 > hg add
35 > hg add
36 > hg qref
36 > hg qref
37 > catlogd 1
37 > catlogd 1
38 >
38 >
39 > echo ==== qref -d
39 > echo ==== qref -d
40 > hg qref -d '4 0'
40 > hg qref -d '4 0'
41 > catlogd 1
41 > catlogd 1
42 >
42 >
43 >
43 >
44 > echo ==== qnew
44 > echo ==== qnew
45 > hg qnew 2.patch
45 > hg qnew 2.patch
46 > echo "2" >2
46 > echo "2" >2
47 > hg add
47 > hg add
48 > hg qref
48 > hg qref
49 > catlog 2
49 > catlog 2
50 >
50 >
51 > echo ==== qref -d
51 > echo ==== qref -d
52 > hg qref -d '5 0'
52 > hg qref -d '5 0'
53 > catlog 2
53 > catlog 2
54 >
54 >
55 > drop 2
55 > drop 2
56 >
56 >
57 >
57 >
58 > echo ==== qnew -d -m
58 > echo ==== qnew -d -m
59 > hg qnew -d '6 0' -m "Three" 3.patch
59 > hg qnew -d '6 0' -m "Three" 3.patch
60 > catlogd 3
60 > catlogd 3
61 >
61 >
62 > echo ==== qref
62 > echo ==== qref
63 > echo "3" >3
63 > echo "3" >3
64 > hg add
64 > hg add
65 > hg qref
65 > hg qref
66 > catlogd 3
66 > catlogd 3
67 >
67 >
68 > echo ==== qref -m
68 > echo ==== qref -m
69 > hg qref -m "Drei"
69 > hg qref -m "Drei"
70 > catlogd 3
70 > catlogd 3
71 >
71 >
72 > echo ==== qref -d
72 > echo ==== qref -d
73 > hg qref -d '7 0'
73 > hg qref -d '7 0'
74 > catlogd 3
74 > catlogd 3
75 >
75 >
76 > echo ==== qref -d -m
76 > echo ==== qref -d -m
77 > hg qref -d '8 0' -m "Three (again)"
77 > hg qref -d '8 0' -m "Three (again)"
78 > catlogd 3
78 > catlogd 3
79 >
79 >
80 >
80 >
81 > echo ==== qnew -m
81 > echo ==== qnew -m
82 > hg qnew -m "Four" 4.patch
82 > hg qnew -m "Four" 4.patch
83 > echo "4" >4
83 > echo "4" >4
84 > hg add
84 > hg add
85 > hg qref
85 > hg qref
86 > catlog 4
86 > catlog 4
87 >
87 >
88 > echo ==== qref -d
88 > echo ==== qref -d
89 > hg qref -d '9 0'
89 > hg qref -d '9 0'
90 > catlog 4
90 > catlog 4
91 >
91 >
92 > drop 4
92 > drop 4
93 >
93 >
94 >
94 >
95 > echo ==== qnew with HG header
95 > echo ==== qnew with HG header
96 > hg qnew --config 'mq.plain=true' 5.patch
96 > hg qnew --config 'mq.plain=true' 5.patch
97 > hg qpop
97 > hg qpop
98 > echo "# HG changeset patch" >>.hg/patches/5.patch
98 > echo "# HG changeset patch" >>.hg/patches/5.patch
99 > echo "# Date 10 0" >>.hg/patches/5.patch
99 > echo "# Date 10 0" >>.hg/patches/5.patch
100 > hg qpush 2>&1 | grep 'Now at'
100 > hg qpush 2>&1 | grep 'Now at'
101 > catlogd 5
101 > catlogd 5
102 >
102 >
103 > echo ==== hg qref
103 > echo ==== hg qref
104 > echo "5" >5
104 > echo "5" >5
105 > hg add
105 > hg add
106 > hg qref
106 > hg qref
107 > catlogd 5
107 > catlogd 5
108 >
108 >
109 > echo ==== hg qref -d
109 > echo ==== hg qref -d
110 > hg qref -d '11 0'
110 > hg qref -d '11 0'
111 > catlogd 5
111 > catlogd 5
112 >
112 >
113 >
113 >
114 > echo ==== qnew with plain header
114 > echo ==== qnew with plain header
115 > hg qnew --config 'mq.plain=true' -d '12 0' 6.patch
115 > hg qnew --config 'mq.plain=true' -d '12 0' 6.patch
116 > hg qpop
116 > hg qpop
117 > hg qpush 2>&1 | grep 'now at'
117 > hg qpush 2>&1 | grep 'now at'
118 > catlog 6
118 > catlog 6
119 >
119 >
120 > echo ==== hg qref
120 > echo ==== hg qref
121 > echo "6" >6
121 > echo "6" >6
122 > hg add
122 > hg add
123 > hg qref
123 > hg qref
124 > catlogd 6
124 > catlogd 6
125 >
125 >
126 > echo ==== hg qref -d
126 > echo ==== hg qref -d
127 > hg qref -d '13 0'
127 > hg qref -d '13 0'
128 > catlogd 6
128 > catlogd 6
129 >
129 >
130 > drop 6
130 > drop 6
131 >
131 >
132 >
132 >
133 > echo ==== qnew -u
133 > echo ==== qnew -u
134 > hg qnew -u jane 6.patch
134 > hg qnew -u jane 6.patch
135 > echo "6" >6
135 > echo "6" >6
136 > hg add
136 > hg add
137 > hg qref
137 > hg qref
138 > catlog 6
138 > catlog 6
139 >
139 >
140 > echo ==== qref -d
140 > echo ==== qref -d
141 > hg qref -d '12 0'
141 > hg qref -d '12 0'
142 > catlog 6
142 > catlog 6
143 >
143 >
144 > drop 6
144 > drop 6
145 >
145 >
146 >
146 >
147 > echo ==== qnew -d
147 > echo ==== qnew -d
148 > hg qnew -d '13 0' 7.patch
148 > hg qnew -d '13 0' 7.patch
149 > echo "7" >7
149 > echo "7" >7
150 > hg add
150 > hg add
151 > hg qref
151 > hg qref
152 > catlog 7
152 > catlog 7
153 >
153 >
154 > echo ==== qref -u
154 > echo ==== qref -u
155 > hg qref -u john
155 > hg qref -u john
156 > catlogd 7
156 > catlogd 7
157 >
157 >
158 >
158 >
159 > echo ==== qnew
159 > echo ==== qnew
160 > hg qnew 8.patch
160 > hg qnew 8.patch
161 > echo "8" >8
161 > echo "8" >8
162 > hg add
162 > hg add
163 > hg qref
163 > hg qref
164 > catlog 8
164 > catlog 8
165 >
165 >
166 > echo ==== qref -u -d
166 > echo ==== qref -u -d
167 > hg qref -u john -d '14 0'
167 > hg qref -u john -d '14 0'
168 > catlog 8
168 > catlog 8
169 >
169 >
170 > drop 8
170 > drop 8
171 >
171 >
172 >
172 >
173 > echo ==== qnew -m
173 > echo ==== qnew -m
174 > hg qnew -m "Nine" 9.patch
174 > hg qnew -m "Nine" 9.patch
175 > echo "9" >9
175 > echo "9" >9
176 > hg add
176 > hg add
177 > hg qref
177 > hg qref
178 > catlog 9
178 > catlog 9
179 >
179 >
180 > echo ==== qref -u -d
180 > echo ==== qref -u -d
181 > hg qref -u john -d '15 0'
181 > hg qref -u john -d '15 0'
182 > catlog 9
182 > catlog 9
183 >
183 >
184 > drop 9
184 > drop 9
185 >
185 >
186 >
186 >
187 > echo ==== "qpop -a / qpush -a"
187 > echo ==== "qpop -a / qpush -a"
188 > hg qpop -a
188 > hg qpop -a
189 > hg qpush -a
189 > hg qpush -a
190 > hg log --template "{rev}: {desc} - {author} - {date}\n"
190 > hg log --template "{rev}: {desc} - {author} - {date}\n"
191 > }
191 > }
192
192
193 ======= plain headers
193 ======= plain headers
194
194
195 $ echo "[mq]" >> $HGRCPATH
195 $ echo "[mq]" >> $HGRCPATH
196 $ echo "plain=true" >> $HGRCPATH
196 $ echo "plain=true" >> $HGRCPATH
197 $ mkdir sandbox
197 $ mkdir sandbox
198 $ (cd sandbox ; runtest)
198 $ (cd sandbox ; runtest)
199 ==== init
199 ==== init
200 ==== qnew -d
200 ==== qnew -d
201 Date: 3 0
201 Date: 3 0
202
202
203 0: [mq]: 1.patch - test - 3.00
203 0: [mq]: 1.patch - test - 3.00
204 ==== qref
204 ==== qref
205 adding 1
205 adding 1
206 Date: 3 0
206 Date: 3 0
207
207
208 diff -r ... 1
208 diff -r ... 1
209 --- /dev/null
209 --- /dev/null
210 +++ b/1
210 +++ b/1
211 @@ -0,0 +1,1 @@
211 @@ -0,0 +1,1 @@
212 +1
212 +1
213 0: [mq]: 1.patch - test - 3.00
213 0: [mq]: 1.patch - test - 3.00
214 ==== qref -d
214 ==== qref -d
215 Date: 4 0
215 Date: 4 0
216
216
217 diff -r ... 1
217 diff -r ... 1
218 --- /dev/null
218 --- /dev/null
219 +++ b/1
219 +++ b/1
220 @@ -0,0 +1,1 @@
220 @@ -0,0 +1,1 @@
221 +1
221 +1
222 0: [mq]: 1.patch - test - 4.00
222 0: [mq]: 1.patch - test - 4.00
223 ==== qnew
223 ==== qnew
224 adding 2
224 adding 2
225 diff -r ... 2
225 diff -r ... 2
226 --- /dev/null
226 --- /dev/null
227 +++ b/2
227 +++ b/2
228 @@ -0,0 +1,1 @@
228 @@ -0,0 +1,1 @@
229 +2
229 +2
230 1: [mq]: 2.patch - test
230 1: [mq]: 2.patch - test
231 0: [mq]: 1.patch - test
231 0: [mq]: 1.patch - test
232 ==== qref -d
232 ==== qref -d
233 Date: 5 0
233 Date: 5 0
234
234
235 diff -r ... 2
235 diff -r ... 2
236 --- /dev/null
236 --- /dev/null
237 +++ b/2
237 +++ b/2
238 @@ -0,0 +1,1 @@
238 @@ -0,0 +1,1 @@
239 +2
239 +2
240 1: [mq]: 2.patch - test
240 1: [mq]: 2.patch - test
241 0: [mq]: 1.patch - test
241 0: [mq]: 1.patch - test
242 popping 2.patch
242 popping 2.patch
243 now at: 1.patch
243 now at: 1.patch
244 ==== qnew -d -m
244 ==== qnew -d -m
245 Date: 6 0
245 Date: 6 0
246 Three
246 Three
247
247
248 1: Three - test - 6.00
248 1: Three - test - 6.00
249 0: [mq]: 1.patch - test - 4.00
249 0: [mq]: 1.patch - test - 4.00
250 ==== qref
250 ==== qref
251 adding 3
251 adding 3
252 Date: 6 0
252 Date: 6 0
253 Three
253 Three
254
254
255 diff -r ... 3
255 diff -r ... 3
256 --- /dev/null
256 --- /dev/null
257 +++ b/3
257 +++ b/3
258 @@ -0,0 +1,1 @@
258 @@ -0,0 +1,1 @@
259 +3
259 +3
260 1: Three - test - 6.00
260 1: Three - test - 6.00
261 0: [mq]: 1.patch - test - 4.00
261 0: [mq]: 1.patch - test - 4.00
262 ==== qref -m
262 ==== qref -m
263 Date: 6 0
263 Date: 6 0
264 Drei
264 Drei
265
265
266 diff -r ... 3
266 diff -r ... 3
267 --- /dev/null
267 --- /dev/null
268 +++ b/3
268 +++ b/3
269 @@ -0,0 +1,1 @@
269 @@ -0,0 +1,1 @@
270 +3
270 +3
271 1: Drei - test - 6.00
271 1: Drei - test - 6.00
272 0: [mq]: 1.patch - test - 4.00
272 0: [mq]: 1.patch - test - 4.00
273 ==== qref -d
273 ==== qref -d
274 Date: 7 0
274 Date: 7 0
275 Drei
275 Drei
276
276
277 diff -r ... 3
277 diff -r ... 3
278 --- /dev/null
278 --- /dev/null
279 +++ b/3
279 +++ b/3
280 @@ -0,0 +1,1 @@
280 @@ -0,0 +1,1 @@
281 +3
281 +3
282 1: Drei - test - 7.00
282 1: Drei - test - 7.00
283 0: [mq]: 1.patch - test - 4.00
283 0: [mq]: 1.patch - test - 4.00
284 ==== qref -d -m
284 ==== qref -d -m
285 Date: 8 0
285 Date: 8 0
286 Three (again)
286 Three (again)
287
287
288 diff -r ... 3
288 diff -r ... 3
289 --- /dev/null
289 --- /dev/null
290 +++ b/3
290 +++ b/3
291 @@ -0,0 +1,1 @@
291 @@ -0,0 +1,1 @@
292 +3
292 +3
293 1: Three (again) - test - 8.00
293 1: Three (again) - test - 8.00
294 0: [mq]: 1.patch - test - 4.00
294 0: [mq]: 1.patch - test - 4.00
295 ==== qnew -m
295 ==== qnew -m
296 adding 4
296 adding 4
297 Four
297 Four
298
298
299 diff -r ... 4
299 diff -r ... 4
300 --- /dev/null
300 --- /dev/null
301 +++ b/4
301 +++ b/4
302 @@ -0,0 +1,1 @@
302 @@ -0,0 +1,1 @@
303 +4
303 +4
304 2: Four - test
304 2: Four - test
305 1: Three (again) - test
305 1: Three (again) - test
306 0: [mq]: 1.patch - test
306 0: [mq]: 1.patch - test
307 ==== qref -d
307 ==== qref -d
308 Date: 9 0
308 Date: 9 0
309 Four
309 Four
310
310
311 diff -r ... 4
311 diff -r ... 4
312 --- /dev/null
312 --- /dev/null
313 +++ b/4
313 +++ b/4
314 @@ -0,0 +1,1 @@
314 @@ -0,0 +1,1 @@
315 +4
315 +4
316 2: Four - test
316 2: Four - test
317 1: Three (again) - test
317 1: Three (again) - test
318 0: [mq]: 1.patch - test
318 0: [mq]: 1.patch - test
319 popping 4.patch
319 popping 4.patch
320 now at: 3.patch
320 now at: 3.patch
321 ==== qnew with HG header
321 ==== qnew with HG header
322 popping 5.patch
322 popping 5.patch
323 now at: 3.patch
323 now at: 3.patch
324 # HG changeset patch
324 # HG changeset patch
325 # Date 10 0
325 # Date 10 0
326 2: imported patch 5.patch - test - 10.00
326 2: imported patch 5.patch - test - 10.00
327 1: Three (again) - test - 8.00
327 1: Three (again) - test - 8.00
328 0: [mq]: 1.patch - test - 4.00
328 0: [mq]: 1.patch - test - 4.00
329 ==== hg qref
329 ==== hg qref
330 adding 5
330 adding 5
331 # HG changeset patch
331 # HG changeset patch
332 # Parent
332 # Parent
333 # Date 10 0
333 # Date 10 0
334
334
335 diff -r ... 5
335 diff -r ... 5
336 --- /dev/null
336 --- /dev/null
337 +++ b/5
337 +++ b/5
338 @@ -0,0 +1,1 @@
338 @@ -0,0 +1,1 @@
339 +5
339 +5
340 2: [mq]: 5.patch - test - 10.00
340 2: [mq]: 5.patch - test - 10.00
341 1: Three (again) - test - 8.00
341 1: Three (again) - test - 8.00
342 0: [mq]: 1.patch - test - 4.00
342 0: [mq]: 1.patch - test - 4.00
343 ==== hg qref -d
343 ==== hg qref -d
344 # HG changeset patch
344 # HG changeset patch
345 # Parent
345 # Parent
346 # Date 11 0
346 # Date 11 0
347
347
348 diff -r ... 5
348 diff -r ... 5
349 --- /dev/null
349 --- /dev/null
350 +++ b/5
350 +++ b/5
351 @@ -0,0 +1,1 @@
351 @@ -0,0 +1,1 @@
352 +5
352 +5
353 2: [mq]: 5.patch - test - 11.00
353 2: [mq]: 5.patch - test - 11.00
354 1: Three (again) - test - 8.00
354 1: Three (again) - test - 8.00
355 0: [mq]: 1.patch - test - 4.00
355 0: [mq]: 1.patch - test - 4.00
356 ==== qnew with plain header
356 ==== qnew with plain header
357 popping 6.patch
357 popping 6.patch
358 now at: 5.patch
358 now at: 5.patch
359 now at: 6.patch
359 now at: 6.patch
360 Date: 12 0
360 Date: 12 0
361
361
362 3: imported patch 6.patch - test
362 3: imported patch 6.patch - test
363 2: [mq]: 5.patch - test
363 2: [mq]: 5.patch - test
364 1: Three (again) - test
364 1: Three (again) - test
365 0: [mq]: 1.patch - test
365 0: [mq]: 1.patch - test
366 ==== hg qref
366 ==== hg qref
367 adding 6
367 adding 6
368 Date: 12 0
368 Date: 12 0
369
369
370 diff -r ... 6
370 diff -r ... 6
371 --- /dev/null
371 --- /dev/null
372 +++ b/6
372 +++ b/6
373 @@ -0,0 +1,1 @@
373 @@ -0,0 +1,1 @@
374 +6
374 +6
375 3: [mq]: 6.patch - test - 12.00
375 3: [mq]: 6.patch - test - 12.00
376 2: [mq]: 5.patch - test - 11.00
376 2: [mq]: 5.patch - test - 11.00
377 1: Three (again) - test - 8.00
377 1: Three (again) - test - 8.00
378 0: [mq]: 1.patch - test - 4.00
378 0: [mq]: 1.patch - test - 4.00
379 ==== hg qref -d
379 ==== hg qref -d
380 Date: 13 0
380 Date: 13 0
381
381
382 diff -r ... 6
382 diff -r ... 6
383 --- /dev/null
383 --- /dev/null
384 +++ b/6
384 +++ b/6
385 @@ -0,0 +1,1 @@
385 @@ -0,0 +1,1 @@
386 +6
386 +6
387 3: [mq]: 6.patch - test - 13.00
387 3: [mq]: 6.patch - test - 13.00
388 2: [mq]: 5.patch - test - 11.00
388 2: [mq]: 5.patch - test - 11.00
389 1: Three (again) - test - 8.00
389 1: Three (again) - test - 8.00
390 0: [mq]: 1.patch - test - 4.00
390 0: [mq]: 1.patch - test - 4.00
391 popping 6.patch
391 popping 6.patch
392 now at: 5.patch
392 now at: 5.patch
393 ==== qnew -u
393 ==== qnew -u
394 adding 6
394 adding 6
395 From: jane
395 From: jane
396
396
397 diff -r ... 6
397 diff -r ... 6
398 --- /dev/null
398 --- /dev/null
399 +++ b/6
399 +++ b/6
400 @@ -0,0 +1,1 @@
400 @@ -0,0 +1,1 @@
401 +6
401 +6
402 3: [mq]: 6.patch - jane
402 3: [mq]: 6.patch - jane
403 2: [mq]: 5.patch - test
403 2: [mq]: 5.patch - test
404 1: Three (again) - test
404 1: Three (again) - test
405 0: [mq]: 1.patch - test
405 0: [mq]: 1.patch - test
406 ==== qref -d
406 ==== qref -d
407 Date: 12 0
407 Date: 12 0
408 From: jane
408 From: jane
409
409
410 diff -r ... 6
410 diff -r ... 6
411 --- /dev/null
411 --- /dev/null
412 +++ b/6
412 +++ b/6
413 @@ -0,0 +1,1 @@
413 @@ -0,0 +1,1 @@
414 +6
414 +6
415 3: [mq]: 6.patch - jane
415 3: [mq]: 6.patch - jane
416 2: [mq]: 5.patch - test
416 2: [mq]: 5.patch - test
417 1: Three (again) - test
417 1: Three (again) - test
418 0: [mq]: 1.patch - test
418 0: [mq]: 1.patch - test
419 popping 6.patch
419 popping 6.patch
420 now at: 5.patch
420 now at: 5.patch
421 ==== qnew -d
421 ==== qnew -d
422 adding 7
422 adding 7
423 Date: 13 0
423 Date: 13 0
424
424
425 diff -r ... 7
425 diff -r ... 7
426 --- /dev/null
426 --- /dev/null
427 +++ b/7
427 +++ b/7
428 @@ -0,0 +1,1 @@
428 @@ -0,0 +1,1 @@
429 +7
429 +7
430 3: [mq]: 7.patch - test
430 3: [mq]: 7.patch - test
431 2: [mq]: 5.patch - test
431 2: [mq]: 5.patch - test
432 1: Three (again) - test
432 1: Three (again) - test
433 0: [mq]: 1.patch - test
433 0: [mq]: 1.patch - test
434 ==== qref -u
434 ==== qref -u
435 From: john
435 From: john
436 Date: 13 0
436 Date: 13 0
437
437
438 diff -r ... 7
438 diff -r ... 7
439 --- /dev/null
439 --- /dev/null
440 +++ b/7
440 +++ b/7
441 @@ -0,0 +1,1 @@
441 @@ -0,0 +1,1 @@
442 +7
442 +7
443 3: [mq]: 7.patch - john - 13.00
443 3: [mq]: 7.patch - john - 13.00
444 2: [mq]: 5.patch - test - 11.00
444 2: [mq]: 5.patch - test - 11.00
445 1: Three (again) - test - 8.00
445 1: Three (again) - test - 8.00
446 0: [mq]: 1.patch - test - 4.00
446 0: [mq]: 1.patch - test - 4.00
447 ==== qnew
447 ==== qnew
448 adding 8
448 adding 8
449 diff -r ... 8
449 diff -r ... 8
450 --- /dev/null
450 --- /dev/null
451 +++ b/8
451 +++ b/8
452 @@ -0,0 +1,1 @@
452 @@ -0,0 +1,1 @@
453 +8
453 +8
454 4: [mq]: 8.patch - test
454 4: [mq]: 8.patch - test
455 3: [mq]: 7.patch - john
455 3: [mq]: 7.patch - john
456 2: [mq]: 5.patch - test
456 2: [mq]: 5.patch - test
457 1: Three (again) - test
457 1: Three (again) - test
458 0: [mq]: 1.patch - test
458 0: [mq]: 1.patch - test
459 ==== qref -u -d
459 ==== qref -u -d
460 Date: 14 0
460 Date: 14 0
461 From: john
461 From: john
462
462
463 diff -r ... 8
463 diff -r ... 8
464 --- /dev/null
464 --- /dev/null
465 +++ b/8
465 +++ b/8
466 @@ -0,0 +1,1 @@
466 @@ -0,0 +1,1 @@
467 +8
467 +8
468 4: [mq]: 8.patch - john
468 4: [mq]: 8.patch - john
469 3: [mq]: 7.patch - john
469 3: [mq]: 7.patch - john
470 2: [mq]: 5.patch - test
470 2: [mq]: 5.patch - test
471 1: Three (again) - test
471 1: Three (again) - test
472 0: [mq]: 1.patch - test
472 0: [mq]: 1.patch - test
473 popping 8.patch
473 popping 8.patch
474 now at: 7.patch
474 now at: 7.patch
475 ==== qnew -m
475 ==== qnew -m
476 adding 9
476 adding 9
477 Nine
477 Nine
478
478
479 diff -r ... 9
479 diff -r ... 9
480 --- /dev/null
480 --- /dev/null
481 +++ b/9
481 +++ b/9
482 @@ -0,0 +1,1 @@
482 @@ -0,0 +1,1 @@
483 +9
483 +9
484 4: Nine - test
484 4: Nine - test
485 3: [mq]: 7.patch - john
485 3: [mq]: 7.patch - john
486 2: [mq]: 5.patch - test
486 2: [mq]: 5.patch - test
487 1: Three (again) - test
487 1: Three (again) - test
488 0: [mq]: 1.patch - test
488 0: [mq]: 1.patch - test
489 ==== qref -u -d
489 ==== qref -u -d
490 Date: 15 0
490 Date: 15 0
491 From: john
491 From: john
492 Nine
492 Nine
493
493
494 diff -r ... 9
494 diff -r ... 9
495 --- /dev/null
495 --- /dev/null
496 +++ b/9
496 +++ b/9
497 @@ -0,0 +1,1 @@
497 @@ -0,0 +1,1 @@
498 +9
498 +9
499 4: Nine - john
499 4: Nine - john
500 3: [mq]: 7.patch - john
500 3: [mq]: 7.patch - john
501 2: [mq]: 5.patch - test
501 2: [mq]: 5.patch - test
502 1: Three (again) - test
502 1: Three (again) - test
503 0: [mq]: 1.patch - test
503 0: [mq]: 1.patch - test
504 popping 9.patch
504 popping 9.patch
505 now at: 7.patch
505 now at: 7.patch
506 ==== qpop -a / qpush -a
506 ==== qpop -a / qpush -a
507 popping 7.patch
507 popping 7.patch
508 popping 5.patch
508 popping 5.patch
509 popping 3.patch
509 popping 3.patch
510 popping 1.patch
510 popping 1.patch
511 patch queue now empty
511 patch queue now empty
512 applying 1.patch
512 applying 1.patch
513 applying 3.patch
513 applying 3.patch
514 applying 5.patch
514 applying 5.patch
515 applying 7.patch
515 applying 7.patch
516 now at: 7.patch
516 now at: 7.patch
517 3: imported patch 7.patch - john - 13.00
517 3: imported patch 7.patch - john - 13.00
518 2: imported patch 5.patch - test - 11.00
518 2: imported patch 5.patch - test - 11.00
519 1: Three (again) - test - 8.00
519 1: Three (again) - test - 8.00
520 0: imported patch 1.patch - test - 4.00
520 0: imported patch 1.patch - test - 4.00
521 $ rm -r sandbox
521 $ rm -r sandbox
522
522
523 ======= hg headers
523 ======= hg headers
524
524
525 $ echo "plain=false" >> $HGRCPATH
525 $ echo "plain=false" >> $HGRCPATH
526 $ mkdir sandbox
526 $ mkdir sandbox
527 $ (cd sandbox ; runtest)
527 $ (cd sandbox ; runtest)
528 ==== init
528 ==== init
529 ==== qnew -d
529 ==== qnew -d
530 # HG changeset patch
530 # HG changeset patch
531 # Date 3 0
531 # Parent
532 # Parent
532 # Date 3 0
533
533
534 0: [mq]: 1.patch - test - 3.00
534 0: [mq]: 1.patch - test - 3.00
535 ==== qref
535 ==== qref
536 adding 1
536 adding 1
537 # HG changeset patch
537 # HG changeset patch
538 # Date 3 0
538 # Parent
539 # Parent
539 # Date 3 0
540
540
541 diff -r ... 1
541 diff -r ... 1
542 --- /dev/null
542 --- /dev/null
543 +++ b/1
543 +++ b/1
544 @@ -0,0 +1,1 @@
544 @@ -0,0 +1,1 @@
545 +1
545 +1
546 0: [mq]: 1.patch - test - 3.00
546 0: [mq]: 1.patch - test - 3.00
547 ==== qref -d
547 ==== qref -d
548 # HG changeset patch
548 # HG changeset patch
549 # Date 4 0
549 # Parent
550 # Parent
550 # Date 4 0
551
551
552 diff -r ... 1
552 diff -r ... 1
553 --- /dev/null
553 --- /dev/null
554 +++ b/1
554 +++ b/1
555 @@ -0,0 +1,1 @@
555 @@ -0,0 +1,1 @@
556 +1
556 +1
557 0: [mq]: 1.patch - test - 4.00
557 0: [mq]: 1.patch - test - 4.00
558 ==== qnew
558 ==== qnew
559 adding 2
559 adding 2
560 # HG changeset patch
560 # HG changeset patch
561 # Parent
561 # Parent
562
562
563 diff -r ... 2
563 diff -r ... 2
564 --- /dev/null
564 --- /dev/null
565 +++ b/2
565 +++ b/2
566 @@ -0,0 +1,1 @@
566 @@ -0,0 +1,1 @@
567 +2
567 +2
568 1: [mq]: 2.patch - test
568 1: [mq]: 2.patch - test
569 0: [mq]: 1.patch - test
569 0: [mq]: 1.patch - test
570 ==== qref -d
570 ==== qref -d
571 # HG changeset patch
571 # HG changeset patch
572 # Date 5 0
572 # Date 5 0
573 # Parent
573 # Parent
574
574
575 diff -r ... 2
575 diff -r ... 2
576 --- /dev/null
576 --- /dev/null
577 +++ b/2
577 +++ b/2
578 @@ -0,0 +1,1 @@
578 @@ -0,0 +1,1 @@
579 +2
579 +2
580 1: [mq]: 2.patch - test
580 1: [mq]: 2.patch - test
581 0: [mq]: 1.patch - test
581 0: [mq]: 1.patch - test
582 popping 2.patch
582 popping 2.patch
583 now at: 1.patch
583 now at: 1.patch
584 ==== qnew -d -m
584 ==== qnew -d -m
585 # HG changeset patch
585 # HG changeset patch
586 # Date 6 0
586 # Parent
587 # Parent
587 # Date 6 0
588 Three
588 Three
589
589
590 1: Three - test - 6.00
590 1: Three - test - 6.00
591 0: [mq]: 1.patch - test - 4.00
591 0: [mq]: 1.patch - test - 4.00
592 ==== qref
592 ==== qref
593 adding 3
593 adding 3
594 # HG changeset patch
594 # HG changeset patch
595 # Date 6 0
595 # Parent
596 # Parent
596 # Date 6 0
597 Three
597 Three
598
598
599 diff -r ... 3
599 diff -r ... 3
600 --- /dev/null
600 --- /dev/null
601 +++ b/3
601 +++ b/3
602 @@ -0,0 +1,1 @@
602 @@ -0,0 +1,1 @@
603 +3
603 +3
604 1: Three - test - 6.00
604 1: Three - test - 6.00
605 0: [mq]: 1.patch - test - 4.00
605 0: [mq]: 1.patch - test - 4.00
606 ==== qref -m
606 ==== qref -m
607 # HG changeset patch
607 # HG changeset patch
608 # Date 6 0
608 # Parent
609 # Parent
609 # Date 6 0
610 Drei
610 Drei
611
611
612 diff -r ... 3
612 diff -r ... 3
613 --- /dev/null
613 --- /dev/null
614 +++ b/3
614 +++ b/3
615 @@ -0,0 +1,1 @@
615 @@ -0,0 +1,1 @@
616 +3
616 +3
617 1: Drei - test - 6.00
617 1: Drei - test - 6.00
618 0: [mq]: 1.patch - test - 4.00
618 0: [mq]: 1.patch - test - 4.00
619 ==== qref -d
619 ==== qref -d
620 # HG changeset patch
620 # HG changeset patch
621 # Date 7 0
621 # Parent
622 # Parent
622 # Date 7 0
623 Drei
623 Drei
624
624
625 diff -r ... 3
625 diff -r ... 3
626 --- /dev/null
626 --- /dev/null
627 +++ b/3
627 +++ b/3
628 @@ -0,0 +1,1 @@
628 @@ -0,0 +1,1 @@
629 +3
629 +3
630 1: Drei - test - 7.00
630 1: Drei - test - 7.00
631 0: [mq]: 1.patch - test - 4.00
631 0: [mq]: 1.patch - test - 4.00
632 ==== qref -d -m
632 ==== qref -d -m
633 # HG changeset patch
633 # HG changeset patch
634 # Date 8 0
634 # Parent
635 # Parent
635 # Date 8 0
636 Three (again)
636 Three (again)
637
637
638 diff -r ... 3
638 diff -r ... 3
639 --- /dev/null
639 --- /dev/null
640 +++ b/3
640 +++ b/3
641 @@ -0,0 +1,1 @@
641 @@ -0,0 +1,1 @@
642 +3
642 +3
643 1: Three (again) - test - 8.00
643 1: Three (again) - test - 8.00
644 0: [mq]: 1.patch - test - 4.00
644 0: [mq]: 1.patch - test - 4.00
645 ==== qnew -m
645 ==== qnew -m
646 adding 4
646 adding 4
647 # HG changeset patch
647 # HG changeset patch
648 # Parent
648 # Parent
649 Four
649 Four
650
650
651 diff -r ... 4
651 diff -r ... 4
652 --- /dev/null
652 --- /dev/null
653 +++ b/4
653 +++ b/4
654 @@ -0,0 +1,1 @@
654 @@ -0,0 +1,1 @@
655 +4
655 +4
656 2: Four - test
656 2: Four - test
657 1: Three (again) - test
657 1: Three (again) - test
658 0: [mq]: 1.patch - test
658 0: [mq]: 1.patch - test
659 ==== qref -d
659 ==== qref -d
660 # HG changeset patch
660 # HG changeset patch
661 # Date 9 0
661 # Date 9 0
662 # Parent
662 # Parent
663 Four
663 Four
664
664
665 diff -r ... 4
665 diff -r ... 4
666 --- /dev/null
666 --- /dev/null
667 +++ b/4
667 +++ b/4
668 @@ -0,0 +1,1 @@
668 @@ -0,0 +1,1 @@
669 +4
669 +4
670 2: Four - test
670 2: Four - test
671 1: Three (again) - test
671 1: Three (again) - test
672 0: [mq]: 1.patch - test
672 0: [mq]: 1.patch - test
673 popping 4.patch
673 popping 4.patch
674 now at: 3.patch
674 now at: 3.patch
675 ==== qnew with HG header
675 ==== qnew with HG header
676 popping 5.patch
676 popping 5.patch
677 now at: 3.patch
677 now at: 3.patch
678 # HG changeset patch
678 # HG changeset patch
679 # Date 10 0
679 # Date 10 0
680 2: imported patch 5.patch - test - 10.00
680 2: imported patch 5.patch - test - 10.00
681 1: Three (again) - test - 8.00
681 1: Three (again) - test - 8.00
682 0: [mq]: 1.patch - test - 4.00
682 0: [mq]: 1.patch - test - 4.00
683 ==== hg qref
683 ==== hg qref
684 adding 5
684 adding 5
685 # HG changeset patch
685 # HG changeset patch
686 # Parent
686 # Parent
687 # Date 10 0
687 # Date 10 0
688
688
689 diff -r ... 5
689 diff -r ... 5
690 --- /dev/null
690 --- /dev/null
691 +++ b/5
691 +++ b/5
692 @@ -0,0 +1,1 @@
692 @@ -0,0 +1,1 @@
693 +5
693 +5
694 2: [mq]: 5.patch - test - 10.00
694 2: [mq]: 5.patch - test - 10.00
695 1: Three (again) - test - 8.00
695 1: Three (again) - test - 8.00
696 0: [mq]: 1.patch - test - 4.00
696 0: [mq]: 1.patch - test - 4.00
697 ==== hg qref -d
697 ==== hg qref -d
698 # HG changeset patch
698 # HG changeset patch
699 # Parent
699 # Parent
700 # Date 11 0
700 # Date 11 0
701
701
702 diff -r ... 5
702 diff -r ... 5
703 --- /dev/null
703 --- /dev/null
704 +++ b/5
704 +++ b/5
705 @@ -0,0 +1,1 @@
705 @@ -0,0 +1,1 @@
706 +5
706 +5
707 2: [mq]: 5.patch - test - 11.00
707 2: [mq]: 5.patch - test - 11.00
708 1: Three (again) - test - 8.00
708 1: Three (again) - test - 8.00
709 0: [mq]: 1.patch - test - 4.00
709 0: [mq]: 1.patch - test - 4.00
710 ==== qnew with plain header
710 ==== qnew with plain header
711 popping 6.patch
711 popping 6.patch
712 now at: 5.patch
712 now at: 5.patch
713 now at: 6.patch
713 now at: 6.patch
714 Date: 12 0
714 Date: 12 0
715
715
716 3: imported patch 6.patch - test
716 3: imported patch 6.patch - test
717 2: [mq]: 5.patch - test
717 2: [mq]: 5.patch - test
718 1: Three (again) - test
718 1: Three (again) - test
719 0: [mq]: 1.patch - test
719 0: [mq]: 1.patch - test
720 ==== hg qref
720 ==== hg qref
721 adding 6
721 adding 6
722 Date: 12 0
722 Date: 12 0
723
723
724 diff -r ... 6
724 diff -r ... 6
725 --- /dev/null
725 --- /dev/null
726 +++ b/6
726 +++ b/6
727 @@ -0,0 +1,1 @@
727 @@ -0,0 +1,1 @@
728 +6
728 +6
729 3: [mq]: 6.patch - test - 12.00
729 3: [mq]: 6.patch - test - 12.00
730 2: [mq]: 5.patch - test - 11.00
730 2: [mq]: 5.patch - test - 11.00
731 1: Three (again) - test - 8.00
731 1: Three (again) - test - 8.00
732 0: [mq]: 1.patch - test - 4.00
732 0: [mq]: 1.patch - test - 4.00
733 ==== hg qref -d
733 ==== hg qref -d
734 Date: 13 0
734 Date: 13 0
735
735
736 diff -r ... 6
736 diff -r ... 6
737 --- /dev/null
737 --- /dev/null
738 +++ b/6
738 +++ b/6
739 @@ -0,0 +1,1 @@
739 @@ -0,0 +1,1 @@
740 +6
740 +6
741 3: [mq]: 6.patch - test - 13.00
741 3: [mq]: 6.patch - test - 13.00
742 2: [mq]: 5.patch - test - 11.00
742 2: [mq]: 5.patch - test - 11.00
743 1: Three (again) - test - 8.00
743 1: Three (again) - test - 8.00
744 0: [mq]: 1.patch - test - 4.00
744 0: [mq]: 1.patch - test - 4.00
745 popping 6.patch
745 popping 6.patch
746 now at: 5.patch
746 now at: 5.patch
747 ==== qnew -u
747 ==== qnew -u
748 adding 6
748 adding 6
749 # HG changeset patch
749 # HG changeset patch
750 # User jane
750 # Parent
751 # Parent
751 # User jane
752
752
753 diff -r ... 6
753 diff -r ... 6
754 --- /dev/null
754 --- /dev/null
755 +++ b/6
755 +++ b/6
756 @@ -0,0 +1,1 @@
756 @@ -0,0 +1,1 @@
757 +6
757 +6
758 3: [mq]: 6.patch - jane
758 3: [mq]: 6.patch - jane
759 2: [mq]: 5.patch - test
759 2: [mq]: 5.patch - test
760 1: Three (again) - test
760 1: Three (again) - test
761 0: [mq]: 1.patch - test
761 0: [mq]: 1.patch - test
762 ==== qref -d
762 ==== qref -d
763 # HG changeset patch
763 # HG changeset patch
764 # Date 12 0
764 # Date 12 0
765 # User jane
765 # Parent
766 # Parent
766 # User jane
767
767
768 diff -r ... 6
768 diff -r ... 6
769 --- /dev/null
769 --- /dev/null
770 +++ b/6
770 +++ b/6
771 @@ -0,0 +1,1 @@
771 @@ -0,0 +1,1 @@
772 +6
772 +6
773 3: [mq]: 6.patch - jane
773 3: [mq]: 6.patch - jane
774 2: [mq]: 5.patch - test
774 2: [mq]: 5.patch - test
775 1: Three (again) - test
775 1: Three (again) - test
776 0: [mq]: 1.patch - test
776 0: [mq]: 1.patch - test
777 popping 6.patch
777 popping 6.patch
778 now at: 5.patch
778 now at: 5.patch
779 ==== qnew -d
779 ==== qnew -d
780 adding 7
780 adding 7
781 # HG changeset patch
781 # HG changeset patch
782 # Date 13 0
782 # Parent
783 # Parent
783 # Date 13 0
784
784
785 diff -r ... 7
785 diff -r ... 7
786 --- /dev/null
786 --- /dev/null
787 +++ b/7
787 +++ b/7
788 @@ -0,0 +1,1 @@
788 @@ -0,0 +1,1 @@
789 +7
789 +7
790 3: [mq]: 7.patch - test
790 3: [mq]: 7.patch - test
791 2: [mq]: 5.patch - test
791 2: [mq]: 5.patch - test
792 1: Three (again) - test
792 1: Three (again) - test
793 0: [mq]: 1.patch - test
793 0: [mq]: 1.patch - test
794 ==== qref -u
794 ==== qref -u
795 # HG changeset patch
795 # HG changeset patch
796 # User john
796 # User john
797 # Date 13 0
797 # Parent
798 # Parent
798 # Date 13 0
799
799
800 diff -r ... 7
800 diff -r ... 7
801 --- /dev/null
801 --- /dev/null
802 +++ b/7
802 +++ b/7
803 @@ -0,0 +1,1 @@
803 @@ -0,0 +1,1 @@
804 +7
804 +7
805 3: [mq]: 7.patch - john - 13.00
805 3: [mq]: 7.patch - john - 13.00
806 2: [mq]: 5.patch - test - 11.00
806 2: [mq]: 5.patch - test - 11.00
807 1: Three (again) - test - 8.00
807 1: Three (again) - test - 8.00
808 0: [mq]: 1.patch - test - 4.00
808 0: [mq]: 1.patch - test - 4.00
809 ==== qnew
809 ==== qnew
810 adding 8
810 adding 8
811 # HG changeset patch
811 # HG changeset patch
812 # Parent
812 # Parent
813
813
814 diff -r ... 8
814 diff -r ... 8
815 --- /dev/null
815 --- /dev/null
816 +++ b/8
816 +++ b/8
817 @@ -0,0 +1,1 @@
817 @@ -0,0 +1,1 @@
818 +8
818 +8
819 4: [mq]: 8.patch - test
819 4: [mq]: 8.patch - test
820 3: [mq]: 7.patch - john
820 3: [mq]: 7.patch - john
821 2: [mq]: 5.patch - test
821 2: [mq]: 5.patch - test
822 1: Three (again) - test
822 1: Three (again) - test
823 0: [mq]: 1.patch - test
823 0: [mq]: 1.patch - test
824 ==== qref -u -d
824 ==== qref -u -d
825 # HG changeset patch
825 # HG changeset patch
826 # Date 14 0
826 # Date 14 0
827 # User john
827 # User john
828 # Parent
828 # Parent
829
829
830 diff -r ... 8
830 diff -r ... 8
831 --- /dev/null
831 --- /dev/null
832 +++ b/8
832 +++ b/8
833 @@ -0,0 +1,1 @@
833 @@ -0,0 +1,1 @@
834 +8
834 +8
835 4: [mq]: 8.patch - john
835 4: [mq]: 8.patch - john
836 3: [mq]: 7.patch - john
836 3: [mq]: 7.patch - john
837 2: [mq]: 5.patch - test
837 2: [mq]: 5.patch - test
838 1: Three (again) - test
838 1: Three (again) - test
839 0: [mq]: 1.patch - test
839 0: [mq]: 1.patch - test
840 popping 8.patch
840 popping 8.patch
841 now at: 7.patch
841 now at: 7.patch
842 ==== qnew -m
842 ==== qnew -m
843 adding 9
843 adding 9
844 # HG changeset patch
844 # HG changeset patch
845 # Parent
845 # Parent
846 Nine
846 Nine
847
847
848 diff -r ... 9
848 diff -r ... 9
849 --- /dev/null
849 --- /dev/null
850 +++ b/9
850 +++ b/9
851 @@ -0,0 +1,1 @@
851 @@ -0,0 +1,1 @@
852 +9
852 +9
853 4: Nine - test
853 4: Nine - test
854 3: [mq]: 7.patch - john
854 3: [mq]: 7.patch - john
855 2: [mq]: 5.patch - test
855 2: [mq]: 5.patch - test
856 1: Three (again) - test
856 1: Three (again) - test
857 0: [mq]: 1.patch - test
857 0: [mq]: 1.patch - test
858 ==== qref -u -d
858 ==== qref -u -d
859 # HG changeset patch
859 # HG changeset patch
860 # Date 15 0
860 # Date 15 0
861 # User john
861 # User john
862 # Parent
862 # Parent
863 Nine
863 Nine
864
864
865 diff -r ... 9
865 diff -r ... 9
866 --- /dev/null
866 --- /dev/null
867 +++ b/9
867 +++ b/9
868 @@ -0,0 +1,1 @@
868 @@ -0,0 +1,1 @@
869 +9
869 +9
870 4: Nine - john
870 4: Nine - john
871 3: [mq]: 7.patch - john
871 3: [mq]: 7.patch - john
872 2: [mq]: 5.patch - test
872 2: [mq]: 5.patch - test
873 1: Three (again) - test
873 1: Three (again) - test
874 0: [mq]: 1.patch - test
874 0: [mq]: 1.patch - test
875 popping 9.patch
875 popping 9.patch
876 now at: 7.patch
876 now at: 7.patch
877 ==== qpop -a / qpush -a
877 ==== qpop -a / qpush -a
878 popping 7.patch
878 popping 7.patch
879 popping 5.patch
879 popping 5.patch
880 popping 3.patch
880 popping 3.patch
881 popping 1.patch
881 popping 1.patch
882 patch queue now empty
882 patch queue now empty
883 applying 1.patch
883 applying 1.patch
884 applying 3.patch
884 applying 3.patch
885 applying 5.patch
885 applying 5.patch
886 applying 7.patch
886 applying 7.patch
887 now at: 7.patch
887 now at: 7.patch
888 3: imported patch 7.patch - john - 13.00
888 3: imported patch 7.patch - john - 13.00
889 2: imported patch 5.patch - test - 11.00
889 2: imported patch 5.patch - test - 11.00
890 1: Three (again) - test - 8.00
890 1: Three (again) - test - 8.00
891 0: imported patch 1.patch - test - 4.00
891 0: imported patch 1.patch - test - 4.00
892 $ rm -r sandbox
892 $ rm -r sandbox
@@ -1,968 +1,968 b''
1
1
2 $ echo "[extensions]" >> $HGRCPATH
2 $ echo "[extensions]" >> $HGRCPATH
3 $ echo "mq=" >> $HGRCPATH
3 $ echo "mq=" >> $HGRCPATH
4 $ echo "[diff]" >> $HGRCPATH
4 $ echo "[diff]" >> $HGRCPATH
5 $ echo "nodates=true" >> $HGRCPATH
5 $ echo "nodates=true" >> $HGRCPATH
6 $ catlog() {
6 $ catlog() {
7 > cat .hg/patches/$1.patch | sed -e "s/^diff \-r [0-9a-f]* /diff -r ... /" \
7 > cat .hg/patches/$1.patch | sed -e "s/^diff \-r [0-9a-f]* /diff -r ... /" \
8 > -e "s/^\(# Parent \).*/\1/"
8 > -e "s/^\(# Parent \).*/\1/"
9 > hg log --template "{rev}: {desc} - {author}\n"
9 > hg log --template "{rev}: {desc} - {author}\n"
10 > }
10 > }
11 $ runtest() {
11 $ runtest() {
12 > echo ==== init
12 > echo ==== init
13 > hg init a
13 > hg init a
14 > cd a
14 > cd a
15 > hg qinit
15 > hg qinit
16 >
16 >
17 >
17 >
18 > echo ==== qnew -U
18 > echo ==== qnew -U
19 > hg qnew -U 1.patch
19 > hg qnew -U 1.patch
20 > catlog 1
20 > catlog 1
21 >
21 >
22 > echo ==== qref
22 > echo ==== qref
23 > echo "1" >1
23 > echo "1" >1
24 > hg add
24 > hg add
25 > hg qref
25 > hg qref
26 > catlog 1
26 > catlog 1
27 >
27 >
28 > echo ==== qref -u
28 > echo ==== qref -u
29 > hg qref -u mary
29 > hg qref -u mary
30 > catlog 1
30 > catlog 1
31 >
31 >
32 > echo ==== qnew
32 > echo ==== qnew
33 > hg qnew 2.patch
33 > hg qnew 2.patch
34 > echo "2" >2
34 > echo "2" >2
35 > hg add
35 > hg add
36 > hg qref
36 > hg qref
37 > catlog 2
37 > catlog 2
38 >
38 >
39 > echo ==== qref -u
39 > echo ==== qref -u
40 > hg qref -u jane
40 > hg qref -u jane
41 > catlog 2
41 > catlog 2
42 >
42 >
43 >
43 >
44 > echo ==== qnew -U -m
44 > echo ==== qnew -U -m
45 > hg qnew -U -m "Three" 3.patch
45 > hg qnew -U -m "Three" 3.patch
46 > catlog 3
46 > catlog 3
47 >
47 >
48 > echo ==== qref
48 > echo ==== qref
49 > echo "3" >3
49 > echo "3" >3
50 > hg add
50 > hg add
51 > hg qref
51 > hg qref
52 > catlog 3
52 > catlog 3
53 >
53 >
54 > echo ==== qref -m
54 > echo ==== qref -m
55 > hg qref -m "Drei"
55 > hg qref -m "Drei"
56 > catlog 3
56 > catlog 3
57 >
57 >
58 > echo ==== qref -u
58 > echo ==== qref -u
59 > hg qref -u mary
59 > hg qref -u mary
60 > catlog 3
60 > catlog 3
61 >
61 >
62 > echo ==== qref -u -m
62 > echo ==== qref -u -m
63 > hg qref -u maria -m "Three (again)"
63 > hg qref -u maria -m "Three (again)"
64 > catlog 3
64 > catlog 3
65 >
65 >
66 > echo ==== qnew -m
66 > echo ==== qnew -m
67 > hg qnew -m "Four" 4.patch
67 > hg qnew -m "Four" 4.patch
68 > echo "4" >4of t
68 > echo "4" >4of t
69 > hg add
69 > hg add
70 > hg qref
70 > hg qref
71 > catlog 4
71 > catlog 4
72 >
72 >
73 > echo ==== qref -u
73 > echo ==== qref -u
74 > hg qref -u jane
74 > hg qref -u jane
75 > catlog 4
75 > catlog 4
76 >
76 >
77 >
77 >
78 > echo ==== qnew with HG header
78 > echo ==== qnew with HG header
79 > hg qnew --config 'mq.plain=true' 5.patch
79 > hg qnew --config 'mq.plain=true' 5.patch
80 > hg qpop
80 > hg qpop
81 > echo "# HG changeset patch" >>.hg/patches/5.patch
81 > echo "# HG changeset patch" >>.hg/patches/5.patch
82 > echo "# User johndoe" >>.hg/patches/5.patch
82 > echo "# User johndoe" >>.hg/patches/5.patch
83 > hg qpush 2>&1 | grep 'now at'
83 > hg qpush 2>&1 | grep 'now at'
84 > catlog 5
84 > catlog 5
85 >
85 >
86 > echo ==== hg qref
86 > echo ==== hg qref
87 > echo "5" >5
87 > echo "5" >5
88 > hg add
88 > hg add
89 > hg qref
89 > hg qref
90 > catlog 5
90 > catlog 5
91 >
91 >
92 > echo ==== hg qref -U
92 > echo ==== hg qref -U
93 > hg qref -U
93 > hg qref -U
94 > catlog 5
94 > catlog 5
95 >
95 >
96 > echo ==== hg qref -u
96 > echo ==== hg qref -u
97 > hg qref -u johndeere
97 > hg qref -u johndeere
98 > catlog 5
98 > catlog 5
99 >
99 >
100 >
100 >
101 > echo ==== qnew with plain header
101 > echo ==== qnew with plain header
102 > hg qnew --config 'mq.plain=true' -U 6.patch
102 > hg qnew --config 'mq.plain=true' -U 6.patch
103 > hg qpop
103 > hg qpop
104 > hg qpush 2>&1 | grep 'now at'
104 > hg qpush 2>&1 | grep 'now at'
105 > catlog 6
105 > catlog 6
106 >
106 >
107 > echo ==== hg qref
107 > echo ==== hg qref
108 > echo "6" >6
108 > echo "6" >6
109 > hg add
109 > hg add
110 > hg qref
110 > hg qref
111 > catlog 6
111 > catlog 6
112 >
112 >
113 > echo ==== hg qref -U
113 > echo ==== hg qref -U
114 > hg qref -U
114 > hg qref -U
115 > catlog 6
115 > catlog 6
116 >
116 >
117 > echo ==== hg qref -u
117 > echo ==== hg qref -u
118 > hg qref -u johndeere
118 > hg qref -u johndeere
119 > catlog 6
119 > catlog 6
120 >
120 >
121 >
121 >
122 > echo ==== "qpop -a / qpush -a"
122 > echo ==== "qpop -a / qpush -a"
123 > hg qpop -a
123 > hg qpop -a
124 > hg qpush -a
124 > hg qpush -a
125 > hg log --template "{rev}: {desc} - {author}\n"
125 > hg log --template "{rev}: {desc} - {author}\n"
126 > }
126 > }
127
127
128 ======= plain headers
128 ======= plain headers
129
129
130 $ echo "[mq]" >> $HGRCPATH
130 $ echo "[mq]" >> $HGRCPATH
131 $ echo "plain=true" >> $HGRCPATH
131 $ echo "plain=true" >> $HGRCPATH
132 $ mkdir sandbox
132 $ mkdir sandbox
133 $ (cd sandbox ; runtest)
133 $ (cd sandbox ; runtest)
134 ==== init
134 ==== init
135 ==== qnew -U
135 ==== qnew -U
136 From: test
136 From: test
137
137
138 0: [mq]: 1.patch - test
138 0: [mq]: 1.patch - test
139 ==== qref
139 ==== qref
140 adding 1
140 adding 1
141 From: test
141 From: test
142
142
143 diff -r ... 1
143 diff -r ... 1
144 --- /dev/null
144 --- /dev/null
145 +++ b/1
145 +++ b/1
146 @@ -0,0 +1,1 @@
146 @@ -0,0 +1,1 @@
147 +1
147 +1
148 0: [mq]: 1.patch - test
148 0: [mq]: 1.patch - test
149 ==== qref -u
149 ==== qref -u
150 From: mary
150 From: mary
151
151
152 diff -r ... 1
152 diff -r ... 1
153 --- /dev/null
153 --- /dev/null
154 +++ b/1
154 +++ b/1
155 @@ -0,0 +1,1 @@
155 @@ -0,0 +1,1 @@
156 +1
156 +1
157 0: [mq]: 1.patch - mary
157 0: [mq]: 1.patch - mary
158 ==== qnew
158 ==== qnew
159 adding 2
159 adding 2
160 diff -r ... 2
160 diff -r ... 2
161 --- /dev/null
161 --- /dev/null
162 +++ b/2
162 +++ b/2
163 @@ -0,0 +1,1 @@
163 @@ -0,0 +1,1 @@
164 +2
164 +2
165 1: [mq]: 2.patch - test
165 1: [mq]: 2.patch - test
166 0: [mq]: 1.patch - mary
166 0: [mq]: 1.patch - mary
167 ==== qref -u
167 ==== qref -u
168 From: jane
168 From: jane
169
169
170 diff -r ... 2
170 diff -r ... 2
171 --- /dev/null
171 --- /dev/null
172 +++ b/2
172 +++ b/2
173 @@ -0,0 +1,1 @@
173 @@ -0,0 +1,1 @@
174 +2
174 +2
175 1: [mq]: 2.patch - jane
175 1: [mq]: 2.patch - jane
176 0: [mq]: 1.patch - mary
176 0: [mq]: 1.patch - mary
177 ==== qnew -U -m
177 ==== qnew -U -m
178 From: test
178 From: test
179 Three
179 Three
180
180
181 2: Three - test
181 2: Three - test
182 1: [mq]: 2.patch - jane
182 1: [mq]: 2.patch - jane
183 0: [mq]: 1.patch - mary
183 0: [mq]: 1.patch - mary
184 ==== qref
184 ==== qref
185 adding 3
185 adding 3
186 From: test
186 From: test
187 Three
187 Three
188
188
189 diff -r ... 3
189 diff -r ... 3
190 --- /dev/null
190 --- /dev/null
191 +++ b/3
191 +++ b/3
192 @@ -0,0 +1,1 @@
192 @@ -0,0 +1,1 @@
193 +3
193 +3
194 2: Three - test
194 2: Three - test
195 1: [mq]: 2.patch - jane
195 1: [mq]: 2.patch - jane
196 0: [mq]: 1.patch - mary
196 0: [mq]: 1.patch - mary
197 ==== qref -m
197 ==== qref -m
198 From: test
198 From: test
199 Drei
199 Drei
200
200
201 diff -r ... 3
201 diff -r ... 3
202 --- /dev/null
202 --- /dev/null
203 +++ b/3
203 +++ b/3
204 @@ -0,0 +1,1 @@
204 @@ -0,0 +1,1 @@
205 +3
205 +3
206 2: Drei - test
206 2: Drei - test
207 1: [mq]: 2.patch - jane
207 1: [mq]: 2.patch - jane
208 0: [mq]: 1.patch - mary
208 0: [mq]: 1.patch - mary
209 ==== qref -u
209 ==== qref -u
210 From: mary
210 From: mary
211 Drei
211 Drei
212
212
213 diff -r ... 3
213 diff -r ... 3
214 --- /dev/null
214 --- /dev/null
215 +++ b/3
215 +++ b/3
216 @@ -0,0 +1,1 @@
216 @@ -0,0 +1,1 @@
217 +3
217 +3
218 2: Drei - mary
218 2: Drei - mary
219 1: [mq]: 2.patch - jane
219 1: [mq]: 2.patch - jane
220 0: [mq]: 1.patch - mary
220 0: [mq]: 1.patch - mary
221 ==== qref -u -m
221 ==== qref -u -m
222 From: maria
222 From: maria
223 Three (again)
223 Three (again)
224
224
225 diff -r ... 3
225 diff -r ... 3
226 --- /dev/null
226 --- /dev/null
227 +++ b/3
227 +++ b/3
228 @@ -0,0 +1,1 @@
228 @@ -0,0 +1,1 @@
229 +3
229 +3
230 2: Three (again) - maria
230 2: Three (again) - maria
231 1: [mq]: 2.patch - jane
231 1: [mq]: 2.patch - jane
232 0: [mq]: 1.patch - mary
232 0: [mq]: 1.patch - mary
233 ==== qnew -m
233 ==== qnew -m
234 adding 4of
234 adding 4of
235 Four
235 Four
236
236
237 diff -r ... 4of
237 diff -r ... 4of
238 --- /dev/null
238 --- /dev/null
239 +++ b/4of
239 +++ b/4of
240 @@ -0,0 +1,1 @@
240 @@ -0,0 +1,1 @@
241 +4 t
241 +4 t
242 3: Four - test
242 3: Four - test
243 2: Three (again) - maria
243 2: Three (again) - maria
244 1: [mq]: 2.patch - jane
244 1: [mq]: 2.patch - jane
245 0: [mq]: 1.patch - mary
245 0: [mq]: 1.patch - mary
246 ==== qref -u
246 ==== qref -u
247 From: jane
247 From: jane
248 Four
248 Four
249
249
250 diff -r ... 4of
250 diff -r ... 4of
251 --- /dev/null
251 --- /dev/null
252 +++ b/4of
252 +++ b/4of
253 @@ -0,0 +1,1 @@
253 @@ -0,0 +1,1 @@
254 +4 t
254 +4 t
255 3: Four - jane
255 3: Four - jane
256 2: Three (again) - maria
256 2: Three (again) - maria
257 1: [mq]: 2.patch - jane
257 1: [mq]: 2.patch - jane
258 0: [mq]: 1.patch - mary
258 0: [mq]: 1.patch - mary
259 ==== qnew with HG header
259 ==== qnew with HG header
260 popping 5.patch
260 popping 5.patch
261 now at: 4.patch
261 now at: 4.patch
262 now at: 5.patch
262 now at: 5.patch
263 # HG changeset patch
263 # HG changeset patch
264 # User johndoe
264 # User johndoe
265 4: imported patch 5.patch - johndoe
265 4: imported patch 5.patch - johndoe
266 3: Four - jane
266 3: Four - jane
267 2: Three (again) - maria
267 2: Three (again) - maria
268 1: [mq]: 2.patch - jane
268 1: [mq]: 2.patch - jane
269 0: [mq]: 1.patch - mary
269 0: [mq]: 1.patch - mary
270 ==== hg qref
270 ==== hg qref
271 adding 5
271 adding 5
272 # HG changeset patch
272 # HG changeset patch
273 # Parent
273 # Parent
274 # User johndoe
274 # User johndoe
275
275
276 diff -r ... 5
276 diff -r ... 5
277 --- /dev/null
277 --- /dev/null
278 +++ b/5
278 +++ b/5
279 @@ -0,0 +1,1 @@
279 @@ -0,0 +1,1 @@
280 +5
280 +5
281 4: [mq]: 5.patch - johndoe
281 4: [mq]: 5.patch - johndoe
282 3: Four - jane
282 3: Four - jane
283 2: Three (again) - maria
283 2: Three (again) - maria
284 1: [mq]: 2.patch - jane
284 1: [mq]: 2.patch - jane
285 0: [mq]: 1.patch - mary
285 0: [mq]: 1.patch - mary
286 ==== hg qref -U
286 ==== hg qref -U
287 # HG changeset patch
287 # HG changeset patch
288 # Parent
288 # Parent
289 # User test
289 # User test
290
290
291 diff -r ... 5
291 diff -r ... 5
292 --- /dev/null
292 --- /dev/null
293 +++ b/5
293 +++ b/5
294 @@ -0,0 +1,1 @@
294 @@ -0,0 +1,1 @@
295 +5
295 +5
296 4: [mq]: 5.patch - test
296 4: [mq]: 5.patch - test
297 3: Four - jane
297 3: Four - jane
298 2: Three (again) - maria
298 2: Three (again) - maria
299 1: [mq]: 2.patch - jane
299 1: [mq]: 2.patch - jane
300 0: [mq]: 1.patch - mary
300 0: [mq]: 1.patch - mary
301 ==== hg qref -u
301 ==== hg qref -u
302 # HG changeset patch
302 # HG changeset patch
303 # Parent
303 # Parent
304 # User johndeere
304 # User johndeere
305
305
306 diff -r ... 5
306 diff -r ... 5
307 --- /dev/null
307 --- /dev/null
308 +++ b/5
308 +++ b/5
309 @@ -0,0 +1,1 @@
309 @@ -0,0 +1,1 @@
310 +5
310 +5
311 4: [mq]: 5.patch - johndeere
311 4: [mq]: 5.patch - johndeere
312 3: Four - jane
312 3: Four - jane
313 2: Three (again) - maria
313 2: Three (again) - maria
314 1: [mq]: 2.patch - jane
314 1: [mq]: 2.patch - jane
315 0: [mq]: 1.patch - mary
315 0: [mq]: 1.patch - mary
316 ==== qnew with plain header
316 ==== qnew with plain header
317 popping 6.patch
317 popping 6.patch
318 now at: 5.patch
318 now at: 5.patch
319 now at: 6.patch
319 now at: 6.patch
320 From: test
320 From: test
321
321
322 5: imported patch 6.patch - test
322 5: imported patch 6.patch - test
323 4: [mq]: 5.patch - johndeere
323 4: [mq]: 5.patch - johndeere
324 3: Four - jane
324 3: Four - jane
325 2: Three (again) - maria
325 2: Three (again) - maria
326 1: [mq]: 2.patch - jane
326 1: [mq]: 2.patch - jane
327 0: [mq]: 1.patch - mary
327 0: [mq]: 1.patch - mary
328 ==== hg qref
328 ==== hg qref
329 adding 6
329 adding 6
330 From: test
330 From: test
331
331
332 diff -r ... 6
332 diff -r ... 6
333 --- /dev/null
333 --- /dev/null
334 +++ b/6
334 +++ b/6
335 @@ -0,0 +1,1 @@
335 @@ -0,0 +1,1 @@
336 +6
336 +6
337 5: [mq]: 6.patch - test
337 5: [mq]: 6.patch - test
338 4: [mq]: 5.patch - johndeere
338 4: [mq]: 5.patch - johndeere
339 3: Four - jane
339 3: Four - jane
340 2: Three (again) - maria
340 2: Three (again) - maria
341 1: [mq]: 2.patch - jane
341 1: [mq]: 2.patch - jane
342 0: [mq]: 1.patch - mary
342 0: [mq]: 1.patch - mary
343 ==== hg qref -U
343 ==== hg qref -U
344 From: test
344 From: test
345
345
346 diff -r ... 6
346 diff -r ... 6
347 --- /dev/null
347 --- /dev/null
348 +++ b/6
348 +++ b/6
349 @@ -0,0 +1,1 @@
349 @@ -0,0 +1,1 @@
350 +6
350 +6
351 5: [mq]: 6.patch - test
351 5: [mq]: 6.patch - test
352 4: [mq]: 5.patch - johndeere
352 4: [mq]: 5.patch - johndeere
353 3: Four - jane
353 3: Four - jane
354 2: Three (again) - maria
354 2: Three (again) - maria
355 1: [mq]: 2.patch - jane
355 1: [mq]: 2.patch - jane
356 0: [mq]: 1.patch - mary
356 0: [mq]: 1.patch - mary
357 ==== hg qref -u
357 ==== hg qref -u
358 From: johndeere
358 From: johndeere
359
359
360 diff -r ... 6
360 diff -r ... 6
361 --- /dev/null
361 --- /dev/null
362 +++ b/6
362 +++ b/6
363 @@ -0,0 +1,1 @@
363 @@ -0,0 +1,1 @@
364 +6
364 +6
365 5: [mq]: 6.patch - johndeere
365 5: [mq]: 6.patch - johndeere
366 4: [mq]: 5.patch - johndeere
366 4: [mq]: 5.patch - johndeere
367 3: Four - jane
367 3: Four - jane
368 2: Three (again) - maria
368 2: Three (again) - maria
369 1: [mq]: 2.patch - jane
369 1: [mq]: 2.patch - jane
370 0: [mq]: 1.patch - mary
370 0: [mq]: 1.patch - mary
371 ==== qpop -a / qpush -a
371 ==== qpop -a / qpush -a
372 popping 6.patch
372 popping 6.patch
373 popping 5.patch
373 popping 5.patch
374 popping 4.patch
374 popping 4.patch
375 popping 3.patch
375 popping 3.patch
376 popping 2.patch
376 popping 2.patch
377 popping 1.patch
377 popping 1.patch
378 patch queue now empty
378 patch queue now empty
379 applying 1.patch
379 applying 1.patch
380 applying 2.patch
380 applying 2.patch
381 applying 3.patch
381 applying 3.patch
382 applying 4.patch
382 applying 4.patch
383 applying 5.patch
383 applying 5.patch
384 applying 6.patch
384 applying 6.patch
385 now at: 6.patch
385 now at: 6.patch
386 5: imported patch 6.patch - johndeere
386 5: imported patch 6.patch - johndeere
387 4: imported patch 5.patch - johndeere
387 4: imported patch 5.patch - johndeere
388 3: Four - jane
388 3: Four - jane
389 2: Three (again) - maria
389 2: Three (again) - maria
390 1: imported patch 2.patch - jane
390 1: imported patch 2.patch - jane
391 0: imported patch 1.patch - mary
391 0: imported patch 1.patch - mary
392 $ rm -r sandbox
392 $ rm -r sandbox
393
393
394 ======= hg headers
394 ======= hg headers
395
395
396 $ echo "plain=false" >> $HGRCPATH
396 $ echo "plain=false" >> $HGRCPATH
397 $ mkdir sandbox
397 $ mkdir sandbox
398 $ (cd sandbox ; runtest)
398 $ (cd sandbox ; runtest)
399 ==== init
399 ==== init
400 ==== qnew -U
400 ==== qnew -U
401 # HG changeset patch
401 # HG changeset patch
402 # User test
402 # Parent
403 # Parent
403 # User test
404
404
405 0: [mq]: 1.patch - test
405 0: [mq]: 1.patch - test
406 ==== qref
406 ==== qref
407 adding 1
407 adding 1
408 # HG changeset patch
408 # HG changeset patch
409 # User test
409 # Parent
410 # Parent
410 # User test
411
411
412 diff -r ... 1
412 diff -r ... 1
413 --- /dev/null
413 --- /dev/null
414 +++ b/1
414 +++ b/1
415 @@ -0,0 +1,1 @@
415 @@ -0,0 +1,1 @@
416 +1
416 +1
417 0: [mq]: 1.patch - test
417 0: [mq]: 1.patch - test
418 ==== qref -u
418 ==== qref -u
419 # HG changeset patch
419 # HG changeset patch
420 # User mary
420 # Parent
421 # Parent
421 # User mary
422
422
423 diff -r ... 1
423 diff -r ... 1
424 --- /dev/null
424 --- /dev/null
425 +++ b/1
425 +++ b/1
426 @@ -0,0 +1,1 @@
426 @@ -0,0 +1,1 @@
427 +1
427 +1
428 0: [mq]: 1.patch - mary
428 0: [mq]: 1.patch - mary
429 ==== qnew
429 ==== qnew
430 adding 2
430 adding 2
431 # HG changeset patch
431 # HG changeset patch
432 # Parent
432 # Parent
433
433
434 diff -r ... 2
434 diff -r ... 2
435 --- /dev/null
435 --- /dev/null
436 +++ b/2
436 +++ b/2
437 @@ -0,0 +1,1 @@
437 @@ -0,0 +1,1 @@
438 +2
438 +2
439 1: [mq]: 2.patch - test
439 1: [mq]: 2.patch - test
440 0: [mq]: 1.patch - mary
440 0: [mq]: 1.patch - mary
441 ==== qref -u
441 ==== qref -u
442 # HG changeset patch
442 # HG changeset patch
443 # User jane
443 # User jane
444 # Parent
444 # Parent
445
445
446 diff -r ... 2
446 diff -r ... 2
447 --- /dev/null
447 --- /dev/null
448 +++ b/2
448 +++ b/2
449 @@ -0,0 +1,1 @@
449 @@ -0,0 +1,1 @@
450 +2
450 +2
451 1: [mq]: 2.patch - jane
451 1: [mq]: 2.patch - jane
452 0: [mq]: 1.patch - mary
452 0: [mq]: 1.patch - mary
453 ==== qnew -U -m
453 ==== qnew -U -m
454 # HG changeset patch
454 # HG changeset patch
455 # User test
455 # Parent
456 # Parent
456 # User test
457 Three
457 Three
458
458
459 2: Three - test
459 2: Three - test
460 1: [mq]: 2.patch - jane
460 1: [mq]: 2.patch - jane
461 0: [mq]: 1.patch - mary
461 0: [mq]: 1.patch - mary
462 ==== qref
462 ==== qref
463 adding 3
463 adding 3
464 # HG changeset patch
464 # HG changeset patch
465 # User test
465 # Parent
466 # Parent
466 # User test
467 Three
467 Three
468
468
469 diff -r ... 3
469 diff -r ... 3
470 --- /dev/null
470 --- /dev/null
471 +++ b/3
471 +++ b/3
472 @@ -0,0 +1,1 @@
472 @@ -0,0 +1,1 @@
473 +3
473 +3
474 2: Three - test
474 2: Three - test
475 1: [mq]: 2.patch - jane
475 1: [mq]: 2.patch - jane
476 0: [mq]: 1.patch - mary
476 0: [mq]: 1.patch - mary
477 ==== qref -m
477 ==== qref -m
478 # HG changeset patch
478 # HG changeset patch
479 # User test
479 # Parent
480 # Parent
480 # User test
481 Drei
481 Drei
482
482
483 diff -r ... 3
483 diff -r ... 3
484 --- /dev/null
484 --- /dev/null
485 +++ b/3
485 +++ b/3
486 @@ -0,0 +1,1 @@
486 @@ -0,0 +1,1 @@
487 +3
487 +3
488 2: Drei - test
488 2: Drei - test
489 1: [mq]: 2.patch - jane
489 1: [mq]: 2.patch - jane
490 0: [mq]: 1.patch - mary
490 0: [mq]: 1.patch - mary
491 ==== qref -u
491 ==== qref -u
492 # HG changeset patch
492 # HG changeset patch
493 # User mary
493 # Parent
494 # Parent
494 # User mary
495 Drei
495 Drei
496
496
497 diff -r ... 3
497 diff -r ... 3
498 --- /dev/null
498 --- /dev/null
499 +++ b/3
499 +++ b/3
500 @@ -0,0 +1,1 @@
500 @@ -0,0 +1,1 @@
501 +3
501 +3
502 2: Drei - mary
502 2: Drei - mary
503 1: [mq]: 2.patch - jane
503 1: [mq]: 2.patch - jane
504 0: [mq]: 1.patch - mary
504 0: [mq]: 1.patch - mary
505 ==== qref -u -m
505 ==== qref -u -m
506 # HG changeset patch
506 # HG changeset patch
507 # User maria
507 # Parent
508 # Parent
508 # User maria
509 Three (again)
509 Three (again)
510
510
511 diff -r ... 3
511 diff -r ... 3
512 --- /dev/null
512 --- /dev/null
513 +++ b/3
513 +++ b/3
514 @@ -0,0 +1,1 @@
514 @@ -0,0 +1,1 @@
515 +3
515 +3
516 2: Three (again) - maria
516 2: Three (again) - maria
517 1: [mq]: 2.patch - jane
517 1: [mq]: 2.patch - jane
518 0: [mq]: 1.patch - mary
518 0: [mq]: 1.patch - mary
519 ==== qnew -m
519 ==== qnew -m
520 adding 4of
520 adding 4of
521 # HG changeset patch
521 # HG changeset patch
522 # Parent
522 # Parent
523 Four
523 Four
524
524
525 diff -r ... 4of
525 diff -r ... 4of
526 --- /dev/null
526 --- /dev/null
527 +++ b/4of
527 +++ b/4of
528 @@ -0,0 +1,1 @@
528 @@ -0,0 +1,1 @@
529 +4 t
529 +4 t
530 3: Four - test
530 3: Four - test
531 2: Three (again) - maria
531 2: Three (again) - maria
532 1: [mq]: 2.patch - jane
532 1: [mq]: 2.patch - jane
533 0: [mq]: 1.patch - mary
533 0: [mq]: 1.patch - mary
534 ==== qref -u
534 ==== qref -u
535 # HG changeset patch
535 # HG changeset patch
536 # User jane
536 # User jane
537 # Parent
537 # Parent
538 Four
538 Four
539
539
540 diff -r ... 4of
540 diff -r ... 4of
541 --- /dev/null
541 --- /dev/null
542 +++ b/4of
542 +++ b/4of
543 @@ -0,0 +1,1 @@
543 @@ -0,0 +1,1 @@
544 +4 t
544 +4 t
545 3: Four - jane
545 3: Four - jane
546 2: Three (again) - maria
546 2: Three (again) - maria
547 1: [mq]: 2.patch - jane
547 1: [mq]: 2.patch - jane
548 0: [mq]: 1.patch - mary
548 0: [mq]: 1.patch - mary
549 ==== qnew with HG header
549 ==== qnew with HG header
550 popping 5.patch
550 popping 5.patch
551 now at: 4.patch
551 now at: 4.patch
552 now at: 5.patch
552 now at: 5.patch
553 # HG changeset patch
553 # HG changeset patch
554 # User johndoe
554 # User johndoe
555 4: imported patch 5.patch - johndoe
555 4: imported patch 5.patch - johndoe
556 3: Four - jane
556 3: Four - jane
557 2: Three (again) - maria
557 2: Three (again) - maria
558 1: [mq]: 2.patch - jane
558 1: [mq]: 2.patch - jane
559 0: [mq]: 1.patch - mary
559 0: [mq]: 1.patch - mary
560 ==== hg qref
560 ==== hg qref
561 adding 5
561 adding 5
562 # HG changeset patch
562 # HG changeset patch
563 # Parent
563 # Parent
564 # User johndoe
564 # User johndoe
565
565
566 diff -r ... 5
566 diff -r ... 5
567 --- /dev/null
567 --- /dev/null
568 +++ b/5
568 +++ b/5
569 @@ -0,0 +1,1 @@
569 @@ -0,0 +1,1 @@
570 +5
570 +5
571 4: [mq]: 5.patch - johndoe
571 4: [mq]: 5.patch - johndoe
572 3: Four - jane
572 3: Four - jane
573 2: Three (again) - maria
573 2: Three (again) - maria
574 1: [mq]: 2.patch - jane
574 1: [mq]: 2.patch - jane
575 0: [mq]: 1.patch - mary
575 0: [mq]: 1.patch - mary
576 ==== hg qref -U
576 ==== hg qref -U
577 # HG changeset patch
577 # HG changeset patch
578 # Parent
578 # Parent
579 # User test
579 # User test
580
580
581 diff -r ... 5
581 diff -r ... 5
582 --- /dev/null
582 --- /dev/null
583 +++ b/5
583 +++ b/5
584 @@ -0,0 +1,1 @@
584 @@ -0,0 +1,1 @@
585 +5
585 +5
586 4: [mq]: 5.patch - test
586 4: [mq]: 5.patch - test
587 3: Four - jane
587 3: Four - jane
588 2: Three (again) - maria
588 2: Three (again) - maria
589 1: [mq]: 2.patch - jane
589 1: [mq]: 2.patch - jane
590 0: [mq]: 1.patch - mary
590 0: [mq]: 1.patch - mary
591 ==== hg qref -u
591 ==== hg qref -u
592 # HG changeset patch
592 # HG changeset patch
593 # Parent
593 # Parent
594 # User johndeere
594 # User johndeere
595
595
596 diff -r ... 5
596 diff -r ... 5
597 --- /dev/null
597 --- /dev/null
598 +++ b/5
598 +++ b/5
599 @@ -0,0 +1,1 @@
599 @@ -0,0 +1,1 @@
600 +5
600 +5
601 4: [mq]: 5.patch - johndeere
601 4: [mq]: 5.patch - johndeere
602 3: Four - jane
602 3: Four - jane
603 2: Three (again) - maria
603 2: Three (again) - maria
604 1: [mq]: 2.patch - jane
604 1: [mq]: 2.patch - jane
605 0: [mq]: 1.patch - mary
605 0: [mq]: 1.patch - mary
606 ==== qnew with plain header
606 ==== qnew with plain header
607 popping 6.patch
607 popping 6.patch
608 now at: 5.patch
608 now at: 5.patch
609 now at: 6.patch
609 now at: 6.patch
610 From: test
610 From: test
611
611
612 5: imported patch 6.patch - test
612 5: imported patch 6.patch - test
613 4: [mq]: 5.patch - johndeere
613 4: [mq]: 5.patch - johndeere
614 3: Four - jane
614 3: Four - jane
615 2: Three (again) - maria
615 2: Three (again) - maria
616 1: [mq]: 2.patch - jane
616 1: [mq]: 2.patch - jane
617 0: [mq]: 1.patch - mary
617 0: [mq]: 1.patch - mary
618 ==== hg qref
618 ==== hg qref
619 adding 6
619 adding 6
620 From: test
620 From: test
621
621
622 diff -r ... 6
622 diff -r ... 6
623 --- /dev/null
623 --- /dev/null
624 +++ b/6
624 +++ b/6
625 @@ -0,0 +1,1 @@
625 @@ -0,0 +1,1 @@
626 +6
626 +6
627 5: [mq]: 6.patch - test
627 5: [mq]: 6.patch - test
628 4: [mq]: 5.patch - johndeere
628 4: [mq]: 5.patch - johndeere
629 3: Four - jane
629 3: Four - jane
630 2: Three (again) - maria
630 2: Three (again) - maria
631 1: [mq]: 2.patch - jane
631 1: [mq]: 2.patch - jane
632 0: [mq]: 1.patch - mary
632 0: [mq]: 1.patch - mary
633 ==== hg qref -U
633 ==== hg qref -U
634 From: test
634 From: test
635
635
636 diff -r ... 6
636 diff -r ... 6
637 --- /dev/null
637 --- /dev/null
638 +++ b/6
638 +++ b/6
639 @@ -0,0 +1,1 @@
639 @@ -0,0 +1,1 @@
640 +6
640 +6
641 5: [mq]: 6.patch - test
641 5: [mq]: 6.patch - test
642 4: [mq]: 5.patch - johndeere
642 4: [mq]: 5.patch - johndeere
643 3: Four - jane
643 3: Four - jane
644 2: Three (again) - maria
644 2: Three (again) - maria
645 1: [mq]: 2.patch - jane
645 1: [mq]: 2.patch - jane
646 0: [mq]: 1.patch - mary
646 0: [mq]: 1.patch - mary
647 ==== hg qref -u
647 ==== hg qref -u
648 From: johndeere
648 From: johndeere
649
649
650 diff -r ... 6
650 diff -r ... 6
651 --- /dev/null
651 --- /dev/null
652 +++ b/6
652 +++ b/6
653 @@ -0,0 +1,1 @@
653 @@ -0,0 +1,1 @@
654 +6
654 +6
655 5: [mq]: 6.patch - johndeere
655 5: [mq]: 6.patch - johndeere
656 4: [mq]: 5.patch - johndeere
656 4: [mq]: 5.patch - johndeere
657 3: Four - jane
657 3: Four - jane
658 2: Three (again) - maria
658 2: Three (again) - maria
659 1: [mq]: 2.patch - jane
659 1: [mq]: 2.patch - jane
660 0: [mq]: 1.patch - mary
660 0: [mq]: 1.patch - mary
661 ==== qpop -a / qpush -a
661 ==== qpop -a / qpush -a
662 popping 6.patch
662 popping 6.patch
663 popping 5.patch
663 popping 5.patch
664 popping 4.patch
664 popping 4.patch
665 popping 3.patch
665 popping 3.patch
666 popping 2.patch
666 popping 2.patch
667 popping 1.patch
667 popping 1.patch
668 patch queue now empty
668 patch queue now empty
669 applying 1.patch
669 applying 1.patch
670 applying 2.patch
670 applying 2.patch
671 applying 3.patch
671 applying 3.patch
672 applying 4.patch
672 applying 4.patch
673 applying 5.patch
673 applying 5.patch
674 applying 6.patch
674 applying 6.patch
675 now at: 6.patch
675 now at: 6.patch
676 5: imported patch 6.patch - johndeere
676 5: imported patch 6.patch - johndeere
677 4: imported patch 5.patch - johndeere
677 4: imported patch 5.patch - johndeere
678 3: Four - jane
678 3: Four - jane
679 2: Three (again) - maria
679 2: Three (again) - maria
680 1: imported patch 2.patch - jane
680 1: imported patch 2.patch - jane
681 0: imported patch 1.patch - mary
681 0: imported patch 1.patch - mary
682 $ rm -r sandbox
682 $ rm -r sandbox
683 $ runtest
683 $ runtest
684 ==== init
684 ==== init
685 ==== qnew -U
685 ==== qnew -U
686 # HG changeset patch
686 # HG changeset patch
687 # User test
687 # Parent
688 # Parent
688 # User test
689
689
690 0: [mq]: 1.patch - test
690 0: [mq]: 1.patch - test
691 ==== qref
691 ==== qref
692 adding 1
692 adding 1
693 # HG changeset patch
693 # HG changeset patch
694 # User test
694 # Parent
695 # Parent
695 # User test
696
696
697 diff -r ... 1
697 diff -r ... 1
698 --- /dev/null
698 --- /dev/null
699 +++ b/1
699 +++ b/1
700 @@ -0,0 +1,1 @@
700 @@ -0,0 +1,1 @@
701 +1
701 +1
702 0: [mq]: 1.patch - test
702 0: [mq]: 1.patch - test
703 ==== qref -u
703 ==== qref -u
704 # HG changeset patch
704 # HG changeset patch
705 # User mary
705 # Parent
706 # Parent
706 # User mary
707
707
708 diff -r ... 1
708 diff -r ... 1
709 --- /dev/null
709 --- /dev/null
710 +++ b/1
710 +++ b/1
711 @@ -0,0 +1,1 @@
711 @@ -0,0 +1,1 @@
712 +1
712 +1
713 0: [mq]: 1.patch - mary
713 0: [mq]: 1.patch - mary
714 ==== qnew
714 ==== qnew
715 adding 2
715 adding 2
716 # HG changeset patch
716 # HG changeset patch
717 # Parent
717 # Parent
718
718
719 diff -r ... 2
719 diff -r ... 2
720 --- /dev/null
720 --- /dev/null
721 +++ b/2
721 +++ b/2
722 @@ -0,0 +1,1 @@
722 @@ -0,0 +1,1 @@
723 +2
723 +2
724 1: [mq]: 2.patch - test
724 1: [mq]: 2.patch - test
725 0: [mq]: 1.patch - mary
725 0: [mq]: 1.patch - mary
726 ==== qref -u
726 ==== qref -u
727 # HG changeset patch
727 # HG changeset patch
728 # User jane
728 # User jane
729 # Parent
729 # Parent
730
730
731 diff -r ... 2
731 diff -r ... 2
732 --- /dev/null
732 --- /dev/null
733 +++ b/2
733 +++ b/2
734 @@ -0,0 +1,1 @@
734 @@ -0,0 +1,1 @@
735 +2
735 +2
736 1: [mq]: 2.patch - jane
736 1: [mq]: 2.patch - jane
737 0: [mq]: 1.patch - mary
737 0: [mq]: 1.patch - mary
738 ==== qnew -U -m
738 ==== qnew -U -m
739 # HG changeset patch
739 # HG changeset patch
740 # User test
740 # Parent
741 # Parent
741 # User test
742 Three
742 Three
743
743
744 2: Three - test
744 2: Three - test
745 1: [mq]: 2.patch - jane
745 1: [mq]: 2.patch - jane
746 0: [mq]: 1.patch - mary
746 0: [mq]: 1.patch - mary
747 ==== qref
747 ==== qref
748 adding 3
748 adding 3
749 # HG changeset patch
749 # HG changeset patch
750 # User test
750 # Parent
751 # Parent
751 # User test
752 Three
752 Three
753
753
754 diff -r ... 3
754 diff -r ... 3
755 --- /dev/null
755 --- /dev/null
756 +++ b/3
756 +++ b/3
757 @@ -0,0 +1,1 @@
757 @@ -0,0 +1,1 @@
758 +3
758 +3
759 2: Three - test
759 2: Three - test
760 1: [mq]: 2.patch - jane
760 1: [mq]: 2.patch - jane
761 0: [mq]: 1.patch - mary
761 0: [mq]: 1.patch - mary
762 ==== qref -m
762 ==== qref -m
763 # HG changeset patch
763 # HG changeset patch
764 # User test
764 # Parent
765 # Parent
765 # User test
766 Drei
766 Drei
767
767
768 diff -r ... 3
768 diff -r ... 3
769 --- /dev/null
769 --- /dev/null
770 +++ b/3
770 +++ b/3
771 @@ -0,0 +1,1 @@
771 @@ -0,0 +1,1 @@
772 +3
772 +3
773 2: Drei - test
773 2: Drei - test
774 1: [mq]: 2.patch - jane
774 1: [mq]: 2.patch - jane
775 0: [mq]: 1.patch - mary
775 0: [mq]: 1.patch - mary
776 ==== qref -u
776 ==== qref -u
777 # HG changeset patch
777 # HG changeset patch
778 # User mary
778 # Parent
779 # Parent
779 # User mary
780 Drei
780 Drei
781
781
782 diff -r ... 3
782 diff -r ... 3
783 --- /dev/null
783 --- /dev/null
784 +++ b/3
784 +++ b/3
785 @@ -0,0 +1,1 @@
785 @@ -0,0 +1,1 @@
786 +3
786 +3
787 2: Drei - mary
787 2: Drei - mary
788 1: [mq]: 2.patch - jane
788 1: [mq]: 2.patch - jane
789 0: [mq]: 1.patch - mary
789 0: [mq]: 1.patch - mary
790 ==== qref -u -m
790 ==== qref -u -m
791 # HG changeset patch
791 # HG changeset patch
792 # User maria
792 # Parent
793 # Parent
793 # User maria
794 Three (again)
794 Three (again)
795
795
796 diff -r ... 3
796 diff -r ... 3
797 --- /dev/null
797 --- /dev/null
798 +++ b/3
798 +++ b/3
799 @@ -0,0 +1,1 @@
799 @@ -0,0 +1,1 @@
800 +3
800 +3
801 2: Three (again) - maria
801 2: Three (again) - maria
802 1: [mq]: 2.patch - jane
802 1: [mq]: 2.patch - jane
803 0: [mq]: 1.patch - mary
803 0: [mq]: 1.patch - mary
804 ==== qnew -m
804 ==== qnew -m
805 adding 4of
805 adding 4of
806 # HG changeset patch
806 # HG changeset patch
807 # Parent
807 # Parent
808 Four
808 Four
809
809
810 diff -r ... 4of
810 diff -r ... 4of
811 --- /dev/null
811 --- /dev/null
812 +++ b/4of
812 +++ b/4of
813 @@ -0,0 +1,1 @@
813 @@ -0,0 +1,1 @@
814 +4 t
814 +4 t
815 3: Four - test
815 3: Four - test
816 2: Three (again) - maria
816 2: Three (again) - maria
817 1: [mq]: 2.patch - jane
817 1: [mq]: 2.patch - jane
818 0: [mq]: 1.patch - mary
818 0: [mq]: 1.patch - mary
819 ==== qref -u
819 ==== qref -u
820 # HG changeset patch
820 # HG changeset patch
821 # User jane
821 # User jane
822 # Parent
822 # Parent
823 Four
823 Four
824
824
825 diff -r ... 4of
825 diff -r ... 4of
826 --- /dev/null
826 --- /dev/null
827 +++ b/4of
827 +++ b/4of
828 @@ -0,0 +1,1 @@
828 @@ -0,0 +1,1 @@
829 +4 t
829 +4 t
830 3: Four - jane
830 3: Four - jane
831 2: Three (again) - maria
831 2: Three (again) - maria
832 1: [mq]: 2.patch - jane
832 1: [mq]: 2.patch - jane
833 0: [mq]: 1.patch - mary
833 0: [mq]: 1.patch - mary
834 ==== qnew with HG header
834 ==== qnew with HG header
835 popping 5.patch
835 popping 5.patch
836 now at: 4.patch
836 now at: 4.patch
837 now at: 5.patch
837 now at: 5.patch
838 # HG changeset patch
838 # HG changeset patch
839 # User johndoe
839 # User johndoe
840 4: imported patch 5.patch - johndoe
840 4: imported patch 5.patch - johndoe
841 3: Four - jane
841 3: Four - jane
842 2: Three (again) - maria
842 2: Three (again) - maria
843 1: [mq]: 2.patch - jane
843 1: [mq]: 2.patch - jane
844 0: [mq]: 1.patch - mary
844 0: [mq]: 1.patch - mary
845 ==== hg qref
845 ==== hg qref
846 adding 5
846 adding 5
847 # HG changeset patch
847 # HG changeset patch
848 # Parent
848 # Parent
849 # User johndoe
849 # User johndoe
850
850
851 diff -r ... 5
851 diff -r ... 5
852 --- /dev/null
852 --- /dev/null
853 +++ b/5
853 +++ b/5
854 @@ -0,0 +1,1 @@
854 @@ -0,0 +1,1 @@
855 +5
855 +5
856 4: [mq]: 5.patch - johndoe
856 4: [mq]: 5.patch - johndoe
857 3: Four - jane
857 3: Four - jane
858 2: Three (again) - maria
858 2: Three (again) - maria
859 1: [mq]: 2.patch - jane
859 1: [mq]: 2.patch - jane
860 0: [mq]: 1.patch - mary
860 0: [mq]: 1.patch - mary
861 ==== hg qref -U
861 ==== hg qref -U
862 # HG changeset patch
862 # HG changeset patch
863 # Parent
863 # Parent
864 # User test
864 # User test
865
865
866 diff -r ... 5
866 diff -r ... 5
867 --- /dev/null
867 --- /dev/null
868 +++ b/5
868 +++ b/5
869 @@ -0,0 +1,1 @@
869 @@ -0,0 +1,1 @@
870 +5
870 +5
871 4: [mq]: 5.patch - test
871 4: [mq]: 5.patch - test
872 3: Four - jane
872 3: Four - jane
873 2: Three (again) - maria
873 2: Three (again) - maria
874 1: [mq]: 2.patch - jane
874 1: [mq]: 2.patch - jane
875 0: [mq]: 1.patch - mary
875 0: [mq]: 1.patch - mary
876 ==== hg qref -u
876 ==== hg qref -u
877 # HG changeset patch
877 # HG changeset patch
878 # Parent
878 # Parent
879 # User johndeere
879 # User johndeere
880
880
881 diff -r ... 5
881 diff -r ... 5
882 --- /dev/null
882 --- /dev/null
883 +++ b/5
883 +++ b/5
884 @@ -0,0 +1,1 @@
884 @@ -0,0 +1,1 @@
885 +5
885 +5
886 4: [mq]: 5.patch - johndeere
886 4: [mq]: 5.patch - johndeere
887 3: Four - jane
887 3: Four - jane
888 2: Three (again) - maria
888 2: Three (again) - maria
889 1: [mq]: 2.patch - jane
889 1: [mq]: 2.patch - jane
890 0: [mq]: 1.patch - mary
890 0: [mq]: 1.patch - mary
891 ==== qnew with plain header
891 ==== qnew with plain header
892 popping 6.patch
892 popping 6.patch
893 now at: 5.patch
893 now at: 5.patch
894 now at: 6.patch
894 now at: 6.patch
895 From: test
895 From: test
896
896
897 5: imported patch 6.patch - test
897 5: imported patch 6.patch - test
898 4: [mq]: 5.patch - johndeere
898 4: [mq]: 5.patch - johndeere
899 3: Four - jane
899 3: Four - jane
900 2: Three (again) - maria
900 2: Three (again) - maria
901 1: [mq]: 2.patch - jane
901 1: [mq]: 2.patch - jane
902 0: [mq]: 1.patch - mary
902 0: [mq]: 1.patch - mary
903 ==== hg qref
903 ==== hg qref
904 adding 6
904 adding 6
905 From: test
905 From: test
906
906
907 diff -r ... 6
907 diff -r ... 6
908 --- /dev/null
908 --- /dev/null
909 +++ b/6
909 +++ b/6
910 @@ -0,0 +1,1 @@
910 @@ -0,0 +1,1 @@
911 +6
911 +6
912 5: [mq]: 6.patch - test
912 5: [mq]: 6.patch - test
913 4: [mq]: 5.patch - johndeere
913 4: [mq]: 5.patch - johndeere
914 3: Four - jane
914 3: Four - jane
915 2: Three (again) - maria
915 2: Three (again) - maria
916 1: [mq]: 2.patch - jane
916 1: [mq]: 2.patch - jane
917 0: [mq]: 1.patch - mary
917 0: [mq]: 1.patch - mary
918 ==== hg qref -U
918 ==== hg qref -U
919 From: test
919 From: test
920
920
921 diff -r ... 6
921 diff -r ... 6
922 --- /dev/null
922 --- /dev/null
923 +++ b/6
923 +++ b/6
924 @@ -0,0 +1,1 @@
924 @@ -0,0 +1,1 @@
925 +6
925 +6
926 5: [mq]: 6.patch - test
926 5: [mq]: 6.patch - test
927 4: [mq]: 5.patch - johndeere
927 4: [mq]: 5.patch - johndeere
928 3: Four - jane
928 3: Four - jane
929 2: Three (again) - maria
929 2: Three (again) - maria
930 1: [mq]: 2.patch - jane
930 1: [mq]: 2.patch - jane
931 0: [mq]: 1.patch - mary
931 0: [mq]: 1.patch - mary
932 ==== hg qref -u
932 ==== hg qref -u
933 From: johndeere
933 From: johndeere
934
934
935 diff -r ... 6
935 diff -r ... 6
936 --- /dev/null
936 --- /dev/null
937 +++ b/6
937 +++ b/6
938 @@ -0,0 +1,1 @@
938 @@ -0,0 +1,1 @@
939 +6
939 +6
940 5: [mq]: 6.patch - johndeere
940 5: [mq]: 6.patch - johndeere
941 4: [mq]: 5.patch - johndeere
941 4: [mq]: 5.patch - johndeere
942 3: Four - jane
942 3: Four - jane
943 2: Three (again) - maria
943 2: Three (again) - maria
944 1: [mq]: 2.patch - jane
944 1: [mq]: 2.patch - jane
945 0: [mq]: 1.patch - mary
945 0: [mq]: 1.patch - mary
946 ==== qpop -a / qpush -a
946 ==== qpop -a / qpush -a
947 popping 6.patch
947 popping 6.patch
948 popping 5.patch
948 popping 5.patch
949 popping 4.patch
949 popping 4.patch
950 popping 3.patch
950 popping 3.patch
951 popping 2.patch
951 popping 2.patch
952 popping 1.patch
952 popping 1.patch
953 patch queue now empty
953 patch queue now empty
954 applying 1.patch
954 applying 1.patch
955 applying 2.patch
955 applying 2.patch
956 applying 3.patch
956 applying 3.patch
957 applying 4.patch
957 applying 4.patch
958 applying 5.patch
958 applying 5.patch
959 applying 6.patch
959 applying 6.patch
960 now at: 6.patch
960 now at: 6.patch
961 5: imported patch 6.patch - johndeere
961 5: imported patch 6.patch - johndeere
962 4: imported patch 5.patch - johndeere
962 4: imported patch 5.patch - johndeere
963 3: Four - jane
963 3: Four - jane
964 2: Three (again) - maria
964 2: Three (again) - maria
965 1: imported patch 2.patch - jane
965 1: imported patch 2.patch - jane
966 0: imported patch 1.patch - mary
966 0: imported patch 1.patch - mary
967
967
968 $ cd ..
968 $ cd ..
@@ -1,175 +1,175 b''
1 Setup extension:
1 Setup extension:
2
2
3 $ echo "[extensions]" >> $HGRCPATH
3 $ echo "[extensions]" >> $HGRCPATH
4 $ echo "mq =" >> $HGRCPATH
4 $ echo "mq =" >> $HGRCPATH
5 $ echo "[mq]" >> $HGRCPATH
5 $ echo "[mq]" >> $HGRCPATH
6 $ echo "git = keep" >> $HGRCPATH
6 $ echo "git = keep" >> $HGRCPATH
7
7
8 Test merge with mq changeset as the second parent:
8 Test merge with mq changeset as the second parent:
9
9
10 $ hg init m
10 $ hg init m
11 $ cd m
11 $ cd m
12 $ touch a b c
12 $ touch a b c
13 $ hg add a
13 $ hg add a
14 $ hg commit -m a
14 $ hg commit -m a
15 $ hg add b
15 $ hg add b
16 $ hg qnew -d "0 0" b
16 $ hg qnew -d "0 0" b
17 $ hg update 0
17 $ hg update 0
18 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
18 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
19 $ hg add c
19 $ hg add c
20 $ hg commit -m c
20 $ hg commit -m c
21 created new head
21 created new head
22 $ hg merge
22 $ hg merge
23 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
23 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
24 (branch merge, don't forget to commit)
24 (branch merge, don't forget to commit)
25 $ hg commit -m merge
25 $ hg commit -m merge
26 abort: cannot commit over an applied mq patch
26 abort: cannot commit over an applied mq patch
27 [255]
27 [255]
28 $ cd ..
28 $ cd ..
29
29
30 Issue529: mq aborts when merging patch deleting files
30 Issue529: mq aborts when merging patch deleting files
31
31
32 $ checkundo()
32 $ checkundo()
33 > {
33 > {
34 > if [ -f .hg/store/undo ]; then
34 > if [ -f .hg/store/undo ]; then
35 > echo ".hg/store/undo still exists"
35 > echo ".hg/store/undo still exists"
36 > fi
36 > fi
37 > }
37 > }
38
38
39 Commit two dummy files in "init" changeset:
39 Commit two dummy files in "init" changeset:
40
40
41 $ hg init t
41 $ hg init t
42 $ cd t
42 $ cd t
43 $ echo a > a
43 $ echo a > a
44 $ echo b > b
44 $ echo b > b
45 $ hg ci -Am init
45 $ hg ci -Am init
46 adding a
46 adding a
47 adding b
47 adding b
48 $ hg tag -l init
48 $ hg tag -l init
49
49
50 Create a patch removing a:
50 Create a patch removing a:
51
51
52 $ hg qnew rm_a
52 $ hg qnew rm_a
53 $ hg rm a
53 $ hg rm a
54 $ hg qrefresh -m "rm a"
54 $ hg qrefresh -m "rm a"
55
55
56 Save the patch queue so we can merge it later:
56 Save the patch queue so we can merge it later:
57
57
58 $ hg qsave -c -e
58 $ hg qsave -c -e
59 copy $TESTTMP/t/.hg/patches to $TESTTMP/t/.hg/patches.1 (glob)
59 copy $TESTTMP/t/.hg/patches to $TESTTMP/t/.hg/patches.1 (glob)
60 $ checkundo
60 $ checkundo
61
61
62 Update b and commit in an "update" changeset:
62 Update b and commit in an "update" changeset:
63
63
64 $ hg up -C init
64 $ hg up -C init
65 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
65 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
66 $ echo b >> b
66 $ echo b >> b
67 $ hg st
67 $ hg st
68 M b
68 M b
69 $ hg ci -m update
69 $ hg ci -m update
70 created new head
70 created new head
71
71
72 # Here, qpush used to abort with :
72 # Here, qpush used to abort with :
73 # The system cannot find the file specified => a
73 # The system cannot find the file specified => a
74 $ hg manifest
74 $ hg manifest
75 a
75 a
76 b
76 b
77
77
78 $ hg qpush -a -m
78 $ hg qpush -a -m
79 merging with queue at: $TESTTMP/t/.hg/patches.1 (glob)
79 merging with queue at: $TESTTMP/t/.hg/patches.1 (glob)
80 applying rm_a
80 applying rm_a
81 now at: rm_a
81 now at: rm_a
82
82
83 $ checkundo
83 $ checkundo
84 $ hg manifest
84 $ hg manifest
85 b
85 b
86
86
87 Ensure status is correct after merge:
87 Ensure status is correct after merge:
88
88
89 $ hg qpop -a
89 $ hg qpop -a
90 popping rm_a
90 popping rm_a
91 popping .hg.patches.merge.marker
91 popping .hg.patches.merge.marker
92 patch queue now empty
92 patch queue now empty
93
93
94 $ cd ..
94 $ cd ..
95
95
96 Classic MQ merge sequence *with an explicit named queue*:
96 Classic MQ merge sequence *with an explicit named queue*:
97
97
98 $ hg init t2
98 $ hg init t2
99 $ cd t2
99 $ cd t2
100 $ echo '[diff]' > .hg/hgrc
100 $ echo '[diff]' > .hg/hgrc
101 $ echo 'nodates = 1' >> .hg/hgrc
101 $ echo 'nodates = 1' >> .hg/hgrc
102 $ echo a > a
102 $ echo a > a
103 $ hg ci -Am init
103 $ hg ci -Am init
104 adding a
104 adding a
105 $ echo b > a
105 $ echo b > a
106 $ hg ci -m changea
106 $ hg ci -m changea
107 $ hg up -C 0
107 $ hg up -C 0
108 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
108 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
109 $ hg cp a aa
109 $ hg cp a aa
110 $ echo c >> a
110 $ echo c >> a
111 $ hg qnew --git -f -e patcha
111 $ hg qnew --git -f -e patcha
112 $ echo d >> a
112 $ echo d >> a
113 $ hg qnew -d '0 0' -f -e patcha2
113 $ hg qnew -d '0 0' -f -e patcha2
114
114
115 Create the reference queue:
115 Create the reference queue:
116
116
117 $ hg qsave -c -e -n refqueue
117 $ hg qsave -c -e -n refqueue
118 copy $TESTTMP/t2/.hg/patches to $TESTTMP/t2/.hg/refqueue (glob)
118 copy $TESTTMP/t2/.hg/patches to $TESTTMP/t2/.hg/refqueue (glob)
119 $ hg up -C 1
119 $ hg up -C 1
120 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
120 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
121
121
122 Merge:
122 Merge:
123
123
124 $ HGMERGE=internal:other hg qpush -a -m -n refqueue
124 $ HGMERGE=internal:other hg qpush -a -m -n refqueue
125 merging with queue at: $TESTTMP/t2/.hg/refqueue (glob)
125 merging with queue at: $TESTTMP/t2/.hg/refqueue (glob)
126 applying patcha
126 applying patcha
127 patching file a
127 patching file a
128 Hunk #1 succeeded at 2 with fuzz 1 (offset 0 lines).
128 Hunk #1 succeeded at 2 with fuzz 1 (offset 0 lines).
129 fuzz found when applying patch, stopping
129 fuzz found when applying patch, stopping
130 patch didn't work out, merging patcha
130 patch didn't work out, merging patcha
131 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
131 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
132 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
132 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
133 (branch merge, don't forget to commit)
133 (branch merge, don't forget to commit)
134 applying patcha2
134 applying patcha2
135 now at: patcha2
135 now at: patcha2
136
136
137 Check patcha is still a git patch:
137 Check patcha is still a git patch:
138
138
139 $ cat .hg/patches/patcha
139 $ cat .hg/patches/patcha
140 # HG changeset patch
140 # HG changeset patch
141 # Parent d3873e73d99ef67873dac33fbcc66268d5d2b6f4
141 # Parent d3873e73d99ef67873dac33fbcc66268d5d2b6f4
142
142
143 diff --git a/a b/a
143 diff --git a/a b/a
144 --- a/a
144 --- a/a
145 +++ b/a
145 +++ b/a
146 @@ -1,1 +1,2 @@
146 @@ -1,1 +1,2 @@
147 -b
147 -b
148 +a
148 +a
149 +c
149 +c
150 diff --git a/a b/aa
150 diff --git a/a b/aa
151 copy from a
151 copy from a
152 copy to aa
152 copy to aa
153 --- a/a
153 --- a/a
154 +++ b/aa
154 +++ b/aa
155 @@ -1,1 +1,1 @@
155 @@ -1,1 +1,1 @@
156 -b
156 -b
157 +a
157 +a
158
158
159 Check patcha2 is still a regular patch:
159 Check patcha2 is still a regular patch:
160
160
161 $ cat .hg/patches/patcha2
161 $ cat .hg/patches/patcha2
162 # HG changeset patch
162 # HG changeset patch
163 # Date 0 0
163 # Parent ???????????????????????????????????????? (glob)
164 # Parent ???????????????????????????????????????? (glob)
164 # Date 0 0
165
165
166 diff -r ???????????? -r ???????????? a (glob)
166 diff -r ???????????? -r ???????????? a (glob)
167 --- a/a
167 --- a/a
168 +++ b/a
168 +++ b/a
169 @@ -1,2 +1,3 @@
169 @@ -1,2 +1,3 @@
170 a
170 a
171 c
171 c
172 +d
172 +d
173
173
174 $ cd ..
174 $ cd ..
175
175
@@ -1,347 +1,347 b''
1
1
2 $ catpatch() {
2 $ catpatch() {
3 > cat $1 | sed -e "s/^\(# Parent \).*/\1/"
3 > cat $1 | sed -e "s/^\(# Parent \).*/\1/"
4 > }
4 > }
5 $ echo "[extensions]" >> $HGRCPATH
5 $ echo "[extensions]" >> $HGRCPATH
6 $ echo "mq=" >> $HGRCPATH
6 $ echo "mq=" >> $HGRCPATH
7 $ runtest() {
7 $ runtest() {
8 > hg init mq
8 > hg init mq
9 > cd mq
9 > cd mq
10 >
10 >
11 > echo a > a
11 > echo a > a
12 > hg ci -Ama
12 > hg ci -Ama
13 >
13 >
14 > echo '% qnew should refuse bad patch names'
14 > echo '% qnew should refuse bad patch names'
15 > hg qnew series
15 > hg qnew series
16 > hg qnew status
16 > hg qnew status
17 > hg qnew guards
17 > hg qnew guards
18 > hg qnew .
18 > hg qnew .
19 > hg qnew ..
19 > hg qnew ..
20 > hg qnew .hgignore
20 > hg qnew .hgignore
21 > hg qnew .mqfoo
21 > hg qnew .mqfoo
22 > hg qnew 'foo#bar'
22 > hg qnew 'foo#bar'
23 > hg qnew 'foo:bar'
23 > hg qnew 'foo:bar'
24 >
24 >
25 > hg qinit -c
25 > hg qinit -c
26 >
26 >
27 > echo '% qnew with name containing slash'
27 > echo '% qnew with name containing slash'
28 > hg qnew foo/
28 > hg qnew foo/
29 > hg qnew foo/bar.patch
29 > hg qnew foo/bar.patch
30 > hg qnew foo
30 > hg qnew foo
31 > hg qseries
31 > hg qseries
32 > hg qpop
32 > hg qpop
33 > hg qdelete foo/bar.patch
33 > hg qdelete foo/bar.patch
34 >
34 >
35 > echo '% qnew with uncommitted changes'
35 > echo '% qnew with uncommitted changes'
36 > echo a > somefile
36 > echo a > somefile
37 > hg add somefile
37 > hg add somefile
38 > hg qnew uncommitted.patch
38 > hg qnew uncommitted.patch
39 > hg st
39 > hg st
40 > hg qseries
40 > hg qseries
41 >
41 >
42 > echo '% qnew implies add'
42 > echo '% qnew implies add'
43 > hg -R .hg/patches st
43 > hg -R .hg/patches st
44 >
44 >
45 > echo '% qnew missing'
45 > echo '% qnew missing'
46 > hg qnew missing.patch missing
46 > hg qnew missing.patch missing
47 >
47 >
48 > echo '% qnew -m'
48 > echo '% qnew -m'
49 > hg qnew -m 'foo bar' mtest.patch
49 > hg qnew -m 'foo bar' mtest.patch
50 > catpatch .hg/patches/mtest.patch
50 > catpatch .hg/patches/mtest.patch
51 >
51 >
52 > echo '% qnew twice'
52 > echo '% qnew twice'
53 > hg qnew first.patch
53 > hg qnew first.patch
54 > hg qnew first.patch
54 > hg qnew first.patch
55 >
55 >
56 > touch ../first.patch
56 > touch ../first.patch
57 > hg qimport ../first.patch
57 > hg qimport ../first.patch
58 >
58 >
59 > echo '% qnew -f from a subdirectory'
59 > echo '% qnew -f from a subdirectory'
60 > hg qpop -a
60 > hg qpop -a
61 > mkdir d
61 > mkdir d
62 > cd d
62 > cd d
63 > echo b > b
63 > echo b > b
64 > hg ci -Am t
64 > hg ci -Am t
65 > echo b >> b
65 > echo b >> b
66 > hg st
66 > hg st
67 > hg qnew -g -f p
67 > hg qnew -g -f p
68 > catpatch ../.hg/patches/p
68 > catpatch ../.hg/patches/p
69 >
69 >
70 > echo '% qnew -u with no username configured'
70 > echo '% qnew -u with no username configured'
71 > HGUSER= hg qnew -u blue red
71 > HGUSER= hg qnew -u blue red
72 > catpatch ../.hg/patches/red
72 > catpatch ../.hg/patches/red
73 >
73 >
74 > echo '% qnew -e -u with no username configured'
74 > echo '% qnew -e -u with no username configured'
75 > HGUSER= hg qnew -e -u chartreuse fucsia
75 > HGUSER= hg qnew -e -u chartreuse fucsia
76 > catpatch ../.hg/patches/fucsia
76 > catpatch ../.hg/patches/fucsia
77 >
77 >
78 > echo '% fail when trying to import a merge'
78 > echo '% fail when trying to import a merge'
79 > hg init merge
79 > hg init merge
80 > cd merge
80 > cd merge
81 > touch a
81 > touch a
82 > hg ci -Am null
82 > hg ci -Am null
83 > echo a >> a
83 > echo a >> a
84 > hg ci -m a
84 > hg ci -m a
85 > hg up -r 0
85 > hg up -r 0
86 > echo b >> a
86 > echo b >> a
87 > hg ci -m b
87 > hg ci -m b
88 > hg merge -f 1
88 > hg merge -f 1
89 > hg resolve --mark a
89 > hg resolve --mark a
90 > hg qnew -f merge
90 > hg qnew -f merge
91 >
91 >
92 > cd ../../..
92 > cd ../../..
93 > rm -r mq
93 > rm -r mq
94 > }
94 > }
95
95
96 plain headers
96 plain headers
97
97
98 $ echo "[mq]" >> $HGRCPATH
98 $ echo "[mq]" >> $HGRCPATH
99 $ echo "plain=true" >> $HGRCPATH
99 $ echo "plain=true" >> $HGRCPATH
100 $ mkdir sandbox
100 $ mkdir sandbox
101 $ (cd sandbox ; runtest)
101 $ (cd sandbox ; runtest)
102 adding a
102 adding a
103 % qnew should refuse bad patch names
103 % qnew should refuse bad patch names
104 abort: "series" cannot be used as the name of a patch
104 abort: "series" cannot be used as the name of a patch
105 abort: "status" cannot be used as the name of a patch
105 abort: "status" cannot be used as the name of a patch
106 abort: "guards" cannot be used as the name of a patch
106 abort: "guards" cannot be used as the name of a patch
107 abort: "." cannot be used as the name of a patch
107 abort: "." cannot be used as the name of a patch
108 abort: ".." cannot be used as the name of a patch
108 abort: ".." cannot be used as the name of a patch
109 abort: patch name cannot begin with ".hg"
109 abort: patch name cannot begin with ".hg"
110 abort: patch name cannot begin with ".mq"
110 abort: patch name cannot begin with ".mq"
111 abort: "#" cannot be used in the name of a patch
111 abort: "#" cannot be used in the name of a patch
112 abort: ":" cannot be used in the name of a patch
112 abort: ":" cannot be used in the name of a patch
113 % qnew with name containing slash
113 % qnew with name containing slash
114 abort: path ends in directory separator: foo/ (glob)
114 abort: path ends in directory separator: foo/ (glob)
115 abort: "foo" already exists as a directory
115 abort: "foo" already exists as a directory
116 foo/bar.patch
116 foo/bar.patch
117 popping foo/bar.patch
117 popping foo/bar.patch
118 patch queue now empty
118 patch queue now empty
119 % qnew with uncommitted changes
119 % qnew with uncommitted changes
120 uncommitted.patch
120 uncommitted.patch
121 % qnew implies add
121 % qnew implies add
122 A .hgignore
122 A .hgignore
123 A series
123 A series
124 A uncommitted.patch
124 A uncommitted.patch
125 % qnew missing
125 % qnew missing
126 abort: missing: * (glob)
126 abort: missing: * (glob)
127 % qnew -m
127 % qnew -m
128 foo bar
128 foo bar
129
129
130 % qnew twice
130 % qnew twice
131 abort: patch "first.patch" already exists
131 abort: patch "first.patch" already exists
132 abort: patch "first.patch" already exists
132 abort: patch "first.patch" already exists
133 % qnew -f from a subdirectory
133 % qnew -f from a subdirectory
134 popping first.patch
134 popping first.patch
135 popping mtest.patch
135 popping mtest.patch
136 popping uncommitted.patch
136 popping uncommitted.patch
137 patch queue now empty
137 patch queue now empty
138 adding d/b
138 adding d/b
139 M d/b
139 M d/b
140 diff --git a/d/b b/d/b
140 diff --git a/d/b b/d/b
141 --- a/d/b
141 --- a/d/b
142 +++ b/d/b
142 +++ b/d/b
143 @@ -1,1 +1,2 @@
143 @@ -1,1 +1,2 @@
144 b
144 b
145 +b
145 +b
146 % qnew -u with no username configured
146 % qnew -u with no username configured
147 From: blue
147 From: blue
148
148
149 % qnew -e -u with no username configured
149 % qnew -e -u with no username configured
150 From: chartreuse
150 From: chartreuse
151
151
152 % fail when trying to import a merge
152 % fail when trying to import a merge
153 adding a
153 adding a
154 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
154 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
155 created new head
155 created new head
156 merging a
156 merging a
157 warning: conflicts during merge.
157 warning: conflicts during merge.
158 merging a incomplete! (edit conflicts, then use 'hg resolve --mark')
158 merging a incomplete! (edit conflicts, then use 'hg resolve --mark')
159 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
159 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
160 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
160 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
161 (no more unresolved files)
161 (no more unresolved files)
162 abort: cannot manage merge changesets
162 abort: cannot manage merge changesets
163 $ rm -r sandbox
163 $ rm -r sandbox
164
164
165 hg headers
165 hg headers
166
166
167 $ echo "plain=false" >> $HGRCPATH
167 $ echo "plain=false" >> $HGRCPATH
168 $ mkdir sandbox
168 $ mkdir sandbox
169 $ (cd sandbox ; runtest)
169 $ (cd sandbox ; runtest)
170 adding a
170 adding a
171 % qnew should refuse bad patch names
171 % qnew should refuse bad patch names
172 abort: "series" cannot be used as the name of a patch
172 abort: "series" cannot be used as the name of a patch
173 abort: "status" cannot be used as the name of a patch
173 abort: "status" cannot be used as the name of a patch
174 abort: "guards" cannot be used as the name of a patch
174 abort: "guards" cannot be used as the name of a patch
175 abort: "." cannot be used as the name of a patch
175 abort: "." cannot be used as the name of a patch
176 abort: ".." cannot be used as the name of a patch
176 abort: ".." cannot be used as the name of a patch
177 abort: patch name cannot begin with ".hg"
177 abort: patch name cannot begin with ".hg"
178 abort: patch name cannot begin with ".mq"
178 abort: patch name cannot begin with ".mq"
179 abort: "#" cannot be used in the name of a patch
179 abort: "#" cannot be used in the name of a patch
180 abort: ":" cannot be used in the name of a patch
180 abort: ":" cannot be used in the name of a patch
181 % qnew with name containing slash
181 % qnew with name containing slash
182 abort: path ends in directory separator: foo/ (glob)
182 abort: path ends in directory separator: foo/ (glob)
183 abort: "foo" already exists as a directory
183 abort: "foo" already exists as a directory
184 foo/bar.patch
184 foo/bar.patch
185 popping foo/bar.patch
185 popping foo/bar.patch
186 patch queue now empty
186 patch queue now empty
187 % qnew with uncommitted changes
187 % qnew with uncommitted changes
188 uncommitted.patch
188 uncommitted.patch
189 % qnew implies add
189 % qnew implies add
190 A .hgignore
190 A .hgignore
191 A series
191 A series
192 A uncommitted.patch
192 A uncommitted.patch
193 % qnew missing
193 % qnew missing
194 abort: missing: * (glob)
194 abort: missing: * (glob)
195 % qnew -m
195 % qnew -m
196 # HG changeset patch
196 # HG changeset patch
197 # Parent
197 # Parent
198 foo bar
198 foo bar
199
199
200 % qnew twice
200 % qnew twice
201 abort: patch "first.patch" already exists
201 abort: patch "first.patch" already exists
202 abort: patch "first.patch" already exists
202 abort: patch "first.patch" already exists
203 % qnew -f from a subdirectory
203 % qnew -f from a subdirectory
204 popping first.patch
204 popping first.patch
205 popping mtest.patch
205 popping mtest.patch
206 popping uncommitted.patch
206 popping uncommitted.patch
207 patch queue now empty
207 patch queue now empty
208 adding d/b
208 adding d/b
209 M d/b
209 M d/b
210 # HG changeset patch
210 # HG changeset patch
211 # Parent
211 # Parent
212
212
213 diff --git a/d/b b/d/b
213 diff --git a/d/b b/d/b
214 --- a/d/b
214 --- a/d/b
215 +++ b/d/b
215 +++ b/d/b
216 @@ -1,1 +1,2 @@
216 @@ -1,1 +1,2 @@
217 b
217 b
218 +b
218 +b
219 % qnew -u with no username configured
219 % qnew -u with no username configured
220 # HG changeset patch
220 # HG changeset patch
221 # User blue
221 # Parent
222 # Parent
222 # User blue
223
223
224 % qnew -e -u with no username configured
224 % qnew -e -u with no username configured
225 # HG changeset patch
225 # HG changeset patch
226 # User chartreuse
226 # Parent
227 # Parent
227 # User chartreuse
228
228
229 % fail when trying to import a merge
229 % fail when trying to import a merge
230 adding a
230 adding a
231 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
231 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
232 created new head
232 created new head
233 merging a
233 merging a
234 warning: conflicts during merge.
234 warning: conflicts during merge.
235 merging a incomplete! (edit conflicts, then use 'hg resolve --mark')
235 merging a incomplete! (edit conflicts, then use 'hg resolve --mark')
236 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
236 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
237 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
237 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
238 (no more unresolved files)
238 (no more unresolved files)
239 abort: cannot manage merge changesets
239 abort: cannot manage merge changesets
240 $ rm -r sandbox
240 $ rm -r sandbox
241
241
242 Test saving last-message.txt
242 Test saving last-message.txt
243
243
244 $ hg init repo
244 $ hg init repo
245 $ cd repo
245 $ cd repo
246
246
247 $ cat > $TESTTMP/commitfailure.py <<EOF
247 $ cat > $TESTTMP/commitfailure.py <<EOF
248 > from mercurial import util
248 > from mercurial import util
249 > def reposetup(ui, repo):
249 > def reposetup(ui, repo):
250 > class commitfailure(repo.__class__):
250 > class commitfailure(repo.__class__):
251 > def commit(self, *args, **kwargs):
251 > def commit(self, *args, **kwargs):
252 > raise util.Abort('emulating unexpected abort')
252 > raise util.Abort('emulating unexpected abort')
253 > repo.__class__ = commitfailure
253 > repo.__class__ = commitfailure
254 > EOF
254 > EOF
255 $ cat >> .hg/hgrc <<EOF
255 $ cat >> .hg/hgrc <<EOF
256 > [extensions]
256 > [extensions]
257 > # this failure occurs before editor invocation
257 > # this failure occurs before editor invocation
258 > commitfailure = $TESTTMP/commitfailure.py
258 > commitfailure = $TESTTMP/commitfailure.py
259 > EOF
259 > EOF
260
260
261 $ cat > $TESTTMP/editor.sh << EOF
261 $ cat > $TESTTMP/editor.sh << EOF
262 > echo "==== before editing"
262 > echo "==== before editing"
263 > cat \$1
263 > cat \$1
264 > echo "===="
264 > echo "===="
265 > echo "test saving last-message.txt" >> \$1
265 > echo "test saving last-message.txt" >> \$1
266 > EOF
266 > EOF
267
267
268 (test that editor is not invoked before transaction starting)
268 (test that editor is not invoked before transaction starting)
269
269
270 $ rm -f .hg/last-message.txt
270 $ rm -f .hg/last-message.txt
271 $ HGEDITOR="sh $TESTTMP/editor.sh" hg qnew -e patch
271 $ HGEDITOR="sh $TESTTMP/editor.sh" hg qnew -e patch
272 abort: emulating unexpected abort
272 abort: emulating unexpected abort
273 [255]
273 [255]
274 $ test -f .hg/last-message.txt
274 $ test -f .hg/last-message.txt
275 [1]
275 [1]
276
276
277 (test that editor is invoked and commit message is saved into
277 (test that editor is invoked and commit message is saved into
278 "last-message.txt")
278 "last-message.txt")
279
279
280 $ cat >> .hg/hgrc <<EOF
280 $ cat >> .hg/hgrc <<EOF
281 > [extensions]
281 > [extensions]
282 > commitfailure = !
282 > commitfailure = !
283 > [hooks]
283 > [hooks]
284 > # this failure occurs after editor invocation
284 > # this failure occurs after editor invocation
285 > pretxncommit.unexpectedabort = false
285 > pretxncommit.unexpectedabort = false
286 > EOF
286 > EOF
287
287
288 $ rm -f .hg/last-message.txt
288 $ rm -f .hg/last-message.txt
289 $ hg status
289 $ hg status
290 $ HGEDITOR="sh $TESTTMP/editor.sh" hg qnew -e patch
290 $ HGEDITOR="sh $TESTTMP/editor.sh" hg qnew -e patch
291 ==== before editing
291 ==== before editing
292
292
293
293
294 HG: Enter commit message. Lines beginning with 'HG:' are removed.
294 HG: Enter commit message. Lines beginning with 'HG:' are removed.
295 HG: Leave message empty to use default message.
295 HG: Leave message empty to use default message.
296 HG: --
296 HG: --
297 HG: user: test
297 HG: user: test
298 HG: branch 'default'
298 HG: branch 'default'
299 HG: no files changed
299 HG: no files changed
300 ====
300 ====
301 transaction abort!
301 transaction abort!
302 rollback completed
302 rollback completed
303 note: commit message saved in .hg/last-message.txt
303 note: commit message saved in .hg/last-message.txt
304 abort: pretxncommit.unexpectedabort hook exited with status 1
304 abort: pretxncommit.unexpectedabort hook exited with status 1
305 [255]
305 [255]
306 $ cat .hg/last-message.txt
306 $ cat .hg/last-message.txt
307
307
308
308
309 test saving last-message.txt
309 test saving last-message.txt
310
310
311 $ cat >> .hg/hgrc <<EOF
311 $ cat >> .hg/hgrc <<EOF
312 > [hooks]
312 > [hooks]
313 > pretxncommit.unexpectedabort =
313 > pretxncommit.unexpectedabort =
314 > EOF
314 > EOF
315
315
316 #if unix-permissions
316 #if unix-permissions
317
317
318 Test handling default message with the patch filename with tail whitespaces
318 Test handling default message with the patch filename with tail whitespaces
319
319
320 $ cat > $TESTTMP/editor.sh << EOF
320 $ cat > $TESTTMP/editor.sh << EOF
321 > echo "==== before editing"
321 > echo "==== before editing"
322 > cat \$1
322 > cat \$1
323 > echo "===="
323 > echo "===="
324 > echo "[mq]: patch " > \$1
324 > echo "[mq]: patch " > \$1
325 > EOF
325 > EOF
326
326
327 $ rm -f .hg/last-message.txt
327 $ rm -f .hg/last-message.txt
328 $ hg status
328 $ hg status
329 $ HGEDITOR="sh $TESTTMP/editor.sh" hg qnew -e "patch "
329 $ HGEDITOR="sh $TESTTMP/editor.sh" hg qnew -e "patch "
330 ==== before editing
330 ==== before editing
331
331
332
332
333 HG: Enter commit message. Lines beginning with 'HG:' are removed.
333 HG: Enter commit message. Lines beginning with 'HG:' are removed.
334 HG: Leave message empty to use default message.
334 HG: Leave message empty to use default message.
335 HG: --
335 HG: --
336 HG: user: test
336 HG: user: test
337 HG: branch 'default'
337 HG: branch 'default'
338 HG: no files changed
338 HG: no files changed
339 ====
339 ====
340 $ cat ".hg/patches/patch "
340 $ cat ".hg/patches/patch "
341 # HG changeset patch
341 # HG changeset patch
342 # Parent 0000000000000000000000000000000000000000
342 # Parent 0000000000000000000000000000000000000000
343
343
344
344
345 $ cd ..
345 $ cd ..
346
346
347 #endif
347 #endif
@@ -1,601 +1,601 b''
1 $ echo "[ui]" >> $HGRCPATH
1 $ echo "[ui]" >> $HGRCPATH
2 $ echo "commitsubrepos = Yes" >> $HGRCPATH
2 $ echo "commitsubrepos = Yes" >> $HGRCPATH
3 $ echo "[extensions]" >> $HGRCPATH
3 $ echo "[extensions]" >> $HGRCPATH
4 $ echo "mq=" >> $HGRCPATH
4 $ echo "mq=" >> $HGRCPATH
5 $ echo "record=" >> $HGRCPATH
5 $ echo "record=" >> $HGRCPATH
6 $ echo "[diff]" >> $HGRCPATH
6 $ echo "[diff]" >> $HGRCPATH
7 $ echo "nodates=1" >> $HGRCPATH
7 $ echo "nodates=1" >> $HGRCPATH
8
8
9 $ stdin=`pwd`/stdin.tmp
9 $ stdin=`pwd`/stdin.tmp
10
10
11 fn to create new repository w/dirty subrepo, and cd into it
11 fn to create new repository w/dirty subrepo, and cd into it
12 $ mkrepo() {
12 $ mkrepo() {
13 > hg init $1
13 > hg init $1
14 > cd $1
14 > cd $1
15 > hg qinit
15 > hg qinit
16 > }
16 > }
17
17
18 fn to create dirty subrepo
18 fn to create dirty subrepo
19 $ mksubrepo() {
19 $ mksubrepo() {
20 > hg init $1
20 > hg init $1
21 > cd $1
21 > cd $1
22 > echo a > a
22 > echo a > a
23 > hg add
23 > hg add
24 > cd ..
24 > cd ..
25 > }
25 > }
26
26
27 $ testadd() {
27 $ testadd() {
28 > cat - > "$stdin"
28 > cat - > "$stdin"
29 > mksubrepo sub
29 > mksubrepo sub
30 > echo sub = sub >> .hgsub
30 > echo sub = sub >> .hgsub
31 > hg add .hgsub
31 > hg add .hgsub
32 > echo % abort when adding .hgsub w/dirty subrepo
32 > echo % abort when adding .hgsub w/dirty subrepo
33 > hg status -S
33 > hg status -S
34 > echo '%' $*
34 > echo '%' $*
35 > cat "$stdin" | hg $*
35 > cat "$stdin" | hg $*
36 > echo [$?]
36 > echo [$?]
37 > hg -R sub ci -m0sub
37 > hg -R sub ci -m0sub
38 > echo % update substate when adding .hgsub w/clean updated subrepo
38 > echo % update substate when adding .hgsub w/clean updated subrepo
39 > hg status -S
39 > hg status -S
40 > echo '%' $*
40 > echo '%' $*
41 > cat "$stdin" | hg $*
41 > cat "$stdin" | hg $*
42 > hg debugsub
42 > hg debugsub
43 > }
43 > }
44
44
45 $ testmod() {
45 $ testmod() {
46 > cat - > "$stdin"
46 > cat - > "$stdin"
47 > mksubrepo sub2
47 > mksubrepo sub2
48 > echo sub2 = sub2 >> .hgsub
48 > echo sub2 = sub2 >> .hgsub
49 > echo % abort when modifying .hgsub w/dirty subrepo
49 > echo % abort when modifying .hgsub w/dirty subrepo
50 > hg status -S
50 > hg status -S
51 > echo '%' $*
51 > echo '%' $*
52 > cat "$stdin" | hg $*
52 > cat "$stdin" | hg $*
53 > echo [$?]
53 > echo [$?]
54 > hg -R sub2 ci -m0sub2
54 > hg -R sub2 ci -m0sub2
55 > echo % update substate when modifying .hgsub w/clean updated subrepo
55 > echo % update substate when modifying .hgsub w/clean updated subrepo
56 > hg status -S
56 > hg status -S
57 > echo '%' $*
57 > echo '%' $*
58 > cat "$stdin" | hg $*
58 > cat "$stdin" | hg $*
59 > hg debugsub
59 > hg debugsub
60 > }
60 > }
61
61
62 $ testrm1() {
62 $ testrm1() {
63 > cat - > "$stdin"
63 > cat - > "$stdin"
64 > mksubrepo sub3
64 > mksubrepo sub3
65 > echo sub3 = sub3 >> .hgsub
65 > echo sub3 = sub3 >> .hgsub
66 > hg ci -Aqmsub3
66 > hg ci -Aqmsub3
67 > $EXTRA
67 > $EXTRA
68 > echo b >> sub3/a
68 > echo b >> sub3/a
69 > hg rm .hgsub
69 > hg rm .hgsub
70 > echo % update substate when removing .hgsub w/dirty subrepo
70 > echo % update substate when removing .hgsub w/dirty subrepo
71 > hg status -S
71 > hg status -S
72 > echo '%' $*
72 > echo '%' $*
73 > cat "$stdin" | hg $*
73 > cat "$stdin" | hg $*
74 > echo % debugsub should be empty
74 > echo % debugsub should be empty
75 > hg debugsub
75 > hg debugsub
76 > }
76 > }
77
77
78 $ testrm2() {
78 $ testrm2() {
79 > cat - > "$stdin"
79 > cat - > "$stdin"
80 > mksubrepo sub4
80 > mksubrepo sub4
81 > echo sub4 = sub4 >> .hgsub
81 > echo sub4 = sub4 >> .hgsub
82 > hg ci -Aqmsub4
82 > hg ci -Aqmsub4
83 > $EXTRA
83 > $EXTRA
84 > hg rm .hgsub
84 > hg rm .hgsub
85 > echo % update substate when removing .hgsub w/clean updated subrepo
85 > echo % update substate when removing .hgsub w/clean updated subrepo
86 > hg status -S
86 > hg status -S
87 > echo '%' $*
87 > echo '%' $*
88 > cat "$stdin" | hg $*
88 > cat "$stdin" | hg $*
89 > echo % debugsub should be empty
89 > echo % debugsub should be empty
90 > hg debugsub
90 > hg debugsub
91 > }
91 > }
92
92
93
93
94 handle subrepos safely on qnew
94 handle subrepos safely on qnew
95
95
96 $ mkrepo repo-2499-qnew
96 $ mkrepo repo-2499-qnew
97 $ testadd qnew -X path:no-effect -m0 0.diff
97 $ testadd qnew -X path:no-effect -m0 0.diff
98 adding a
98 adding a
99 % abort when adding .hgsub w/dirty subrepo
99 % abort when adding .hgsub w/dirty subrepo
100 A .hgsub
100 A .hgsub
101 A sub/a
101 A sub/a
102 % qnew -X path:no-effect -m0 0.diff
102 % qnew -X path:no-effect -m0 0.diff
103 abort: uncommitted changes in subrepository sub
103 abort: uncommitted changes in subrepository sub
104 [255]
104 [255]
105 % update substate when adding .hgsub w/clean updated subrepo
105 % update substate when adding .hgsub w/clean updated subrepo
106 A .hgsub
106 A .hgsub
107 % qnew -X path:no-effect -m0 0.diff
107 % qnew -X path:no-effect -m0 0.diff
108 path sub
108 path sub
109 source sub
109 source sub
110 revision b2fdb12cd82b021c3b7053d67802e77b6eeaee31
110 revision b2fdb12cd82b021c3b7053d67802e77b6eeaee31
111
111
112 $ testmod qnew --cwd .. -R repo-2499-qnew -X path:no-effect -m1 1.diff
112 $ testmod qnew --cwd .. -R repo-2499-qnew -X path:no-effect -m1 1.diff
113 adding a
113 adding a
114 % abort when modifying .hgsub w/dirty subrepo
114 % abort when modifying .hgsub w/dirty subrepo
115 M .hgsub
115 M .hgsub
116 A sub2/a
116 A sub2/a
117 % qnew --cwd .. -R repo-2499-qnew -X path:no-effect -m1 1.diff
117 % qnew --cwd .. -R repo-2499-qnew -X path:no-effect -m1 1.diff
118 abort: uncommitted changes in subrepository sub2
118 abort: uncommitted changes in subrepository sub2
119 [255]
119 [255]
120 % update substate when modifying .hgsub w/clean updated subrepo
120 % update substate when modifying .hgsub w/clean updated subrepo
121 M .hgsub
121 M .hgsub
122 % qnew --cwd .. -R repo-2499-qnew -X path:no-effect -m1 1.diff
122 % qnew --cwd .. -R repo-2499-qnew -X path:no-effect -m1 1.diff
123 path sub
123 path sub
124 source sub
124 source sub
125 revision b2fdb12cd82b021c3b7053d67802e77b6eeaee31
125 revision b2fdb12cd82b021c3b7053d67802e77b6eeaee31
126 path sub2
126 path sub2
127 source sub2
127 source sub2
128 revision 1f94c7611cc6b74f5a17b16121a1170d44776845
128 revision 1f94c7611cc6b74f5a17b16121a1170d44776845
129
129
130 $ hg qpop -qa
130 $ hg qpop -qa
131 patch queue now empty
131 patch queue now empty
132 $ testrm1 qnew -m2 2.diff
132 $ testrm1 qnew -m2 2.diff
133 adding a
133 adding a
134 % update substate when removing .hgsub w/dirty subrepo
134 % update substate when removing .hgsub w/dirty subrepo
135 M sub3/a
135 M sub3/a
136 R .hgsub
136 R .hgsub
137 % qnew -m2 2.diff
137 % qnew -m2 2.diff
138 % debugsub should be empty
138 % debugsub should be empty
139
139
140 $ hg qpop -qa
140 $ hg qpop -qa
141 patch queue now empty
141 patch queue now empty
142 $ testrm2 qnew -m3 3.diff
142 $ testrm2 qnew -m3 3.diff
143 adding a
143 adding a
144 % update substate when removing .hgsub w/clean updated subrepo
144 % update substate when removing .hgsub w/clean updated subrepo
145 R .hgsub
145 R .hgsub
146 % qnew -m3 3.diff
146 % qnew -m3 3.diff
147 % debugsub should be empty
147 % debugsub should be empty
148
148
149 $ cd ..
149 $ cd ..
150
150
151
151
152 handle subrepos safely on qrefresh
152 handle subrepos safely on qrefresh
153
153
154 $ mkrepo repo-2499-qrefresh
154 $ mkrepo repo-2499-qrefresh
155 $ hg qnew -m0 0.diff
155 $ hg qnew -m0 0.diff
156 $ testadd qrefresh
156 $ testadd qrefresh
157 adding a
157 adding a
158 % abort when adding .hgsub w/dirty subrepo
158 % abort when adding .hgsub w/dirty subrepo
159 A .hgsub
159 A .hgsub
160 A sub/a
160 A sub/a
161 % qrefresh
161 % qrefresh
162 abort: uncommitted changes in subrepository sub
162 abort: uncommitted changes in subrepository sub
163 [255]
163 [255]
164 % update substate when adding .hgsub w/clean updated subrepo
164 % update substate when adding .hgsub w/clean updated subrepo
165 A .hgsub
165 A .hgsub
166 % qrefresh
166 % qrefresh
167 path sub
167 path sub
168 source sub
168 source sub
169 revision b2fdb12cd82b021c3b7053d67802e77b6eeaee31
169 revision b2fdb12cd82b021c3b7053d67802e77b6eeaee31
170
170
171 $ hg qnew -m1 1.diff
171 $ hg qnew -m1 1.diff
172 $ testmod qrefresh
172 $ testmod qrefresh
173 adding a
173 adding a
174 % abort when modifying .hgsub w/dirty subrepo
174 % abort when modifying .hgsub w/dirty subrepo
175 M .hgsub
175 M .hgsub
176 A sub2/a
176 A sub2/a
177 % qrefresh
177 % qrefresh
178 abort: uncommitted changes in subrepository sub2
178 abort: uncommitted changes in subrepository sub2
179 [255]
179 [255]
180 % update substate when modifying .hgsub w/clean updated subrepo
180 % update substate when modifying .hgsub w/clean updated subrepo
181 M .hgsub
181 M .hgsub
182 % qrefresh
182 % qrefresh
183 path sub
183 path sub
184 source sub
184 source sub
185 revision b2fdb12cd82b021c3b7053d67802e77b6eeaee31
185 revision b2fdb12cd82b021c3b7053d67802e77b6eeaee31
186 path sub2
186 path sub2
187 source sub2
187 source sub2
188 revision 1f94c7611cc6b74f5a17b16121a1170d44776845
188 revision 1f94c7611cc6b74f5a17b16121a1170d44776845
189
189
190 $ hg qpop -qa
190 $ hg qpop -qa
191 patch queue now empty
191 patch queue now empty
192 $ EXTRA='hg qnew -m2 2.diff'
192 $ EXTRA='hg qnew -m2 2.diff'
193 $ testrm1 qrefresh
193 $ testrm1 qrefresh
194 adding a
194 adding a
195 % update substate when removing .hgsub w/dirty subrepo
195 % update substate when removing .hgsub w/dirty subrepo
196 M sub3/a
196 M sub3/a
197 R .hgsub
197 R .hgsub
198 % qrefresh
198 % qrefresh
199 % debugsub should be empty
199 % debugsub should be empty
200
200
201 $ hg qpop -qa
201 $ hg qpop -qa
202 patch queue now empty
202 patch queue now empty
203 $ EXTRA='hg qnew -m3 3.diff'
203 $ EXTRA='hg qnew -m3 3.diff'
204 $ testrm2 qrefresh
204 $ testrm2 qrefresh
205 adding a
205 adding a
206 % update substate when removing .hgsub w/clean updated subrepo
206 % update substate when removing .hgsub w/clean updated subrepo
207 R .hgsub
207 R .hgsub
208 % qrefresh
208 % qrefresh
209 % debugsub should be empty
209 % debugsub should be empty
210 $ EXTRA=
210 $ EXTRA=
211
211
212 $ cd ..
212 $ cd ..
213
213
214
214
215 handle subrepos safely on qpush/qpop
215 handle subrepos safely on qpush/qpop
216 (and we cannot qpop / qpush with a modified subrepo)
216 (and we cannot qpop / qpush with a modified subrepo)
217
217
218 $ mkrepo repo-2499-qpush
218 $ mkrepo repo-2499-qpush
219 $ mksubrepo sub
219 $ mksubrepo sub
220 adding a
220 adding a
221 $ hg -R sub ci -m0sub
221 $ hg -R sub ci -m0sub
222 $ echo sub = sub > .hgsub
222 $ echo sub = sub > .hgsub
223 $ hg add .hgsub
223 $ hg add .hgsub
224 $ hg commit -m0
224 $ hg commit -m0
225 $ hg debugsub
225 $ hg debugsub
226 path sub
226 path sub
227 source sub
227 source sub
228 revision b2fdb12cd82b021c3b7053d67802e77b6eeaee31
228 revision b2fdb12cd82b021c3b7053d67802e77b6eeaee31
229 $ echo foo > ./sub/a
229 $ echo foo > ./sub/a
230 $ hg -R sub commit -m foo
230 $ hg -R sub commit -m foo
231 $ hg commit -m1
231 $ hg commit -m1
232 $ hg qimport -r "0:tip"
232 $ hg qimport -r "0:tip"
233 $ hg -R sub id --id
233 $ hg -R sub id --id
234 aa037b301eba
234 aa037b301eba
235
235
236 qpop
236 qpop
237 $ hg -R sub update 0000
237 $ hg -R sub update 0000
238 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
238 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
239 $ hg qpop
239 $ hg qpop
240 abort: local changed subrepos found, refresh first
240 abort: local changed subrepos found, refresh first
241 [255]
241 [255]
242 $ hg revert sub
242 $ hg revert sub
243 reverting subrepo sub
243 reverting subrepo sub
244 adding sub/a
244 adding sub/a
245 $ hg qpop
245 $ hg qpop
246 popping 1.diff
246 popping 1.diff
247 now at: 0.diff
247 now at: 0.diff
248 $ hg status -AS
248 $ hg status -AS
249 C .hgsub
249 C .hgsub
250 C .hgsubstate
250 C .hgsubstate
251 C sub/a
251 C sub/a
252 $ hg -R sub id --id
252 $ hg -R sub id --id
253 b2fdb12cd82b
253 b2fdb12cd82b
254
254
255 qpush
255 qpush
256 $ hg -R sub update 0000
256 $ hg -R sub update 0000
257 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
257 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
258 $ hg qpush
258 $ hg qpush
259 abort: local changed subrepos found, refresh first
259 abort: local changed subrepos found, refresh first
260 [255]
260 [255]
261 $ hg revert sub
261 $ hg revert sub
262 reverting subrepo sub
262 reverting subrepo sub
263 adding sub/a
263 adding sub/a
264 $ hg qpush
264 $ hg qpush
265 applying 1.diff
265 applying 1.diff
266 subrepository sub diverged (local revision: b2fdb12cd82b, remote revision: aa037b301eba)
266 subrepository sub diverged (local revision: b2fdb12cd82b, remote revision: aa037b301eba)
267 (M)erge, keep (l)ocal or keep (r)emote? m
267 (M)erge, keep (l)ocal or keep (r)emote? m
268 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
268 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
269 now at: 1.diff
269 now at: 1.diff
270 $ hg status -AS
270 $ hg status -AS
271 C .hgsub
271 C .hgsub
272 C .hgsubstate
272 C .hgsubstate
273 C sub/a
273 C sub/a
274 $ hg -R sub id --id
274 $ hg -R sub id --id
275 aa037b301eba
275 aa037b301eba
276
276
277 $ cd ..
277 $ cd ..
278
278
279
279
280 handle subrepos safely on qrecord
280 handle subrepos safely on qrecord
281
281
282 $ mkrepo repo-2499-qrecord
282 $ mkrepo repo-2499-qrecord
283 $ testadd qrecord --config ui.interactive=1 -m0 0.diff <<EOF
283 $ testadd qrecord --config ui.interactive=1 -m0 0.diff <<EOF
284 > y
284 > y
285 > y
285 > y
286 > EOF
286 > EOF
287 adding a
287 adding a
288 % abort when adding .hgsub w/dirty subrepo
288 % abort when adding .hgsub w/dirty subrepo
289 A .hgsub
289 A .hgsub
290 A sub/a
290 A sub/a
291 % qrecord --config ui.interactive=1 -m0 0.diff
291 % qrecord --config ui.interactive=1 -m0 0.diff
292 diff --git a/.hgsub b/.hgsub
292 diff --git a/.hgsub b/.hgsub
293 new file mode 100644
293 new file mode 100644
294 examine changes to '.hgsub'? [Ynesfdaq?]
294 examine changes to '.hgsub'? [Ynesfdaq?]
295 abort: uncommitted changes in subrepository sub
295 abort: uncommitted changes in subrepository sub
296 [255]
296 [255]
297 % update substate when adding .hgsub w/clean updated subrepo
297 % update substate when adding .hgsub w/clean updated subrepo
298 A .hgsub
298 A .hgsub
299 % qrecord --config ui.interactive=1 -m0 0.diff
299 % qrecord --config ui.interactive=1 -m0 0.diff
300 diff --git a/.hgsub b/.hgsub
300 diff --git a/.hgsub b/.hgsub
301 new file mode 100644
301 new file mode 100644
302 examine changes to '.hgsub'? [Ynesfdaq?]
302 examine changes to '.hgsub'? [Ynesfdaq?]
303 path sub
303 path sub
304 source sub
304 source sub
305 revision b2fdb12cd82b021c3b7053d67802e77b6eeaee31
305 revision b2fdb12cd82b021c3b7053d67802e77b6eeaee31
306
306
307 $ testmod qrecord --config ui.interactive=1 -m1 1.diff <<EOF
307 $ testmod qrecord --config ui.interactive=1 -m1 1.diff <<EOF
308 > y
308 > y
309 > y
309 > y
310 > EOF
310 > EOF
311 adding a
311 adding a
312 % abort when modifying .hgsub w/dirty subrepo
312 % abort when modifying .hgsub w/dirty subrepo
313 M .hgsub
313 M .hgsub
314 A sub2/a
314 A sub2/a
315 % qrecord --config ui.interactive=1 -m1 1.diff
315 % qrecord --config ui.interactive=1 -m1 1.diff
316 diff --git a/.hgsub b/.hgsub
316 diff --git a/.hgsub b/.hgsub
317 1 hunks, 1 lines changed
317 1 hunks, 1 lines changed
318 examine changes to '.hgsub'? [Ynesfdaq?]
318 examine changes to '.hgsub'? [Ynesfdaq?]
319 @@ -1,1 +1,2 @@
319 @@ -1,1 +1,2 @@
320 sub = sub
320 sub = sub
321 +sub2 = sub2
321 +sub2 = sub2
322 record this change to '.hgsub'? [Ynesfdaq?]
322 record this change to '.hgsub'? [Ynesfdaq?]
323 abort: uncommitted changes in subrepository sub2
323 abort: uncommitted changes in subrepository sub2
324 [255]
324 [255]
325 % update substate when modifying .hgsub w/clean updated subrepo
325 % update substate when modifying .hgsub w/clean updated subrepo
326 M .hgsub
326 M .hgsub
327 % qrecord --config ui.interactive=1 -m1 1.diff
327 % qrecord --config ui.interactive=1 -m1 1.diff
328 diff --git a/.hgsub b/.hgsub
328 diff --git a/.hgsub b/.hgsub
329 1 hunks, 1 lines changed
329 1 hunks, 1 lines changed
330 examine changes to '.hgsub'? [Ynesfdaq?]
330 examine changes to '.hgsub'? [Ynesfdaq?]
331 @@ -1,1 +1,2 @@
331 @@ -1,1 +1,2 @@
332 sub = sub
332 sub = sub
333 +sub2 = sub2
333 +sub2 = sub2
334 record this change to '.hgsub'? [Ynesfdaq?]
334 record this change to '.hgsub'? [Ynesfdaq?]
335 path sub
335 path sub
336 source sub
336 source sub
337 revision b2fdb12cd82b021c3b7053d67802e77b6eeaee31
337 revision b2fdb12cd82b021c3b7053d67802e77b6eeaee31
338 path sub2
338 path sub2
339 source sub2
339 source sub2
340 revision 1f94c7611cc6b74f5a17b16121a1170d44776845
340 revision 1f94c7611cc6b74f5a17b16121a1170d44776845
341
341
342 $ hg qpop -qa
342 $ hg qpop -qa
343 patch queue now empty
343 patch queue now empty
344 $ testrm1 qrecord --config ui.interactive=1 -m2 2.diff <<EOF
344 $ testrm1 qrecord --config ui.interactive=1 -m2 2.diff <<EOF
345 > y
345 > y
346 > y
346 > y
347 > EOF
347 > EOF
348 adding a
348 adding a
349 % update substate when removing .hgsub w/dirty subrepo
349 % update substate when removing .hgsub w/dirty subrepo
350 M sub3/a
350 M sub3/a
351 R .hgsub
351 R .hgsub
352 % qrecord --config ui.interactive=1 -m2 2.diff
352 % qrecord --config ui.interactive=1 -m2 2.diff
353 diff --git a/.hgsub b/.hgsub
353 diff --git a/.hgsub b/.hgsub
354 deleted file mode 100644
354 deleted file mode 100644
355 examine changes to '.hgsub'? [Ynesfdaq?]
355 examine changes to '.hgsub'? [Ynesfdaq?]
356 % debugsub should be empty
356 % debugsub should be empty
357
357
358 $ hg qpop -qa
358 $ hg qpop -qa
359 patch queue now empty
359 patch queue now empty
360 $ testrm2 qrecord --config ui.interactive=1 -m3 3.diff <<EOF
360 $ testrm2 qrecord --config ui.interactive=1 -m3 3.diff <<EOF
361 > y
361 > y
362 > y
362 > y
363 > EOF
363 > EOF
364 adding a
364 adding a
365 % update substate when removing .hgsub w/clean updated subrepo
365 % update substate when removing .hgsub w/clean updated subrepo
366 R .hgsub
366 R .hgsub
367 % qrecord --config ui.interactive=1 -m3 3.diff
367 % qrecord --config ui.interactive=1 -m3 3.diff
368 diff --git a/.hgsub b/.hgsub
368 diff --git a/.hgsub b/.hgsub
369 deleted file mode 100644
369 deleted file mode 100644
370 examine changes to '.hgsub'? [Ynesfdaq?]
370 examine changes to '.hgsub'? [Ynesfdaq?]
371 % debugsub should be empty
371 % debugsub should be empty
372
372
373 $ cd ..
373 $ cd ..
374
374
375
375
376 correctly handle subrepos with patch queues
376 correctly handle subrepos with patch queues
377 $ mkrepo repo-subrepo-with-queue
377 $ mkrepo repo-subrepo-with-queue
378 $ mksubrepo sub
378 $ mksubrepo sub
379 adding a
379 adding a
380 $ hg -R sub qnew sub0.diff
380 $ hg -R sub qnew sub0.diff
381 $ echo sub = sub >> .hgsub
381 $ echo sub = sub >> .hgsub
382 $ hg add .hgsub
382 $ hg add .hgsub
383 $ hg qnew 0.diff
383 $ hg qnew 0.diff
384
384
385 $ cd ..
385 $ cd ..
386
386
387 check whether MQ operations can import updated .hgsubstate correctly
387 check whether MQ operations can import updated .hgsubstate correctly
388 both into 'revision' and 'patch file under .hg/patches':
388 both into 'revision' and 'patch file under .hg/patches':
389
389
390 $ hg init importing-hgsubstate
390 $ hg init importing-hgsubstate
391 $ cd importing-hgsubstate
391 $ cd importing-hgsubstate
392
392
393 $ echo a > a
393 $ echo a > a
394 $ hg commit -u test -d '0 0' -Am '#0 in parent'
394 $ hg commit -u test -d '0 0' -Am '#0 in parent'
395 adding a
395 adding a
396 $ hg init sub
396 $ hg init sub
397 $ echo sa > sub/sa
397 $ echo sa > sub/sa
398 $ hg -R sub commit -u test -d '0 0' -Am '#0 in sub'
398 $ hg -R sub commit -u test -d '0 0' -Am '#0 in sub'
399 adding sa
399 adding sa
400 $ echo 'sub = sub' > .hgsub
400 $ echo 'sub = sub' > .hgsub
401 $ touch .hgsubstate
401 $ touch .hgsubstate
402 $ hg add .hgsub .hgsubstate
402 $ hg add .hgsub .hgsubstate
403
403
404 $ hg qnew -u test -d '0 0' import-at-qnew
404 $ hg qnew -u test -d '0 0' import-at-qnew
405 $ hg -R sub parents --template '{node} sub\n'
405 $ hg -R sub parents --template '{node} sub\n'
406 b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
406 b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
407 $ cat .hgsubstate
407 $ cat .hgsubstate
408 b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
408 b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
409 $ hg diff -c tip
409 $ hg diff -c tip
410 diff -r f499373e340c -r f69e96d86e75 .hgsub
410 diff -r f499373e340c -r f69e96d86e75 .hgsub
411 --- /dev/null
411 --- /dev/null
412 +++ b/.hgsub
412 +++ b/.hgsub
413 @@ -0,0 +1,1 @@
413 @@ -0,0 +1,1 @@
414 +sub = sub
414 +sub = sub
415 diff -r f499373e340c -r f69e96d86e75 .hgsubstate
415 diff -r f499373e340c -r f69e96d86e75 .hgsubstate
416 --- /dev/null
416 --- /dev/null
417 +++ b/.hgsubstate
417 +++ b/.hgsubstate
418 @@ -0,0 +1,1 @@
418 @@ -0,0 +1,1 @@
419 +b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
419 +b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
420 $ cat .hg/patches/import-at-qnew
420 $ cat .hg/patches/import-at-qnew
421 # HG changeset patch
421 # HG changeset patch
422 # Parent f499373e340cdca5d01dee904aeb42dd2a325e71
423 # User test
422 # User test
424 # Date 0 0
423 # Date 0 0
424 # Parent f499373e340cdca5d01dee904aeb42dd2a325e71
425
425
426 diff -r f499373e340c -r f69e96d86e75 .hgsub
426 diff -r f499373e340c -r f69e96d86e75 .hgsub
427 --- /dev/null
427 --- /dev/null
428 +++ b/.hgsub
428 +++ b/.hgsub
429 @@ -0,0 +1,1 @@
429 @@ -0,0 +1,1 @@
430 +sub = sub
430 +sub = sub
431 diff -r f499373e340c -r f69e96d86e75 .hgsubstate
431 diff -r f499373e340c -r f69e96d86e75 .hgsubstate
432 --- /dev/null
432 --- /dev/null
433 +++ b/.hgsubstate
433 +++ b/.hgsubstate
434 @@ -0,0 +1,1 @@
434 @@ -0,0 +1,1 @@
435 +b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
435 +b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
436 $ hg parents --template '{node}\n'
436 $ hg parents --template '{node}\n'
437 f69e96d86e75a6d4fd88285dc9697acb23951041
437 f69e96d86e75a6d4fd88285dc9697acb23951041
438 $ hg parents --template '{files}\n'
438 $ hg parents --template '{files}\n'
439 .hgsub .hgsubstate
439 .hgsub .hgsubstate
440
440
441 check also whether qnew not including ".hgsubstate" explicitly causes
441 check also whether qnew not including ".hgsubstate" explicitly causes
442 as same result (in node hash) as one including it.
442 as same result (in node hash) as one including it.
443
443
444 $ hg qpop -a -q
444 $ hg qpop -a -q
445 patch queue now empty
445 patch queue now empty
446 $ hg qdelete import-at-qnew
446 $ hg qdelete import-at-qnew
447 $ echo 'sub = sub' > .hgsub
447 $ echo 'sub = sub' > .hgsub
448 $ hg add .hgsub
448 $ hg add .hgsub
449 $ rm -f .hgsubstate
449 $ rm -f .hgsubstate
450 $ hg qnew -u test -d '0 0' import-at-qnew
450 $ hg qnew -u test -d '0 0' import-at-qnew
451 $ hg parents --template '{node}\n'
451 $ hg parents --template '{node}\n'
452 f69e96d86e75a6d4fd88285dc9697acb23951041
452 f69e96d86e75a6d4fd88285dc9697acb23951041
453 $ hg parents --template '{files}\n'
453 $ hg parents --template '{files}\n'
454 .hgsub .hgsubstate
454 .hgsub .hgsubstate
455
455
456 check whether qrefresh imports updated .hgsubstate correctly
456 check whether qrefresh imports updated .hgsubstate correctly
457
457
458 $ hg qpop
458 $ hg qpop
459 popping import-at-qnew
459 popping import-at-qnew
460 patch queue now empty
460 patch queue now empty
461 $ hg qpush
461 $ hg qpush
462 applying import-at-qnew
462 applying import-at-qnew
463 now at: import-at-qnew
463 now at: import-at-qnew
464 $ hg parents --template '{files}\n'
464 $ hg parents --template '{files}\n'
465 .hgsub .hgsubstate
465 .hgsub .hgsubstate
466
466
467 $ hg qnew import-at-qrefresh
467 $ hg qnew import-at-qrefresh
468 $ echo sb > sub/sb
468 $ echo sb > sub/sb
469 $ hg -R sub commit -u test -d '0 0' -Am '#1 in sub'
469 $ hg -R sub commit -u test -d '0 0' -Am '#1 in sub'
470 adding sb
470 adding sb
471 $ hg qrefresh -u test -d '0 0'
471 $ hg qrefresh -u test -d '0 0'
472 $ hg -R sub parents --template '{node} sub\n'
472 $ hg -R sub parents --template '{node} sub\n'
473 88ac1bef5ed43b689d1d200b59886b675dec474b sub
473 88ac1bef5ed43b689d1d200b59886b675dec474b sub
474 $ cat .hgsubstate
474 $ cat .hgsubstate
475 88ac1bef5ed43b689d1d200b59886b675dec474b sub
475 88ac1bef5ed43b689d1d200b59886b675dec474b sub
476 $ hg diff -c tip
476 $ hg diff -c tip
477 diff -r 05b056bb9c8c -r d987bec230f4 .hgsubstate
477 diff -r 05b056bb9c8c -r d987bec230f4 .hgsubstate
478 --- a/.hgsubstate
478 --- a/.hgsubstate
479 +++ b/.hgsubstate
479 +++ b/.hgsubstate
480 @@ -1,1 +1,1 @@
480 @@ -1,1 +1,1 @@
481 -b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
481 -b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
482 +88ac1bef5ed43b689d1d200b59886b675dec474b sub
482 +88ac1bef5ed43b689d1d200b59886b675dec474b sub
483 $ cat .hg/patches/import-at-qrefresh
483 $ cat .hg/patches/import-at-qrefresh
484 # HG changeset patch
484 # HG changeset patch
485 # Date 0 0
485 # Date 0 0
486 # User test
486 # User test
487 # Parent 05b056bb9c8c05ff15258b84fd42ab3527271033
487 # Parent 05b056bb9c8c05ff15258b84fd42ab3527271033
488
488
489 diff -r 05b056bb9c8c .hgsubstate
489 diff -r 05b056bb9c8c .hgsubstate
490 --- a/.hgsubstate
490 --- a/.hgsubstate
491 +++ b/.hgsubstate
491 +++ b/.hgsubstate
492 @@ -1,1 +1,1 @@
492 @@ -1,1 +1,1 @@
493 -b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
493 -b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
494 +88ac1bef5ed43b689d1d200b59886b675dec474b sub
494 +88ac1bef5ed43b689d1d200b59886b675dec474b sub
495 $ hg parents --template '{files}\n'
495 $ hg parents --template '{files}\n'
496 .hgsubstate
496 .hgsubstate
497
497
498 $ hg qrefresh -u test -d '0 0'
498 $ hg qrefresh -u test -d '0 0'
499 $ cat .hgsubstate
499 $ cat .hgsubstate
500 88ac1bef5ed43b689d1d200b59886b675dec474b sub
500 88ac1bef5ed43b689d1d200b59886b675dec474b sub
501 $ hg diff -c tip
501 $ hg diff -c tip
502 diff -r 05b056bb9c8c -r d987bec230f4 .hgsubstate
502 diff -r 05b056bb9c8c -r d987bec230f4 .hgsubstate
503 --- a/.hgsubstate
503 --- a/.hgsubstate
504 +++ b/.hgsubstate
504 +++ b/.hgsubstate
505 @@ -1,1 +1,1 @@
505 @@ -1,1 +1,1 @@
506 -b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
506 -b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
507 +88ac1bef5ed43b689d1d200b59886b675dec474b sub
507 +88ac1bef5ed43b689d1d200b59886b675dec474b sub
508 $ cat .hg/patches/import-at-qrefresh
508 $ cat .hg/patches/import-at-qrefresh
509 # HG changeset patch
509 # HG changeset patch
510 # Date 0 0
510 # Date 0 0
511 # User test
511 # User test
512 # Parent 05b056bb9c8c05ff15258b84fd42ab3527271033
512 # Parent 05b056bb9c8c05ff15258b84fd42ab3527271033
513
513
514 diff -r 05b056bb9c8c .hgsubstate
514 diff -r 05b056bb9c8c .hgsubstate
515 --- a/.hgsubstate
515 --- a/.hgsubstate
516 +++ b/.hgsubstate
516 +++ b/.hgsubstate
517 @@ -1,1 +1,1 @@
517 @@ -1,1 +1,1 @@
518 -b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
518 -b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
519 +88ac1bef5ed43b689d1d200b59886b675dec474b sub
519 +88ac1bef5ed43b689d1d200b59886b675dec474b sub
520 $ hg parents --template '{files}\n'
520 $ hg parents --template '{files}\n'
521 .hgsubstate
521 .hgsubstate
522
522
523 $ hg update -C tip
523 $ hg update -C tip
524 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
524 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
525 $ hg qpop -a
525 $ hg qpop -a
526 popping import-at-qrefresh
526 popping import-at-qrefresh
527 popping import-at-qnew
527 popping import-at-qnew
528 patch queue now empty
528 patch queue now empty
529
529
530 $ hg -R sub update -C 0
530 $ hg -R sub update -C 0
531 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
531 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
532 $ echo 'sub = sub' > .hgsub
532 $ echo 'sub = sub' > .hgsub
533 $ hg commit -Am '#1 in parent'
533 $ hg commit -Am '#1 in parent'
534 adding .hgsub
534 adding .hgsub
535 $ hg -R sub update -C 1
535 $ hg -R sub update -C 1
536 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
536 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
537 $ hg commit -Am '#2 in parent (but will be rolled back soon)'
537 $ hg commit -Am '#2 in parent (but will be rolled back soon)'
538 $ hg rollback
538 $ hg rollback
539 repository tip rolled back to revision 1 (undo commit)
539 repository tip rolled back to revision 1 (undo commit)
540 working directory now based on revision 1
540 working directory now based on revision 1
541 $ hg status
541 $ hg status
542 M .hgsubstate
542 M .hgsubstate
543 $ hg qnew -u test -d '0 0' checkstate-at-qnew
543 $ hg qnew -u test -d '0 0' checkstate-at-qnew
544 $ hg -R sub parents --template '{node} sub\n'
544 $ hg -R sub parents --template '{node} sub\n'
545 88ac1bef5ed43b689d1d200b59886b675dec474b sub
545 88ac1bef5ed43b689d1d200b59886b675dec474b sub
546 $ cat .hgsubstate
546 $ cat .hgsubstate
547 88ac1bef5ed43b689d1d200b59886b675dec474b sub
547 88ac1bef5ed43b689d1d200b59886b675dec474b sub
548 $ hg diff -c tip
548 $ hg diff -c tip
549 diff -r 4d91eb2fa1d1 -r 1259c112d884 .hgsubstate
549 diff -r 4d91eb2fa1d1 -r 1259c112d884 .hgsubstate
550 --- a/.hgsubstate
550 --- a/.hgsubstate
551 +++ b/.hgsubstate
551 +++ b/.hgsubstate
552 @@ -1,1 +1,1 @@
552 @@ -1,1 +1,1 @@
553 -b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
553 -b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
554 +88ac1bef5ed43b689d1d200b59886b675dec474b sub
554 +88ac1bef5ed43b689d1d200b59886b675dec474b sub
555 $ cat .hg/patches/checkstate-at-qnew
555 $ cat .hg/patches/checkstate-at-qnew
556 # HG changeset patch
556 # HG changeset patch
557 # Parent 4d91eb2fa1d1b22ec513347b9cd06f6b49d470fa
558 # User test
557 # User test
559 # Date 0 0
558 # Date 0 0
559 # Parent 4d91eb2fa1d1b22ec513347b9cd06f6b49d470fa
560
560
561 diff -r 4d91eb2fa1d1 -r 1259c112d884 .hgsubstate
561 diff -r 4d91eb2fa1d1 -r 1259c112d884 .hgsubstate
562 --- a/.hgsubstate
562 --- a/.hgsubstate
563 +++ b/.hgsubstate
563 +++ b/.hgsubstate
564 @@ -1,1 +1,1 @@
564 @@ -1,1 +1,1 @@
565 -b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
565 -b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
566 +88ac1bef5ed43b689d1d200b59886b675dec474b sub
566 +88ac1bef5ed43b689d1d200b59886b675dec474b sub
567 $ hg parents --template '{files}\n'
567 $ hg parents --template '{files}\n'
568 .hgsubstate
568 .hgsubstate
569
569
570 check whether qrefresh not including ".hgsubstate" explicitly causes
570 check whether qrefresh not including ".hgsubstate" explicitly causes
571 as same result (in node hash) as one including it.
571 as same result (in node hash) as one including it.
572
572
573 $ hg update -C -q 0
573 $ hg update -C -q 0
574 $ hg qpop -a -q
574 $ hg qpop -a -q
575 patch queue now empty
575 patch queue now empty
576 $ hg qnew -u test -d '0 0' add-hgsub-at-qrefresh
576 $ hg qnew -u test -d '0 0' add-hgsub-at-qrefresh
577 $ echo 'sub = sub' > .hgsub
577 $ echo 'sub = sub' > .hgsub
578 $ echo > .hgsubstate
578 $ echo > .hgsubstate
579 $ hg add .hgsub .hgsubstate
579 $ hg add .hgsub .hgsubstate
580 $ hg qrefresh -u test -d '0 0'
580 $ hg qrefresh -u test -d '0 0'
581 $ hg parents --template '{node}\n'
581 $ hg parents --template '{node}\n'
582 7c48c35501aae6770ed9c2517014628615821a8e
582 7c48c35501aae6770ed9c2517014628615821a8e
583 $ hg parents --template '{files}\n'
583 $ hg parents --template '{files}\n'
584 .hgsub .hgsubstate
584 .hgsub .hgsubstate
585
585
586 $ hg qpop -a -q
586 $ hg qpop -a -q
587 patch queue now empty
587 patch queue now empty
588 $ hg qdelete add-hgsub-at-qrefresh
588 $ hg qdelete add-hgsub-at-qrefresh
589 $ hg qnew -u test -d '0 0' add-hgsub-at-qrefresh
589 $ hg qnew -u test -d '0 0' add-hgsub-at-qrefresh
590 $ echo 'sub = sub' > .hgsub
590 $ echo 'sub = sub' > .hgsub
591 $ hg add .hgsub
591 $ hg add .hgsub
592 $ rm -f .hgsubstate
592 $ rm -f .hgsubstate
593 $ hg qrefresh -u test -d '0 0'
593 $ hg qrefresh -u test -d '0 0'
594 $ hg parents --template '{node}\n'
594 $ hg parents --template '{node}\n'
595 7c48c35501aae6770ed9c2517014628615821a8e
595 7c48c35501aae6770ed9c2517014628615821a8e
596 $ hg parents --template '{files}\n'
596 $ hg parents --template '{files}\n'
597 .hgsub .hgsubstate
597 .hgsub .hgsubstate
598
598
599 $ cd ..
599 $ cd ..
600
600
601 $ cd ..
601 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now