##// END OF EJS Templates
record: check that we are not committing a merge before patch selection...
Nicolas Dumazet -
r11237:feb2a58f stable
parent child Browse files
Show More
@@ -1,552 +1,559
1 # record.py
1 # record.py
2 #
2 #
3 # Copyright 2007 Bryan O'Sullivan <bos@serpentine.com>
3 # Copyright 2007 Bryan O'Sullivan <bos@serpentine.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 '''commands to interactively select changes for commit/qrefresh'''
8 '''commands to interactively select changes for commit/qrefresh'''
9
9
10 from mercurial.i18n import gettext, _
10 from mercurial.i18n import gettext, _
11 from mercurial import cmdutil, commands, extensions, hg, mdiff, patch
11 from mercurial import cmdutil, commands, extensions, hg, mdiff, patch
12 from mercurial import util
12 from mercurial import util
13 import copy, cStringIO, errno, operator, os, re, tempfile
13 import copy, cStringIO, errno, operator, os, re, tempfile
14
14
15 lines_re = re.compile(r'@@ -(\d+),(\d+) \+(\d+),(\d+) @@\s*(.*)')
15 lines_re = re.compile(r'@@ -(\d+),(\d+) \+(\d+),(\d+) @@\s*(.*)')
16
16
17 def scanpatch(fp):
17 def scanpatch(fp):
18 """like patch.iterhunks, but yield different events
18 """like patch.iterhunks, but yield different events
19
19
20 - ('file', [header_lines + fromfile + tofile])
20 - ('file', [header_lines + fromfile + tofile])
21 - ('context', [context_lines])
21 - ('context', [context_lines])
22 - ('hunk', [hunk_lines])
22 - ('hunk', [hunk_lines])
23 - ('range', (-start,len, +start,len, diffp))
23 - ('range', (-start,len, +start,len, diffp))
24 """
24 """
25 lr = patch.linereader(fp)
25 lr = patch.linereader(fp)
26
26
27 def scanwhile(first, p):
27 def scanwhile(first, p):
28 """scan lr while predicate holds"""
28 """scan lr while predicate holds"""
29 lines = [first]
29 lines = [first]
30 while True:
30 while True:
31 line = lr.readline()
31 line = lr.readline()
32 if not line:
32 if not line:
33 break
33 break
34 if p(line):
34 if p(line):
35 lines.append(line)
35 lines.append(line)
36 else:
36 else:
37 lr.push(line)
37 lr.push(line)
38 break
38 break
39 return lines
39 return lines
40
40
41 while True:
41 while True:
42 line = lr.readline()
42 line = lr.readline()
43 if not line:
43 if not line:
44 break
44 break
45 if line.startswith('diff --git a/'):
45 if line.startswith('diff --git a/'):
46 def notheader(line):
46 def notheader(line):
47 s = line.split(None, 1)
47 s = line.split(None, 1)
48 return not s or s[0] not in ('---', 'diff')
48 return not s or s[0] not in ('---', 'diff')
49 header = scanwhile(line, notheader)
49 header = scanwhile(line, notheader)
50 fromfile = lr.readline()
50 fromfile = lr.readline()
51 if fromfile.startswith('---'):
51 if fromfile.startswith('---'):
52 tofile = lr.readline()
52 tofile = lr.readline()
53 header += [fromfile, tofile]
53 header += [fromfile, tofile]
54 else:
54 else:
55 lr.push(fromfile)
55 lr.push(fromfile)
56 yield 'file', header
56 yield 'file', header
57 elif line[0] == ' ':
57 elif line[0] == ' ':
58 yield 'context', scanwhile(line, lambda l: l[0] in ' \\')
58 yield 'context', scanwhile(line, lambda l: l[0] in ' \\')
59 elif line[0] in '-+':
59 elif line[0] in '-+':
60 yield 'hunk', scanwhile(line, lambda l: l[0] in '-+\\')
60 yield 'hunk', scanwhile(line, lambda l: l[0] in '-+\\')
61 else:
61 else:
62 m = lines_re.match(line)
62 m = lines_re.match(line)
63 if m:
63 if m:
64 yield 'range', m.groups()
64 yield 'range', m.groups()
65 else:
65 else:
66 raise patch.PatchError('unknown patch content: %r' % line)
66 raise patch.PatchError('unknown patch content: %r' % line)
67
67
68 class header(object):
68 class header(object):
69 """patch header
69 """patch header
70
70
71 XXX shoudn't we move this to mercurial/patch.py ?
71 XXX shoudn't we move this to mercurial/patch.py ?
72 """
72 """
73 diff_re = re.compile('diff --git a/(.*) b/(.*)$')
73 diff_re = re.compile('diff --git a/(.*) b/(.*)$')
74 allhunks_re = re.compile('(?:index|new file|deleted file) ')
74 allhunks_re = re.compile('(?:index|new file|deleted file) ')
75 pretty_re = re.compile('(?:new file|deleted file) ')
75 pretty_re = re.compile('(?:new file|deleted file) ')
76 special_re = re.compile('(?:index|new|deleted|copy|rename) ')
76 special_re = re.compile('(?:index|new|deleted|copy|rename) ')
77
77
78 def __init__(self, header):
78 def __init__(self, header):
79 self.header = header
79 self.header = header
80 self.hunks = []
80 self.hunks = []
81
81
82 def binary(self):
82 def binary(self):
83 for h in self.header:
83 for h in self.header:
84 if h.startswith('index '):
84 if h.startswith('index '):
85 return True
85 return True
86
86
87 def pretty(self, fp):
87 def pretty(self, fp):
88 for h in self.header:
88 for h in self.header:
89 if h.startswith('index '):
89 if h.startswith('index '):
90 fp.write(_('this modifies a binary file (all or nothing)\n'))
90 fp.write(_('this modifies a binary file (all or nothing)\n'))
91 break
91 break
92 if self.pretty_re.match(h):
92 if self.pretty_re.match(h):
93 fp.write(h)
93 fp.write(h)
94 if self.binary():
94 if self.binary():
95 fp.write(_('this is a binary file\n'))
95 fp.write(_('this is a binary file\n'))
96 break
96 break
97 if h.startswith('---'):
97 if h.startswith('---'):
98 fp.write(_('%d hunks, %d lines changed\n') %
98 fp.write(_('%d hunks, %d lines changed\n') %
99 (len(self.hunks),
99 (len(self.hunks),
100 sum([h.added + h.removed for h in self.hunks])))
100 sum([h.added + h.removed for h in self.hunks])))
101 break
101 break
102 fp.write(h)
102 fp.write(h)
103
103
104 def write(self, fp):
104 def write(self, fp):
105 fp.write(''.join(self.header))
105 fp.write(''.join(self.header))
106
106
107 def allhunks(self):
107 def allhunks(self):
108 for h in self.header:
108 for h in self.header:
109 if self.allhunks_re.match(h):
109 if self.allhunks_re.match(h):
110 return True
110 return True
111
111
112 def files(self):
112 def files(self):
113 fromfile, tofile = self.diff_re.match(self.header[0]).groups()
113 fromfile, tofile = self.diff_re.match(self.header[0]).groups()
114 if fromfile == tofile:
114 if fromfile == tofile:
115 return [fromfile]
115 return [fromfile]
116 return [fromfile, tofile]
116 return [fromfile, tofile]
117
117
118 def filename(self):
118 def filename(self):
119 return self.files()[-1]
119 return self.files()[-1]
120
120
121 def __repr__(self):
121 def __repr__(self):
122 return '<header %s>' % (' '.join(map(repr, self.files())))
122 return '<header %s>' % (' '.join(map(repr, self.files())))
123
123
124 def special(self):
124 def special(self):
125 for h in self.header:
125 for h in self.header:
126 if self.special_re.match(h):
126 if self.special_re.match(h):
127 return True
127 return True
128
128
129 def countchanges(hunk):
129 def countchanges(hunk):
130 """hunk -> (n+,n-)"""
130 """hunk -> (n+,n-)"""
131 add = len([h for h in hunk if h[0] == '+'])
131 add = len([h for h in hunk if h[0] == '+'])
132 rem = len([h for h in hunk if h[0] == '-'])
132 rem = len([h for h in hunk if h[0] == '-'])
133 return add, rem
133 return add, rem
134
134
135 class hunk(object):
135 class hunk(object):
136 """patch hunk
136 """patch hunk
137
137
138 XXX shouldn't we merge this with patch.hunk ?
138 XXX shouldn't we merge this with patch.hunk ?
139 """
139 """
140 maxcontext = 3
140 maxcontext = 3
141
141
142 def __init__(self, header, fromline, toline, proc, before, hunk, after):
142 def __init__(self, header, fromline, toline, proc, before, hunk, after):
143 def trimcontext(number, lines):
143 def trimcontext(number, lines):
144 delta = len(lines) - self.maxcontext
144 delta = len(lines) - self.maxcontext
145 if False and delta > 0:
145 if False and delta > 0:
146 return number + delta, lines[:self.maxcontext]
146 return number + delta, lines[:self.maxcontext]
147 return number, lines
147 return number, lines
148
148
149 self.header = header
149 self.header = header
150 self.fromline, self.before = trimcontext(fromline, before)
150 self.fromline, self.before = trimcontext(fromline, before)
151 self.toline, self.after = trimcontext(toline, after)
151 self.toline, self.after = trimcontext(toline, after)
152 self.proc = proc
152 self.proc = proc
153 self.hunk = hunk
153 self.hunk = hunk
154 self.added, self.removed = countchanges(self.hunk)
154 self.added, self.removed = countchanges(self.hunk)
155
155
156 def write(self, fp):
156 def write(self, fp):
157 delta = len(self.before) + len(self.after)
157 delta = len(self.before) + len(self.after)
158 if self.after and self.after[-1] == '\\ No newline at end of file\n':
158 if self.after and self.after[-1] == '\\ No newline at end of file\n':
159 delta -= 1
159 delta -= 1
160 fromlen = delta + self.removed
160 fromlen = delta + self.removed
161 tolen = delta + self.added
161 tolen = delta + self.added
162 fp.write('@@ -%d,%d +%d,%d @@%s\n' %
162 fp.write('@@ -%d,%d +%d,%d @@%s\n' %
163 (self.fromline, fromlen, self.toline, tolen,
163 (self.fromline, fromlen, self.toline, tolen,
164 self.proc and (' ' + self.proc)))
164 self.proc and (' ' + self.proc)))
165 fp.write(''.join(self.before + self.hunk + self.after))
165 fp.write(''.join(self.before + self.hunk + self.after))
166
166
167 pretty = write
167 pretty = write
168
168
169 def filename(self):
169 def filename(self):
170 return self.header.filename()
170 return self.header.filename()
171
171
172 def __repr__(self):
172 def __repr__(self):
173 return '<hunk %r@%d>' % (self.filename(), self.fromline)
173 return '<hunk %r@%d>' % (self.filename(), self.fromline)
174
174
175 def parsepatch(fp):
175 def parsepatch(fp):
176 """patch -> [] of hunks """
176 """patch -> [] of hunks """
177 class parser(object):
177 class parser(object):
178 """patch parsing state machine"""
178 """patch parsing state machine"""
179 def __init__(self):
179 def __init__(self):
180 self.fromline = 0
180 self.fromline = 0
181 self.toline = 0
181 self.toline = 0
182 self.proc = ''
182 self.proc = ''
183 self.header = None
183 self.header = None
184 self.context = []
184 self.context = []
185 self.before = []
185 self.before = []
186 self.hunk = []
186 self.hunk = []
187 self.stream = []
187 self.stream = []
188
188
189 def addrange(self, (fromstart, fromend, tostart, toend, proc)):
189 def addrange(self, (fromstart, fromend, tostart, toend, proc)):
190 self.fromline = int(fromstart)
190 self.fromline = int(fromstart)
191 self.toline = int(tostart)
191 self.toline = int(tostart)
192 self.proc = proc
192 self.proc = proc
193
193
194 def addcontext(self, context):
194 def addcontext(self, context):
195 if self.hunk:
195 if self.hunk:
196 h = hunk(self.header, self.fromline, self.toline, self.proc,
196 h = hunk(self.header, self.fromline, self.toline, self.proc,
197 self.before, self.hunk, context)
197 self.before, self.hunk, context)
198 self.header.hunks.append(h)
198 self.header.hunks.append(h)
199 self.stream.append(h)
199 self.stream.append(h)
200 self.fromline += len(self.before) + h.removed
200 self.fromline += len(self.before) + h.removed
201 self.toline += len(self.before) + h.added
201 self.toline += len(self.before) + h.added
202 self.before = []
202 self.before = []
203 self.hunk = []
203 self.hunk = []
204 self.proc = ''
204 self.proc = ''
205 self.context = context
205 self.context = context
206
206
207 def addhunk(self, hunk):
207 def addhunk(self, hunk):
208 if self.context:
208 if self.context:
209 self.before = self.context
209 self.before = self.context
210 self.context = []
210 self.context = []
211 self.hunk = hunk
211 self.hunk = hunk
212
212
213 def newfile(self, hdr):
213 def newfile(self, hdr):
214 self.addcontext([])
214 self.addcontext([])
215 h = header(hdr)
215 h = header(hdr)
216 self.stream.append(h)
216 self.stream.append(h)
217 self.header = h
217 self.header = h
218
218
219 def finished(self):
219 def finished(self):
220 self.addcontext([])
220 self.addcontext([])
221 return self.stream
221 return self.stream
222
222
223 transitions = {
223 transitions = {
224 'file': {'context': addcontext,
224 'file': {'context': addcontext,
225 'file': newfile,
225 'file': newfile,
226 'hunk': addhunk,
226 'hunk': addhunk,
227 'range': addrange},
227 'range': addrange},
228 'context': {'file': newfile,
228 'context': {'file': newfile,
229 'hunk': addhunk,
229 'hunk': addhunk,
230 'range': addrange},
230 'range': addrange},
231 'hunk': {'context': addcontext,
231 'hunk': {'context': addcontext,
232 'file': newfile,
232 'file': newfile,
233 'range': addrange},
233 'range': addrange},
234 'range': {'context': addcontext,
234 'range': {'context': addcontext,
235 'hunk': addhunk},
235 'hunk': addhunk},
236 }
236 }
237
237
238 p = parser()
238 p = parser()
239
239
240 state = 'context'
240 state = 'context'
241 for newstate, data in scanpatch(fp):
241 for newstate, data in scanpatch(fp):
242 try:
242 try:
243 p.transitions[state][newstate](p, data)
243 p.transitions[state][newstate](p, data)
244 except KeyError:
244 except KeyError:
245 raise patch.PatchError('unhandled transition: %s -> %s' %
245 raise patch.PatchError('unhandled transition: %s -> %s' %
246 (state, newstate))
246 (state, newstate))
247 state = newstate
247 state = newstate
248 return p.finished()
248 return p.finished()
249
249
250 def filterpatch(ui, chunks):
250 def filterpatch(ui, chunks):
251 """Interactively filter patch chunks into applied-only chunks"""
251 """Interactively filter patch chunks into applied-only chunks"""
252 chunks = list(chunks)
252 chunks = list(chunks)
253 chunks.reverse()
253 chunks.reverse()
254 seen = set()
254 seen = set()
255 def consumefile():
255 def consumefile():
256 """fetch next portion from chunks until a 'header' is seen
256 """fetch next portion from chunks until a 'header' is seen
257 NB: header == new-file mark
257 NB: header == new-file mark
258 """
258 """
259 consumed = []
259 consumed = []
260 while chunks:
260 while chunks:
261 if isinstance(chunks[-1], header):
261 if isinstance(chunks[-1], header):
262 break
262 break
263 else:
263 else:
264 consumed.append(chunks.pop())
264 consumed.append(chunks.pop())
265 return consumed
265 return consumed
266
266
267 resp_all = [None] # this two are changed from inside prompt,
267 resp_all = [None] # this two are changed from inside prompt,
268 resp_file = [None] # so can't be usual variables
268 resp_file = [None] # so can't be usual variables
269 applied = {} # 'filename' -> [] of chunks
269 applied = {} # 'filename' -> [] of chunks
270 def prompt(query):
270 def prompt(query):
271 """prompt query, and process base inputs
271 """prompt query, and process base inputs
272
272
273 - y/n for the rest of file
273 - y/n for the rest of file
274 - y/n for the rest
274 - y/n for the rest
275 - ? (help)
275 - ? (help)
276 - q (quit)
276 - q (quit)
277
277
278 Returns True/False and sets reps_all and resp_file as
278 Returns True/False and sets reps_all and resp_file as
279 appropriate.
279 appropriate.
280 """
280 """
281 if resp_all[0] is not None:
281 if resp_all[0] is not None:
282 return resp_all[0]
282 return resp_all[0]
283 if resp_file[0] is not None:
283 if resp_file[0] is not None:
284 return resp_file[0]
284 return resp_file[0]
285 while True:
285 while True:
286 resps = _('[Ynsfdaq?]')
286 resps = _('[Ynsfdaq?]')
287 choices = (_('&Yes, record this change'),
287 choices = (_('&Yes, record this change'),
288 _('&No, skip this change'),
288 _('&No, skip this change'),
289 _('&Skip remaining changes to this file'),
289 _('&Skip remaining changes to this file'),
290 _('Record remaining changes to this &file'),
290 _('Record remaining changes to this &file'),
291 _('&Done, skip remaining changes and files'),
291 _('&Done, skip remaining changes and files'),
292 _('Record &all changes to all remaining files'),
292 _('Record &all changes to all remaining files'),
293 _('&Quit, recording no changes'),
293 _('&Quit, recording no changes'),
294 _('&?'))
294 _('&?'))
295 r = ui.promptchoice("%s %s" % (query, resps), choices)
295 r = ui.promptchoice("%s %s" % (query, resps), choices)
296 if r == 7: # ?
296 if r == 7: # ?
297 doc = gettext(record.__doc__)
297 doc = gettext(record.__doc__)
298 c = doc.find('::') + 2
298 c = doc.find('::') + 2
299 for l in doc[c:].splitlines():
299 for l in doc[c:].splitlines():
300 if l.startswith(' '):
300 if l.startswith(' '):
301 ui.write(l.strip(), '\n')
301 ui.write(l.strip(), '\n')
302 continue
302 continue
303 elif r == 0: # yes
303 elif r == 0: # yes
304 ret = True
304 ret = True
305 elif r == 1: # no
305 elif r == 1: # no
306 ret = False
306 ret = False
307 elif r == 2: # Skip
307 elif r == 2: # Skip
308 ret = resp_file[0] = False
308 ret = resp_file[0] = False
309 elif r == 3: # file (Record remaining)
309 elif r == 3: # file (Record remaining)
310 ret = resp_file[0] = True
310 ret = resp_file[0] = True
311 elif r == 4: # done, skip remaining
311 elif r == 4: # done, skip remaining
312 ret = resp_all[0] = False
312 ret = resp_all[0] = False
313 elif r == 5: # all
313 elif r == 5: # all
314 ret = resp_all[0] = True
314 ret = resp_all[0] = True
315 elif r == 6: # quit
315 elif r == 6: # quit
316 raise util.Abort(_('user quit'))
316 raise util.Abort(_('user quit'))
317 return ret
317 return ret
318 pos, total = 0, len(chunks) - 1
318 pos, total = 0, len(chunks) - 1
319 while chunks:
319 while chunks:
320 pos = total - len(chunks) + 1
320 pos = total - len(chunks) + 1
321 chunk = chunks.pop()
321 chunk = chunks.pop()
322 if isinstance(chunk, header):
322 if isinstance(chunk, header):
323 # new-file mark
323 # new-file mark
324 resp_file = [None]
324 resp_file = [None]
325 fixoffset = 0
325 fixoffset = 0
326 hdr = ''.join(chunk.header)
326 hdr = ''.join(chunk.header)
327 if hdr in seen:
327 if hdr in seen:
328 consumefile()
328 consumefile()
329 continue
329 continue
330 seen.add(hdr)
330 seen.add(hdr)
331 if resp_all[0] is None:
331 if resp_all[0] is None:
332 chunk.pretty(ui)
332 chunk.pretty(ui)
333 r = prompt(_('examine changes to %s?') %
333 r = prompt(_('examine changes to %s?') %
334 _(' and ').join(map(repr, chunk.files())))
334 _(' and ').join(map(repr, chunk.files())))
335 if r:
335 if r:
336 applied[chunk.filename()] = [chunk]
336 applied[chunk.filename()] = [chunk]
337 if chunk.allhunks():
337 if chunk.allhunks():
338 applied[chunk.filename()] += consumefile()
338 applied[chunk.filename()] += consumefile()
339 else:
339 else:
340 consumefile()
340 consumefile()
341 else:
341 else:
342 # new hunk
342 # new hunk
343 if resp_file[0] is None and resp_all[0] is None:
343 if resp_file[0] is None and resp_all[0] is None:
344 chunk.pretty(ui)
344 chunk.pretty(ui)
345 r = total == 1 and prompt(_('record this change to %r?') %
345 r = total == 1 and prompt(_('record this change to %r?') %
346 chunk.filename()) \
346 chunk.filename()) \
347 or prompt(_('record change %d/%d to %r?') %
347 or prompt(_('record change %d/%d to %r?') %
348 (pos, total, chunk.filename()))
348 (pos, total, chunk.filename()))
349 if r:
349 if r:
350 if fixoffset:
350 if fixoffset:
351 chunk = copy.copy(chunk)
351 chunk = copy.copy(chunk)
352 chunk.toline += fixoffset
352 chunk.toline += fixoffset
353 applied[chunk.filename()].append(chunk)
353 applied[chunk.filename()].append(chunk)
354 else:
354 else:
355 fixoffset += chunk.removed - chunk.added
355 fixoffset += chunk.removed - chunk.added
356 return reduce(operator.add, [h for h in applied.itervalues()
356 return reduce(operator.add, [h for h in applied.itervalues()
357 if h[0].special() or len(h) > 1], [])
357 if h[0].special() or len(h) > 1], [])
358
358
359 def record(ui, repo, *pats, **opts):
359 def record(ui, repo, *pats, **opts):
360 '''interactively select changes to commit
360 '''interactively select changes to commit
361
361
362 If a list of files is omitted, all changes reported by "hg status"
362 If a list of files is omitted, all changes reported by "hg status"
363 will be candidates for recording.
363 will be candidates for recording.
364
364
365 See 'hg help dates' for a list of formats valid for -d/--date.
365 See 'hg help dates' for a list of formats valid for -d/--date.
366
366
367 You will be prompted for whether to record changes to each
367 You will be prompted for whether to record changes to each
368 modified file, and for files with multiple changes, for each
368 modified file, and for files with multiple changes, for each
369 change to use. For each query, the following responses are
369 change to use. For each query, the following responses are
370 possible::
370 possible::
371
371
372 y - record this change
372 y - record this change
373 n - skip this change
373 n - skip this change
374
374
375 s - skip remaining changes to this file
375 s - skip remaining changes to this file
376 f - record remaining changes to this file
376 f - record remaining changes to this file
377
377
378 d - done, skip remaining changes and files
378 d - done, skip remaining changes and files
379 a - record all changes to all remaining files
379 a - record all changes to all remaining files
380 q - quit, recording no changes
380 q - quit, recording no changes
381
381
382 ? - display help'''
382 ? - display help
383
384 This command is not available when committing a merge.'''
383
385
384 dorecord(ui, repo, commands.commit, *pats, **opts)
386 dorecord(ui, repo, commands.commit, *pats, **opts)
385
387
386
388
387 def qrecord(ui, repo, patch, *pats, **opts):
389 def qrecord(ui, repo, patch, *pats, **opts):
388 '''interactively record a new patch
390 '''interactively record a new patch
389
391
390 See 'hg help qnew' & 'hg help record' for more information and
392 See 'hg help qnew' & 'hg help record' for more information and
391 usage.
393 usage.
392 '''
394 '''
393
395
394 try:
396 try:
395 mq = extensions.find('mq')
397 mq = extensions.find('mq')
396 except KeyError:
398 except KeyError:
397 raise util.Abort(_("'mq' extension not loaded"))
399 raise util.Abort(_("'mq' extension not loaded"))
398
400
399 def committomq(ui, repo, *pats, **opts):
401 def committomq(ui, repo, *pats, **opts):
400 mq.new(ui, repo, patch, *pats, **opts)
402 mq.new(ui, repo, patch, *pats, **opts)
401
403
402 opts = opts.copy()
404 opts = opts.copy()
403 opts['force'] = True # always 'qnew -f'
405 opts['force'] = True # always 'qnew -f'
404 dorecord(ui, repo, committomq, *pats, **opts)
406 dorecord(ui, repo, committomq, *pats, **opts)
405
407
406
408
407 def dorecord(ui, repo, commitfunc, *pats, **opts):
409 def dorecord(ui, repo, commitfunc, *pats, **opts):
408 if not ui.interactive():
410 if not ui.interactive():
409 raise util.Abort(_('running non-interactively, use commit instead'))
411 raise util.Abort(_('running non-interactively, use commit instead'))
410
412
411 def recordfunc(ui, repo, message, match, opts):
413 def recordfunc(ui, repo, message, match, opts):
412 """This is generic record driver.
414 """This is generic record driver.
413
415
414 Its job is to interactively filter local changes, and accordingly
416 Its job is to interactively filter local changes, and accordingly
415 prepare working dir into a state, where the job can be delegated to
417 prepare working dir into a state, where the job can be delegated to
416 non-interactive commit command such as 'commit' or 'qrefresh'.
418 non-interactive commit command such as 'commit' or 'qrefresh'.
417
419
418 After the actual job is done by non-interactive command, working dir
420 After the actual job is done by non-interactive command, working dir
419 state is restored to original.
421 state is restored to original.
420
422
421 In the end we'll record interesting changes, and everything else will be
423 In the end we'll record interesting changes, and everything else will be
422 left in place, so the user can continue his work.
424 left in place, so the user can continue his work.
423 """
425 """
424
426
427 merge = len(repo[None].parents()) > 1
428 if merge:
429 raise util.Abort(_('cannot partially commit a merge '
430 '(use hg commit instead)'))
431
425 changes = repo.status(match=match)[:3]
432 changes = repo.status(match=match)[:3]
426 diffopts = mdiff.diffopts(git=True, nodates=True)
433 diffopts = mdiff.diffopts(git=True, nodates=True)
427 chunks = patch.diff(repo, changes=changes, opts=diffopts)
434 chunks = patch.diff(repo, changes=changes, opts=diffopts)
428 fp = cStringIO.StringIO()
435 fp = cStringIO.StringIO()
429 fp.write(''.join(chunks))
436 fp.write(''.join(chunks))
430 fp.seek(0)
437 fp.seek(0)
431
438
432 # 1. filter patch, so we have intending-to apply subset of it
439 # 1. filter patch, so we have intending-to apply subset of it
433 chunks = filterpatch(ui, parsepatch(fp))
440 chunks = filterpatch(ui, parsepatch(fp))
434 del fp
441 del fp
435
442
436 contenders = set()
443 contenders = set()
437 for h in chunks:
444 for h in chunks:
438 try:
445 try:
439 contenders.update(set(h.files()))
446 contenders.update(set(h.files()))
440 except AttributeError:
447 except AttributeError:
441 pass
448 pass
442
449
443 changed = changes[0] + changes[1] + changes[2]
450 changed = changes[0] + changes[1] + changes[2]
444 newfiles = [f for f in changed if f in contenders]
451 newfiles = [f for f in changed if f in contenders]
445 if not newfiles:
452 if not newfiles:
446 ui.status(_('no changes to record\n'))
453 ui.status(_('no changes to record\n'))
447 return 0
454 return 0
448
455
449 modified = set(changes[0])
456 modified = set(changes[0])
450
457
451 # 2. backup changed files, so we can restore them in the end
458 # 2. backup changed files, so we can restore them in the end
452 backups = {}
459 backups = {}
453 backupdir = repo.join('record-backups')
460 backupdir = repo.join('record-backups')
454 try:
461 try:
455 os.mkdir(backupdir)
462 os.mkdir(backupdir)
456 except OSError, err:
463 except OSError, err:
457 if err.errno != errno.EEXIST:
464 if err.errno != errno.EEXIST:
458 raise
465 raise
459 try:
466 try:
460 # backup continues
467 # backup continues
461 for f in newfiles:
468 for f in newfiles:
462 if f not in modified:
469 if f not in modified:
463 continue
470 continue
464 fd, tmpname = tempfile.mkstemp(prefix=f.replace('/', '_')+'.',
471 fd, tmpname = tempfile.mkstemp(prefix=f.replace('/', '_')+'.',
465 dir=backupdir)
472 dir=backupdir)
466 os.close(fd)
473 os.close(fd)
467 ui.debug('backup %r as %r\n' % (f, tmpname))
474 ui.debug('backup %r as %r\n' % (f, tmpname))
468 util.copyfile(repo.wjoin(f), tmpname)
475 util.copyfile(repo.wjoin(f), tmpname)
469 backups[f] = tmpname
476 backups[f] = tmpname
470
477
471 fp = cStringIO.StringIO()
478 fp = cStringIO.StringIO()
472 for c in chunks:
479 for c in chunks:
473 if c.filename() in backups:
480 if c.filename() in backups:
474 c.write(fp)
481 c.write(fp)
475 dopatch = fp.tell()
482 dopatch = fp.tell()
476 fp.seek(0)
483 fp.seek(0)
477
484
478 # 3a. apply filtered patch to clean repo (clean)
485 # 3a. apply filtered patch to clean repo (clean)
479 if backups:
486 if backups:
480 hg.revert(repo, repo.dirstate.parents()[0], backups.has_key)
487 hg.revert(repo, repo.dirstate.parents()[0], backups.has_key)
481
488
482 # 3b. (apply)
489 # 3b. (apply)
483 if dopatch:
490 if dopatch:
484 try:
491 try:
485 ui.debug('applying patch\n')
492 ui.debug('applying patch\n')
486 ui.debug(fp.getvalue())
493 ui.debug(fp.getvalue())
487 pfiles = {}
494 pfiles = {}
488 patch.internalpatch(fp, ui, 1, repo.root, files=pfiles,
495 patch.internalpatch(fp, ui, 1, repo.root, files=pfiles,
489 eolmode=None)
496 eolmode=None)
490 patch.updatedir(ui, repo, pfiles)
497 patch.updatedir(ui, repo, pfiles)
491 except patch.PatchError, err:
498 except patch.PatchError, err:
492 s = str(err)
499 s = str(err)
493 if s:
500 if s:
494 raise util.Abort(s)
501 raise util.Abort(s)
495 else:
502 else:
496 raise util.Abort(_('patch failed to apply'))
503 raise util.Abort(_('patch failed to apply'))
497 del fp
504 del fp
498
505
499 # 4. We prepared working directory according to filtered patch.
506 # 4. We prepared working directory according to filtered patch.
500 # Now is the time to delegate the job to commit/qrefresh or the like!
507 # Now is the time to delegate the job to commit/qrefresh or the like!
501
508
502 # it is important to first chdir to repo root -- we'll call a
509 # it is important to first chdir to repo root -- we'll call a
503 # highlevel command with list of pathnames relative to repo root
510 # highlevel command with list of pathnames relative to repo root
504 cwd = os.getcwd()
511 cwd = os.getcwd()
505 os.chdir(repo.root)
512 os.chdir(repo.root)
506 try:
513 try:
507 commitfunc(ui, repo, *newfiles, **opts)
514 commitfunc(ui, repo, *newfiles, **opts)
508 finally:
515 finally:
509 os.chdir(cwd)
516 os.chdir(cwd)
510
517
511 return 0
518 return 0
512 finally:
519 finally:
513 # 5. finally restore backed-up files
520 # 5. finally restore backed-up files
514 try:
521 try:
515 for realname, tmpname in backups.iteritems():
522 for realname, tmpname in backups.iteritems():
516 ui.debug('restoring %r to %r\n' % (tmpname, realname))
523 ui.debug('restoring %r to %r\n' % (tmpname, realname))
517 util.copyfile(tmpname, repo.wjoin(realname))
524 util.copyfile(tmpname, repo.wjoin(realname))
518 os.unlink(tmpname)
525 os.unlink(tmpname)
519 os.rmdir(backupdir)
526 os.rmdir(backupdir)
520 except OSError:
527 except OSError:
521 pass
528 pass
522 return cmdutil.commit(ui, repo, recordfunc, pats, opts)
529 return cmdutil.commit(ui, repo, recordfunc, pats, opts)
523
530
524 cmdtable = {
531 cmdtable = {
525 "record":
532 "record":
526 (record,
533 (record,
527
534
528 # add commit options
535 # add commit options
529 commands.table['^commit|ci'][1],
536 commands.table['^commit|ci'][1],
530
537
531 _('hg record [OPTION]... [FILE]...')),
538 _('hg record [OPTION]... [FILE]...')),
532 }
539 }
533
540
534
541
535 def uisetup(ui):
542 def uisetup(ui):
536 try:
543 try:
537 mq = extensions.find('mq')
544 mq = extensions.find('mq')
538 except KeyError:
545 except KeyError:
539 return
546 return
540
547
541 qcmdtable = {
548 qcmdtable = {
542 "qrecord":
549 "qrecord":
543 (qrecord,
550 (qrecord,
544
551
545 # add qnew options, except '--force'
552 # add qnew options, except '--force'
546 [opt for opt in mq.cmdtable['qnew'][1] if opt[1] != 'force'],
553 [opt for opt in mq.cmdtable['qnew'][1] if opt[1] != 'force'],
547
554
548 _('hg qrecord [OPTION]... PATCH [FILE]...')),
555 _('hg qrecord [OPTION]... PATCH [FILE]...')),
549 }
556 }
550
557
551 cmdtable.update(qcmdtable)
558 cmdtable.update(qcmdtable)
552
559
@@ -1,318 +1,329
1 #!/bin/sh
1 #!/bin/sh
2
2
3 echo "[ui]" >> $HGRCPATH
3 echo "[ui]" >> $HGRCPATH
4 echo "interactive=true" >> $HGRCPATH
4 echo "interactive=true" >> $HGRCPATH
5 echo "[extensions]" >> $HGRCPATH
5 echo "[extensions]" >> $HGRCPATH
6 echo "record=" >> $HGRCPATH
6 echo "record=" >> $HGRCPATH
7
7
8 echo % help
8 echo % help
9
9
10 hg help record
10 hg help record
11
11
12 hg init a
12 hg init a
13 cd a
13 cd a
14
14
15 echo % select no files
15 echo % select no files
16
16
17 touch empty-rw
17 touch empty-rw
18 hg add empty-rw
18 hg add empty-rw
19 hg record empty-rw<<EOF
19 hg record empty-rw<<EOF
20 n
20 n
21 EOF
21 EOF
22 echo; hg tip -p
22 echo; hg tip -p
23
23
24 echo % select files but no hunks
24 echo % select files but no hunks
25
25
26 hg record empty-rw<<EOF
26 hg record empty-rw<<EOF
27 y
27 y
28 n
28 n
29 EOF
29 EOF
30 echo; hg tip -p
30 echo; hg tip -p
31
31
32 echo % record empty file
32 echo % record empty file
33
33
34 hg record -d '0 0' -m empty empty-rw<<EOF
34 hg record -d '0 0' -m empty empty-rw<<EOF
35 y
35 y
36 y
36 y
37 EOF
37 EOF
38 echo; hg tip -p
38 echo; hg tip -p
39
39
40 echo % rename empty file
40 echo % rename empty file
41
41
42 hg mv empty-rw empty-rename
42 hg mv empty-rw empty-rename
43 hg record -d '1 0' -m rename<<EOF
43 hg record -d '1 0' -m rename<<EOF
44 y
44 y
45 EOF
45 EOF
46 echo; hg tip -p
46 echo; hg tip -p
47
47
48 echo % copy empty file
48 echo % copy empty file
49
49
50 hg cp empty-rename empty-copy
50 hg cp empty-rename empty-copy
51 hg record -d '2 0' -m copy<<EOF
51 hg record -d '2 0' -m copy<<EOF
52 y
52 y
53 EOF
53 EOF
54 echo; hg tip -p
54 echo; hg tip -p
55
55
56 echo % delete empty file
56 echo % delete empty file
57
57
58 hg rm empty-copy
58 hg rm empty-copy
59 hg record -d '3 0' -m delete<<EOF
59 hg record -d '3 0' -m delete<<EOF
60 y
60 y
61 EOF
61 EOF
62 echo; hg tip -p
62 echo; hg tip -p
63
63
64 echo % add binary file
64 echo % add binary file
65
65
66 hg bundle --base -2 tip.bundle
66 hg bundle --base -2 tip.bundle
67 hg add tip.bundle
67 hg add tip.bundle
68 hg record -d '4 0' -m binary<<EOF
68 hg record -d '4 0' -m binary<<EOF
69 y
69 y
70 EOF
70 EOF
71 echo; hg tip -p
71 echo; hg tip -p
72
72
73 echo % change binary file
73 echo % change binary file
74
74
75 hg bundle --base -2 tip.bundle
75 hg bundle --base -2 tip.bundle
76 hg record -d '5 0' -m binary-change<<EOF
76 hg record -d '5 0' -m binary-change<<EOF
77 y
77 y
78 EOF
78 EOF
79 echo; hg tip -p
79 echo; hg tip -p
80
80
81 echo % rename and change binary file
81 echo % rename and change binary file
82
82
83 hg mv tip.bundle top.bundle
83 hg mv tip.bundle top.bundle
84 hg bundle --base -2 top.bundle
84 hg bundle --base -2 top.bundle
85 hg record -d '6 0' -m binary-change-rename<<EOF
85 hg record -d '6 0' -m binary-change-rename<<EOF
86 y
86 y
87 EOF
87 EOF
88 echo; hg tip -p
88 echo; hg tip -p
89
89
90 echo % add plain file
90 echo % add plain file
91
91
92 for i in 1 2 3 4 5 6 7 8 9 10; do
92 for i in 1 2 3 4 5 6 7 8 9 10; do
93 echo $i >> plain
93 echo $i >> plain
94 done
94 done
95
95
96 hg add plain
96 hg add plain
97 hg record -d '7 0' -m plain plain<<EOF
97 hg record -d '7 0' -m plain plain<<EOF
98 y
98 y
99 y
99 y
100 EOF
100 EOF
101 echo; hg tip -p
101 echo; hg tip -p
102
102
103 echo % modify end of plain file
103 echo % modify end of plain file
104
104
105 echo 11 >> plain
105 echo 11 >> plain
106 hg record -d '8 0' -m end plain <<EOF
106 hg record -d '8 0' -m end plain <<EOF
107 y
107 y
108 y
108 y
109 EOF
109 EOF
110
110
111 echo % modify end of plain file, no EOL
111 echo % modify end of plain file, no EOL
112
112
113 hg tip --template '{node}' >> plain
113 hg tip --template '{node}' >> plain
114 hg record -d '9 0' -m noeol plain <<EOF
114 hg record -d '9 0' -m noeol plain <<EOF
115 y
115 y
116 y
116 y
117 EOF
117 EOF
118
118
119 echo % modify end of plain file, add EOL
119 echo % modify end of plain file, add EOL
120
120
121 echo >> plain
121 echo >> plain
122 hg record -d '10 0' -m eol plain <<EOF
122 hg record -d '10 0' -m eol plain <<EOF
123 y
123 y
124 y
124 y
125 y
125 y
126 EOF
126 EOF
127
127
128 echo % modify beginning, trim end, record both
128 echo % modify beginning, trim end, record both
129
129
130 rm plain
130 rm plain
131 for i in 2 2 3 4 5 6 7 8 9 10; do
131 for i in 2 2 3 4 5 6 7 8 9 10; do
132 echo $i >> plain
132 echo $i >> plain
133 done
133 done
134
134
135 hg record -d '10 0' -m begin-and-end plain <<EOF
135 hg record -d '10 0' -m begin-and-end plain <<EOF
136 y
136 y
137 y
137 y
138 y
138 y
139 EOF
139 EOF
140 echo; hg tip -p
140 echo; hg tip -p
141
141
142 echo % trim beginning, modify end
142 echo % trim beginning, modify end
143
143
144 rm plain
144 rm plain
145 for i in 4 5 6 7 8 9 10.new; do
145 for i in 4 5 6 7 8 9 10.new; do
146 echo $i >> plain
146 echo $i >> plain
147 done
147 done
148
148
149 echo % record end
149 echo % record end
150
150
151 hg record -d '11 0' -m end-only plain <<EOF
151 hg record -d '11 0' -m end-only plain <<EOF
152 y
152 y
153 n
153 n
154 y
154 y
155 EOF
155 EOF
156 echo; hg tip -p
156 echo; hg tip -p
157
157
158 echo % record beginning
158 echo % record beginning
159
159
160 hg record -d '12 0' -m begin-only plain <<EOF
160 hg record -d '12 0' -m begin-only plain <<EOF
161 y
161 y
162 y
162 y
163 EOF
163 EOF
164 echo; hg tip -p
164 echo; hg tip -p
165
165
166 echo % add to beginning, trim from end
166 echo % add to beginning, trim from end
167
167
168 rm plain
168 rm plain
169 for i in 1 2 3 4 5 6 7 8 9; do
169 for i in 1 2 3 4 5 6 7 8 9; do
170 echo $i >> plain
170 echo $i >> plain
171 done
171 done
172
172
173 echo % record end
173 echo % record end
174
174
175 hg record --traceback -d '13 0' -m end-again plain<<EOF
175 hg record --traceback -d '13 0' -m end-again plain<<EOF
176 y
176 y
177 n
177 n
178 y
178 y
179 EOF
179 EOF
180
180
181 echo % add to beginning, middle, end
181 echo % add to beginning, middle, end
182
182
183 rm plain
183 rm plain
184 for i in 1 2 3 4 5 5.new 5.reallynew 6 7 8 9 10 11; do
184 for i in 1 2 3 4 5 5.new 5.reallynew 6 7 8 9 10 11; do
185 echo $i >> plain
185 echo $i >> plain
186 done
186 done
187
187
188 echo % record beginning, middle
188 echo % record beginning, middle
189
189
190 hg record -d '14 0' -m middle-only plain <<EOF
190 hg record -d '14 0' -m middle-only plain <<EOF
191 y
191 y
192 y
192 y
193 y
193 y
194 n
194 n
195 EOF
195 EOF
196 echo; hg tip -p
196 echo; hg tip -p
197
197
198 echo % record end
198 echo % record end
199
199
200 hg record -d '15 0' -m end-only plain <<EOF
200 hg record -d '15 0' -m end-only plain <<EOF
201 y
201 y
202 y
202 y
203 EOF
203 EOF
204 echo; hg tip -p
204 echo; hg tip -p
205
205
206 mkdir subdir
206 mkdir subdir
207 cd subdir
207 cd subdir
208 echo a > a
208 echo a > a
209 hg ci -d '16 0' -Amsubdir
209 hg ci -d '16 0' -Amsubdir
210
210
211 echo a >> a
211 echo a >> a
212 hg record -d '16 0' -m subdir-change a <<EOF
212 hg record -d '16 0' -m subdir-change a <<EOF
213 y
213 y
214 y
214 y
215 EOF
215 EOF
216 echo; hg tip -p
216 echo; hg tip -p
217
217
218 echo a > f1
218 echo a > f1
219 echo b > f2
219 echo b > f2
220 hg add f1 f2
220 hg add f1 f2
221
221
222 hg ci -mz -d '17 0'
222 hg ci -mz -d '17 0'
223
223
224 echo a >> f1
224 echo a >> f1
225 echo b >> f2
225 echo b >> f2
226
226
227 echo % help, quit
227 echo % help, quit
228
228
229 hg record <<EOF
229 hg record <<EOF
230 ?
230 ?
231 q
231 q
232 EOF
232 EOF
233
233
234 echo % skip
234 echo % skip
235
235
236 hg record <<EOF
236 hg record <<EOF
237 s
237 s
238 EOF
238 EOF
239
239
240 echo % no
240 echo % no
241
241
242 hg record <<EOF
242 hg record <<EOF
243 n
243 n
244 EOF
244 EOF
245
245
246 echo % f, quit
246 echo % f, quit
247
247
248 hg record <<EOF
248 hg record <<EOF
249 f
249 f
250 q
250 q
251 EOF
251 EOF
252
252
253 echo % s, all
253 echo % s, all
254
254
255 hg record -d '18 0' -mx <<EOF
255 hg record -d '18 0' -mx <<EOF
256 s
256 s
257 a
257 a
258 EOF
258 EOF
259 echo; hg tip -p
259 echo; hg tip -p
260
260
261 echo % f
261 echo % f
262
262
263 hg record -d '19 0' -my <<EOF
263 hg record -d '19 0' -my <<EOF
264 f
264 f
265 EOF
265 EOF
266 echo; hg tip -p
266 echo; hg tip -p
267
267
268 echo % preserve chmod +x
268 echo % preserve chmod +x
269
269
270 chmod +x f1
270 chmod +x f1
271 echo a >> f1
271 echo a >> f1
272 hg record -d '20 0' -mz <<EOF
272 hg record -d '20 0' -mz <<EOF
273 y
273 y
274 y
274 y
275 y
275 y
276 EOF
276 EOF
277 echo; hg tip --config diff.git=True -p
277 echo; hg tip --config diff.git=True -p
278
278
279 echo % preserve execute permission on original
279 echo % preserve execute permission on original
280
280
281 echo b >> f1
281 echo b >> f1
282 hg record -d '21 0' -maa <<EOF
282 hg record -d '21 0' -maa <<EOF
283 y
283 y
284 y
284 y
285 y
285 y
286 EOF
286 EOF
287 echo; hg tip --config diff.git=True -p
287 echo; hg tip --config diff.git=True -p
288
288
289 echo % preserve chmod -x
289 echo % preserve chmod -x
290
290
291 chmod -x f1
291 chmod -x f1
292 echo c >> f1
292 echo c >> f1
293 hg record -d '22 0' -mab <<EOF
293 hg record -d '22 0' -mab <<EOF
294 y
294 y
295 y
295 y
296 y
296 y
297 EOF
297 EOF
298 echo; hg tip --config diff.git=True -p
298 echo; hg tip --config diff.git=True -p
299
299
300 cd ..
301
302 echo % abort early when a merge is in progress
303 hg up 4
304 touch iwillmergethat
305 hg add iwillmergethat
306 hg branch thatbranch
307 hg ci -m'new head'
308 hg up default
309 hg merge thatbranch
310 echo; hg record -m'will abort'
311 hg up -C
300
312
301 echo % with win32ext
313 echo % with win32ext
302 cd ..
303 echo '[extensions]' >> .hg/hgrc
314 echo '[extensions]' >> .hg/hgrc
304 echo 'win32text = ' >> .hg/hgrc
315 echo 'win32text = ' >> .hg/hgrc
305 echo '[decode]' >> .hg/hgrc
316 echo '[decode]' >> .hg/hgrc
306 echo '** = cleverdecode:' >> .hg/hgrc
317 echo '** = cleverdecode:' >> .hg/hgrc
307 echo '[encode]' >> .hg/hgrc
318 echo '[encode]' >> .hg/hgrc
308 echo '** = cleverencode:' >> .hg/hgrc
319 echo '** = cleverencode:' >> .hg/hgrc
309 echo '[patch]' >> .hg/hgrc
320 echo '[patch]' >> .hg/hgrc
310 echo 'eol = crlf' >> .hg/hgrc
321 echo 'eol = crlf' >> .hg/hgrc
311
322
312 echo d >> subdir/f1
323 echo d >> subdir/f1
313 hg record -d '23 0' -mw1 <<EOF
324 hg record -d '23 0' -mw1 <<EOF
314 y
325 y
315 y
326 y
316 EOF
327 EOF
317 echo; hg tip -p
328 echo; hg tip -p
318
329
@@ -1,595 +1,608
1 % help
1 % help
2 hg record [OPTION]... [FILE]...
2 hg record [OPTION]... [FILE]...
3
3
4 interactively select changes to commit
4 interactively select changes to commit
5
5
6 If a list of files is omitted, all changes reported by "hg status" will be
6 If a list of files is omitted, all changes reported by "hg status" will be
7 candidates for recording.
7 candidates for recording.
8
8
9 See 'hg help dates' for a list of formats valid for -d/--date.
9 See 'hg help dates' for a list of formats valid for -d/--date.
10
10
11 You will be prompted for whether to record changes to each modified file,
11 You will be prompted for whether to record changes to each modified file,
12 and for files with multiple changes, for each change to use. For each
12 and for files with multiple changes, for each change to use. For each
13 query, the following responses are possible:
13 query, the following responses are possible:
14
14
15 y - record this change
15 y - record this change
16 n - skip this change
16 n - skip this change
17
17
18 s - skip remaining changes to this file
18 s - skip remaining changes to this file
19 f - record remaining changes to this file
19 f - record remaining changes to this file
20
20
21 d - done, skip remaining changes and files
21 d - done, skip remaining changes and files
22 a - record all changes to all remaining files
22 a - record all changes to all remaining files
23 q - quit, recording no changes
23 q - quit, recording no changes
24
24
25 ? - display help
25 ? - display help
26
26
27 This command is not available when committing a merge.
28
27 options:
29 options:
28
30
29 -A --addremove mark new/missing files as added/removed before committing
31 -A --addremove mark new/missing files as added/removed before committing
30 --close-branch mark a branch as closed, hiding it from the branch list
32 --close-branch mark a branch as closed, hiding it from the branch list
31 -I --include include names matching the given patterns
33 -I --include include names matching the given patterns
32 -X --exclude exclude names matching the given patterns
34 -X --exclude exclude names matching the given patterns
33 -m --message use <text> as commit message
35 -m --message use <text> as commit message
34 -l --logfile read commit message from <file>
36 -l --logfile read commit message from <file>
35 -d --date record datecode as commit date
37 -d --date record datecode as commit date
36 -u --user record the specified user as committer
38 -u --user record the specified user as committer
37
39
38 use "hg -v help record" to show global options
40 use "hg -v help record" to show global options
39 % select no files
41 % select no files
40 diff --git a/empty-rw b/empty-rw
42 diff --git a/empty-rw b/empty-rw
41 new file mode 100644
43 new file mode 100644
42 examine changes to 'empty-rw'? [Ynsfdaq?] no changes to record
44 examine changes to 'empty-rw'? [Ynsfdaq?] no changes to record
43
45
44 changeset: -1:000000000000
46 changeset: -1:000000000000
45 tag: tip
47 tag: tip
46 user:
48 user:
47 date: Thu Jan 01 00:00:00 1970 +0000
49 date: Thu Jan 01 00:00:00 1970 +0000
48
50
49
51
50 % select files but no hunks
52 % select files but no hunks
51 diff --git a/empty-rw b/empty-rw
53 diff --git a/empty-rw b/empty-rw
52 new file mode 100644
54 new file mode 100644
53 examine changes to 'empty-rw'? [Ynsfdaq?] abort: empty commit message
55 examine changes to 'empty-rw'? [Ynsfdaq?] abort: empty commit message
54
56
55 changeset: -1:000000000000
57 changeset: -1:000000000000
56 tag: tip
58 tag: tip
57 user:
59 user:
58 date: Thu Jan 01 00:00:00 1970 +0000
60 date: Thu Jan 01 00:00:00 1970 +0000
59
61
60
62
61 % record empty file
63 % record empty file
62 diff --git a/empty-rw b/empty-rw
64 diff --git a/empty-rw b/empty-rw
63 new file mode 100644
65 new file mode 100644
64 examine changes to 'empty-rw'? [Ynsfdaq?]
66 examine changes to 'empty-rw'? [Ynsfdaq?]
65 changeset: 0:c0708cf4e46e
67 changeset: 0:c0708cf4e46e
66 tag: tip
68 tag: tip
67 user: test
69 user: test
68 date: Thu Jan 01 00:00:00 1970 +0000
70 date: Thu Jan 01 00:00:00 1970 +0000
69 summary: empty
71 summary: empty
70
72
71
73
72 % rename empty file
74 % rename empty file
73 diff --git a/empty-rw b/empty-rename
75 diff --git a/empty-rw b/empty-rename
74 rename from empty-rw
76 rename from empty-rw
75 rename to empty-rename
77 rename to empty-rename
76 examine changes to 'empty-rw' and 'empty-rename'? [Ynsfdaq?]
78 examine changes to 'empty-rw' and 'empty-rename'? [Ynsfdaq?]
77 changeset: 1:d695e8dcb197
79 changeset: 1:d695e8dcb197
78 tag: tip
80 tag: tip
79 user: test
81 user: test
80 date: Thu Jan 01 00:00:01 1970 +0000
82 date: Thu Jan 01 00:00:01 1970 +0000
81 summary: rename
83 summary: rename
82
84
83
85
84 % copy empty file
86 % copy empty file
85 diff --git a/empty-rename b/empty-copy
87 diff --git a/empty-rename b/empty-copy
86 copy from empty-rename
88 copy from empty-rename
87 copy to empty-copy
89 copy to empty-copy
88 examine changes to 'empty-rename' and 'empty-copy'? [Ynsfdaq?]
90 examine changes to 'empty-rename' and 'empty-copy'? [Ynsfdaq?]
89 changeset: 2:1d4b90bea524
91 changeset: 2:1d4b90bea524
90 tag: tip
92 tag: tip
91 user: test
93 user: test
92 date: Thu Jan 01 00:00:02 1970 +0000
94 date: Thu Jan 01 00:00:02 1970 +0000
93 summary: copy
95 summary: copy
94
96
95
97
96 % delete empty file
98 % delete empty file
97 diff --git a/empty-copy b/empty-copy
99 diff --git a/empty-copy b/empty-copy
98 deleted file mode 100644
100 deleted file mode 100644
99 examine changes to 'empty-copy'? [Ynsfdaq?]
101 examine changes to 'empty-copy'? [Ynsfdaq?]
100 changeset: 3:b39a238f01a1
102 changeset: 3:b39a238f01a1
101 tag: tip
103 tag: tip
102 user: test
104 user: test
103 date: Thu Jan 01 00:00:03 1970 +0000
105 date: Thu Jan 01 00:00:03 1970 +0000
104 summary: delete
106 summary: delete
105
107
106
108
107 % add binary file
109 % add binary file
108 1 changesets found
110 1 changesets found
109 diff --git a/tip.bundle b/tip.bundle
111 diff --git a/tip.bundle b/tip.bundle
110 new file mode 100644
112 new file mode 100644
111 this is a binary file
113 this is a binary file
112 examine changes to 'tip.bundle'? [Ynsfdaq?]
114 examine changes to 'tip.bundle'? [Ynsfdaq?]
113 changeset: 4:ad816da3711e
115 changeset: 4:ad816da3711e
114 tag: tip
116 tag: tip
115 user: test
117 user: test
116 date: Thu Jan 01 00:00:04 1970 +0000
118 date: Thu Jan 01 00:00:04 1970 +0000
117 summary: binary
119 summary: binary
118
120
119 diff -r b39a238f01a1 -r ad816da3711e tip.bundle
121 diff -r b39a238f01a1 -r ad816da3711e tip.bundle
120 Binary file tip.bundle has changed
122 Binary file tip.bundle has changed
121
123
122 % change binary file
124 % change binary file
123 1 changesets found
125 1 changesets found
124 diff --git a/tip.bundle b/tip.bundle
126 diff --git a/tip.bundle b/tip.bundle
125 this modifies a binary file (all or nothing)
127 this modifies a binary file (all or nothing)
126 examine changes to 'tip.bundle'? [Ynsfdaq?]
128 examine changes to 'tip.bundle'? [Ynsfdaq?]
127 changeset: 5:dccd6f3eb485
129 changeset: 5:dccd6f3eb485
128 tag: tip
130 tag: tip
129 user: test
131 user: test
130 date: Thu Jan 01 00:00:05 1970 +0000
132 date: Thu Jan 01 00:00:05 1970 +0000
131 summary: binary-change
133 summary: binary-change
132
134
133 diff -r ad816da3711e -r dccd6f3eb485 tip.bundle
135 diff -r ad816da3711e -r dccd6f3eb485 tip.bundle
134 Binary file tip.bundle has changed
136 Binary file tip.bundle has changed
135
137
136 % rename and change binary file
138 % rename and change binary file
137 1 changesets found
139 1 changesets found
138 diff --git a/tip.bundle b/top.bundle
140 diff --git a/tip.bundle b/top.bundle
139 rename from tip.bundle
141 rename from tip.bundle
140 rename to top.bundle
142 rename to top.bundle
141 this modifies a binary file (all or nothing)
143 this modifies a binary file (all or nothing)
142 examine changes to 'tip.bundle' and 'top.bundle'? [Ynsfdaq?]
144 examine changes to 'tip.bundle' and 'top.bundle'? [Ynsfdaq?]
143 changeset: 6:7fa44105f5b3
145 changeset: 6:7fa44105f5b3
144 tag: tip
146 tag: tip
145 user: test
147 user: test
146 date: Thu Jan 01 00:00:06 1970 +0000
148 date: Thu Jan 01 00:00:06 1970 +0000
147 summary: binary-change-rename
149 summary: binary-change-rename
148
150
149 diff -r dccd6f3eb485 -r 7fa44105f5b3 tip.bundle
151 diff -r dccd6f3eb485 -r 7fa44105f5b3 tip.bundle
150 Binary file tip.bundle has changed
152 Binary file tip.bundle has changed
151 diff -r dccd6f3eb485 -r 7fa44105f5b3 top.bundle
153 diff -r dccd6f3eb485 -r 7fa44105f5b3 top.bundle
152 Binary file top.bundle has changed
154 Binary file top.bundle has changed
153
155
154 % add plain file
156 % add plain file
155 diff --git a/plain b/plain
157 diff --git a/plain b/plain
156 new file mode 100644
158 new file mode 100644
157 examine changes to 'plain'? [Ynsfdaq?]
159 examine changes to 'plain'? [Ynsfdaq?]
158 changeset: 7:11fb457c1be4
160 changeset: 7:11fb457c1be4
159 tag: tip
161 tag: tip
160 user: test
162 user: test
161 date: Thu Jan 01 00:00:07 1970 +0000
163 date: Thu Jan 01 00:00:07 1970 +0000
162 summary: plain
164 summary: plain
163
165
164 diff -r 7fa44105f5b3 -r 11fb457c1be4 plain
166 diff -r 7fa44105f5b3 -r 11fb457c1be4 plain
165 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
167 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
166 +++ b/plain Thu Jan 01 00:00:07 1970 +0000
168 +++ b/plain Thu Jan 01 00:00:07 1970 +0000
167 @@ -0,0 +1,10 @@
169 @@ -0,0 +1,10 @@
168 +1
170 +1
169 +2
171 +2
170 +3
172 +3
171 +4
173 +4
172 +5
174 +5
173 +6
175 +6
174 +7
176 +7
175 +8
177 +8
176 +9
178 +9
177 +10
179 +10
178
180
179 % modify end of plain file
181 % modify end of plain file
180 diff --git a/plain b/plain
182 diff --git a/plain b/plain
181 1 hunks, 1 lines changed
183 1 hunks, 1 lines changed
182 examine changes to 'plain'? [Ynsfdaq?] @@ -8,3 +8,4 @@
184 examine changes to 'plain'? [Ynsfdaq?] @@ -8,3 +8,4 @@
183 8
185 8
184 9
186 9
185 10
187 10
186 +11
188 +11
187 record this change to 'plain'? [Ynsfdaq?] % modify end of plain file, no EOL
189 record this change to 'plain'? [Ynsfdaq?] % modify end of plain file, no EOL
188 diff --git a/plain b/plain
190 diff --git a/plain b/plain
189 1 hunks, 1 lines changed
191 1 hunks, 1 lines changed
190 examine changes to 'plain'? [Ynsfdaq?] @@ -9,3 +9,4 @@
192 examine changes to 'plain'? [Ynsfdaq?] @@ -9,3 +9,4 @@
191 9
193 9
192 10
194 10
193 11
195 11
194 +7264f99c5f5ff3261504828afa4fb4d406c3af54
196 +7264f99c5f5ff3261504828afa4fb4d406c3af54
195 \ No newline at end of file
197 \ No newline at end of file
196 record this change to 'plain'? [Ynsfdaq?] % modify end of plain file, add EOL
198 record this change to 'plain'? [Ynsfdaq?] % modify end of plain file, add EOL
197 diff --git a/plain b/plain
199 diff --git a/plain b/plain
198 1 hunks, 2 lines changed
200 1 hunks, 2 lines changed
199 examine changes to 'plain'? [Ynsfdaq?] @@ -9,4 +9,4 @@
201 examine changes to 'plain'? [Ynsfdaq?] @@ -9,4 +9,4 @@
200 9
202 9
201 10
203 10
202 11
204 11
203 -7264f99c5f5ff3261504828afa4fb4d406c3af54
205 -7264f99c5f5ff3261504828afa4fb4d406c3af54
204 \ No newline at end of file
206 \ No newline at end of file
205 +7264f99c5f5ff3261504828afa4fb4d406c3af54
207 +7264f99c5f5ff3261504828afa4fb4d406c3af54
206 record this change to 'plain'? [Ynsfdaq?] % modify beginning, trim end, record both
208 record this change to 'plain'? [Ynsfdaq?] % modify beginning, trim end, record both
207 diff --git a/plain b/plain
209 diff --git a/plain b/plain
208 2 hunks, 4 lines changed
210 2 hunks, 4 lines changed
209 examine changes to 'plain'? [Ynsfdaq?] @@ -1,4 +1,4 @@
211 examine changes to 'plain'? [Ynsfdaq?] @@ -1,4 +1,4 @@
210 -1
212 -1
211 +2
213 +2
212 2
214 2
213 3
215 3
214 4
216 4
215 record change 1/2 to 'plain'? [Ynsfdaq?] @@ -8,5 +8,3 @@
217 record change 1/2 to 'plain'? [Ynsfdaq?] @@ -8,5 +8,3 @@
216 8
218 8
217 9
219 9
218 10
220 10
219 -11
221 -11
220 -7264f99c5f5ff3261504828afa4fb4d406c3af54
222 -7264f99c5f5ff3261504828afa4fb4d406c3af54
221 record change 2/2 to 'plain'? [Ynsfdaq?]
223 record change 2/2 to 'plain'? [Ynsfdaq?]
222 changeset: 11:efca65c9b09e
224 changeset: 11:efca65c9b09e
223 tag: tip
225 tag: tip
224 user: test
226 user: test
225 date: Thu Jan 01 00:00:10 1970 +0000
227 date: Thu Jan 01 00:00:10 1970 +0000
226 summary: begin-and-end
228 summary: begin-and-end
227
229
228 diff -r cd07d48e8cbe -r efca65c9b09e plain
230 diff -r cd07d48e8cbe -r efca65c9b09e plain
229 --- a/plain Thu Jan 01 00:00:10 1970 +0000
231 --- a/plain Thu Jan 01 00:00:10 1970 +0000
230 +++ b/plain Thu Jan 01 00:00:10 1970 +0000
232 +++ b/plain Thu Jan 01 00:00:10 1970 +0000
231 @@ -1,4 +1,4 @@
233 @@ -1,4 +1,4 @@
232 -1
234 -1
233 +2
235 +2
234 2
236 2
235 3
237 3
236 4
238 4
237 @@ -8,5 +8,3 @@
239 @@ -8,5 +8,3 @@
238 8
240 8
239 9
241 9
240 10
242 10
241 -11
243 -11
242 -7264f99c5f5ff3261504828afa4fb4d406c3af54
244 -7264f99c5f5ff3261504828afa4fb4d406c3af54
243
245
244 % trim beginning, modify end
246 % trim beginning, modify end
245 % record end
247 % record end
246 diff --git a/plain b/plain
248 diff --git a/plain b/plain
247 2 hunks, 5 lines changed
249 2 hunks, 5 lines changed
248 examine changes to 'plain'? [Ynsfdaq?] @@ -1,9 +1,6 @@
250 examine changes to 'plain'? [Ynsfdaq?] @@ -1,9 +1,6 @@
249 -2
251 -2
250 -2
252 -2
251 -3
253 -3
252 4
254 4
253 5
255 5
254 6
256 6
255 7
257 7
256 8
258 8
257 9
259 9
258 record change 1/2 to 'plain'? [Ynsfdaq?] @@ -4,7 +1,7 @@
260 record change 1/2 to 'plain'? [Ynsfdaq?] @@ -4,7 +1,7 @@
259 4
261 4
260 5
262 5
261 6
263 6
262 7
264 7
263 8
265 8
264 9
266 9
265 -10
267 -10
266 +10.new
268 +10.new
267 record change 2/2 to 'plain'? [Ynsfdaq?]
269 record change 2/2 to 'plain'? [Ynsfdaq?]
268 changeset: 12:7d1e66983c15
270 changeset: 12:7d1e66983c15
269 tag: tip
271 tag: tip
270 user: test
272 user: test
271 date: Thu Jan 01 00:00:11 1970 +0000
273 date: Thu Jan 01 00:00:11 1970 +0000
272 summary: end-only
274 summary: end-only
273
275
274 diff -r efca65c9b09e -r 7d1e66983c15 plain
276 diff -r efca65c9b09e -r 7d1e66983c15 plain
275 --- a/plain Thu Jan 01 00:00:10 1970 +0000
277 --- a/plain Thu Jan 01 00:00:10 1970 +0000
276 +++ b/plain Thu Jan 01 00:00:11 1970 +0000
278 +++ b/plain Thu Jan 01 00:00:11 1970 +0000
277 @@ -7,4 +7,4 @@
279 @@ -7,4 +7,4 @@
278 7
280 7
279 8
281 8
280 9
282 9
281 -10
283 -10
282 +10.new
284 +10.new
283
285
284 % record beginning
286 % record beginning
285 diff --git a/plain b/plain
287 diff --git a/plain b/plain
286 1 hunks, 3 lines changed
288 1 hunks, 3 lines changed
287 examine changes to 'plain'? [Ynsfdaq?] @@ -1,6 +1,3 @@
289 examine changes to 'plain'? [Ynsfdaq?] @@ -1,6 +1,3 @@
288 -2
290 -2
289 -2
291 -2
290 -3
292 -3
291 4
293 4
292 5
294 5
293 6
295 6
294 record this change to 'plain'? [Ynsfdaq?]
296 record this change to 'plain'? [Ynsfdaq?]
295 changeset: 13:a09fc62a0e61
297 changeset: 13:a09fc62a0e61
296 tag: tip
298 tag: tip
297 user: test
299 user: test
298 date: Thu Jan 01 00:00:12 1970 +0000
300 date: Thu Jan 01 00:00:12 1970 +0000
299 summary: begin-only
301 summary: begin-only
300
302
301 diff -r 7d1e66983c15 -r a09fc62a0e61 plain
303 diff -r 7d1e66983c15 -r a09fc62a0e61 plain
302 --- a/plain Thu Jan 01 00:00:11 1970 +0000
304 --- a/plain Thu Jan 01 00:00:11 1970 +0000
303 +++ b/plain Thu Jan 01 00:00:12 1970 +0000
305 +++ b/plain Thu Jan 01 00:00:12 1970 +0000
304 @@ -1,6 +1,3 @@
306 @@ -1,6 +1,3 @@
305 -2
307 -2
306 -2
308 -2
307 -3
309 -3
308 4
310 4
309 5
311 5
310 6
312 6
311
313
312 % add to beginning, trim from end
314 % add to beginning, trim from end
313 % record end
315 % record end
314 diff --git a/plain b/plain
316 diff --git a/plain b/plain
315 2 hunks, 4 lines changed
317 2 hunks, 4 lines changed
316 examine changes to 'plain'? [Ynsfdaq?] @@ -1,6 +1,9 @@
318 examine changes to 'plain'? [Ynsfdaq?] @@ -1,6 +1,9 @@
317 +1
319 +1
318 +2
320 +2
319 +3
321 +3
320 4
322 4
321 5
323 5
322 6
324 6
323 7
325 7
324 8
326 8
325 9
327 9
326 record change 1/2 to 'plain'? [Ynsfdaq?] @@ -1,7 +4,6 @@
328 record change 1/2 to 'plain'? [Ynsfdaq?] @@ -1,7 +4,6 @@
327 4
329 4
328 5
330 5
329 6
331 6
330 7
332 7
331 8
333 8
332 9
334 9
333 -10.new
335 -10.new
334 record change 2/2 to 'plain'? [Ynsfdaq?] % add to beginning, middle, end
336 record change 2/2 to 'plain'? [Ynsfdaq?] % add to beginning, middle, end
335 % record beginning, middle
337 % record beginning, middle
336 diff --git a/plain b/plain
338 diff --git a/plain b/plain
337 3 hunks, 7 lines changed
339 3 hunks, 7 lines changed
338 examine changes to 'plain'? [Ynsfdaq?] @@ -1,2 +1,5 @@
340 examine changes to 'plain'? [Ynsfdaq?] @@ -1,2 +1,5 @@
339 +1
341 +1
340 +2
342 +2
341 +3
343 +3
342 4
344 4
343 5
345 5
344 record change 1/3 to 'plain'? [Ynsfdaq?] @@ -1,6 +4,8 @@
346 record change 1/3 to 'plain'? [Ynsfdaq?] @@ -1,6 +4,8 @@
345 4
347 4
346 5
348 5
347 +5.new
349 +5.new
348 +5.reallynew
350 +5.reallynew
349 6
351 6
350 7
352 7
351 8
353 8
352 9
354 9
353 record change 2/3 to 'plain'? [Ynsfdaq?] @@ -3,4 +8,6 @@
355 record change 2/3 to 'plain'? [Ynsfdaq?] @@ -3,4 +8,6 @@
354 6
356 6
355 7
357 7
356 8
358 8
357 9
359 9
358 +10
360 +10
359 +11
361 +11
360 record change 3/3 to 'plain'? [Ynsfdaq?]
362 record change 3/3 to 'plain'? [Ynsfdaq?]
361 changeset: 15:7d137997f3a6
363 changeset: 15:7d137997f3a6
362 tag: tip
364 tag: tip
363 user: test
365 user: test
364 date: Thu Jan 01 00:00:14 1970 +0000
366 date: Thu Jan 01 00:00:14 1970 +0000
365 summary: middle-only
367 summary: middle-only
366
368
367 diff -r c0b8e5fb0be6 -r 7d137997f3a6 plain
369 diff -r c0b8e5fb0be6 -r 7d137997f3a6 plain
368 --- a/plain Thu Jan 01 00:00:13 1970 +0000
370 --- a/plain Thu Jan 01 00:00:13 1970 +0000
369 +++ b/plain Thu Jan 01 00:00:14 1970 +0000
371 +++ b/plain Thu Jan 01 00:00:14 1970 +0000
370 @@ -1,5 +1,10 @@
372 @@ -1,5 +1,10 @@
371 +1
373 +1
372 +2
374 +2
373 +3
375 +3
374 4
376 4
375 5
377 5
376 +5.new
378 +5.new
377 +5.reallynew
379 +5.reallynew
378 6
380 6
379 7
381 7
380 8
382 8
381
383
382 % record end
384 % record end
383 diff --git a/plain b/plain
385 diff --git a/plain b/plain
384 1 hunks, 2 lines changed
386 1 hunks, 2 lines changed
385 examine changes to 'plain'? [Ynsfdaq?] @@ -9,3 +9,5 @@
387 examine changes to 'plain'? [Ynsfdaq?] @@ -9,3 +9,5 @@
386 7
388 7
387 8
389 8
388 9
390 9
389 +10
391 +10
390 +11
392 +11
391 record this change to 'plain'? [Ynsfdaq?]
393 record this change to 'plain'? [Ynsfdaq?]
392 changeset: 16:4959e3ff13eb
394 changeset: 16:4959e3ff13eb
393 tag: tip
395 tag: tip
394 user: test
396 user: test
395 date: Thu Jan 01 00:00:15 1970 +0000
397 date: Thu Jan 01 00:00:15 1970 +0000
396 summary: end-only
398 summary: end-only
397
399
398 diff -r 7d137997f3a6 -r 4959e3ff13eb plain
400 diff -r 7d137997f3a6 -r 4959e3ff13eb plain
399 --- a/plain Thu Jan 01 00:00:14 1970 +0000
401 --- a/plain Thu Jan 01 00:00:14 1970 +0000
400 +++ b/plain Thu Jan 01 00:00:15 1970 +0000
402 +++ b/plain Thu Jan 01 00:00:15 1970 +0000
401 @@ -9,3 +9,5 @@
403 @@ -9,3 +9,5 @@
402 7
404 7
403 8
405 8
404 9
406 9
405 +10
407 +10
406 +11
408 +11
407
409
408 adding subdir/a
410 adding subdir/a
409 diff --git a/subdir/a b/subdir/a
411 diff --git a/subdir/a b/subdir/a
410 1 hunks, 1 lines changed
412 1 hunks, 1 lines changed
411 examine changes to 'subdir/a'? [Ynsfdaq?] @@ -1,1 +1,2 @@
413 examine changes to 'subdir/a'? [Ynsfdaq?] @@ -1,1 +1,2 @@
412 a
414 a
413 +a
415 +a
414 record this change to 'subdir/a'? [Ynsfdaq?]
416 record this change to 'subdir/a'? [Ynsfdaq?]
415 changeset: 18:40698cd490b2
417 changeset: 18:40698cd490b2
416 tag: tip
418 tag: tip
417 user: test
419 user: test
418 date: Thu Jan 01 00:00:16 1970 +0000
420 date: Thu Jan 01 00:00:16 1970 +0000
419 summary: subdir-change
421 summary: subdir-change
420
422
421 diff -r 661eacdc08b9 -r 40698cd490b2 subdir/a
423 diff -r 661eacdc08b9 -r 40698cd490b2 subdir/a
422 --- a/subdir/a Thu Jan 01 00:00:16 1970 +0000
424 --- a/subdir/a Thu Jan 01 00:00:16 1970 +0000
423 +++ b/subdir/a Thu Jan 01 00:00:16 1970 +0000
425 +++ b/subdir/a Thu Jan 01 00:00:16 1970 +0000
424 @@ -1,1 +1,2 @@
426 @@ -1,1 +1,2 @@
425 a
427 a
426 +a
428 +a
427
429
428 % help, quit
430 % help, quit
429 diff --git a/subdir/f1 b/subdir/f1
431 diff --git a/subdir/f1 b/subdir/f1
430 1 hunks, 1 lines changed
432 1 hunks, 1 lines changed
431 examine changes to 'subdir/f1'? [Ynsfdaq?] y - record this change
433 examine changes to 'subdir/f1'? [Ynsfdaq?] y - record this change
432 n - skip this change
434 n - skip this change
433 s - skip remaining changes to this file
435 s - skip remaining changes to this file
434 f - record remaining changes to this file
436 f - record remaining changes to this file
435 d - done, skip remaining changes and files
437 d - done, skip remaining changes and files
436 a - record all changes to all remaining files
438 a - record all changes to all remaining files
437 q - quit, recording no changes
439 q - quit, recording no changes
438 ? - display help
440 ? - display help
439 examine changes to 'subdir/f1'? [Ynsfdaq?] abort: user quit
441 examine changes to 'subdir/f1'? [Ynsfdaq?] abort: user quit
440 % skip
442 % skip
441 diff --git a/subdir/f1 b/subdir/f1
443 diff --git a/subdir/f1 b/subdir/f1
442 1 hunks, 1 lines changed
444 1 hunks, 1 lines changed
443 examine changes to 'subdir/f1'? [Ynsfdaq?] diff --git a/subdir/f2 b/subdir/f2
445 examine changes to 'subdir/f1'? [Ynsfdaq?] diff --git a/subdir/f2 b/subdir/f2
444 1 hunks, 1 lines changed
446 1 hunks, 1 lines changed
445 examine changes to 'subdir/f2'? [Ynsfdaq?] abort: response expected
447 examine changes to 'subdir/f2'? [Ynsfdaq?] abort: response expected
446 % no
448 % no
447 diff --git a/subdir/f1 b/subdir/f1
449 diff --git a/subdir/f1 b/subdir/f1
448 1 hunks, 1 lines changed
450 1 hunks, 1 lines changed
449 examine changes to 'subdir/f1'? [Ynsfdaq?] diff --git a/subdir/f2 b/subdir/f2
451 examine changes to 'subdir/f1'? [Ynsfdaq?] diff --git a/subdir/f2 b/subdir/f2
450 1 hunks, 1 lines changed
452 1 hunks, 1 lines changed
451 examine changes to 'subdir/f2'? [Ynsfdaq?] abort: response expected
453 examine changes to 'subdir/f2'? [Ynsfdaq?] abort: response expected
452 % f, quit
454 % f, quit
453 diff --git a/subdir/f1 b/subdir/f1
455 diff --git a/subdir/f1 b/subdir/f1
454 1 hunks, 1 lines changed
456 1 hunks, 1 lines changed
455 examine changes to 'subdir/f1'? [Ynsfdaq?] diff --git a/subdir/f2 b/subdir/f2
457 examine changes to 'subdir/f1'? [Ynsfdaq?] diff --git a/subdir/f2 b/subdir/f2
456 1 hunks, 1 lines changed
458 1 hunks, 1 lines changed
457 examine changes to 'subdir/f2'? [Ynsfdaq?] abort: user quit
459 examine changes to 'subdir/f2'? [Ynsfdaq?] abort: user quit
458 % s, all
460 % s, all
459 diff --git a/subdir/f1 b/subdir/f1
461 diff --git a/subdir/f1 b/subdir/f1
460 1 hunks, 1 lines changed
462 1 hunks, 1 lines changed
461 examine changes to 'subdir/f1'? [Ynsfdaq?] diff --git a/subdir/f2 b/subdir/f2
463 examine changes to 'subdir/f1'? [Ynsfdaq?] diff --git a/subdir/f2 b/subdir/f2
462 1 hunks, 1 lines changed
464 1 hunks, 1 lines changed
463 examine changes to 'subdir/f2'? [Ynsfdaq?]
465 examine changes to 'subdir/f2'? [Ynsfdaq?]
464 changeset: 20:d2d8c25276a8
466 changeset: 20:d2d8c25276a8
465 tag: tip
467 tag: tip
466 user: test
468 user: test
467 date: Thu Jan 01 00:00:18 1970 +0000
469 date: Thu Jan 01 00:00:18 1970 +0000
468 summary: x
470 summary: x
469
471
470 diff -r 25eb2a7694fb -r d2d8c25276a8 subdir/f2
472 diff -r 25eb2a7694fb -r d2d8c25276a8 subdir/f2
471 --- a/subdir/f2 Thu Jan 01 00:00:17 1970 +0000
473 --- a/subdir/f2 Thu Jan 01 00:00:17 1970 +0000
472 +++ b/subdir/f2 Thu Jan 01 00:00:18 1970 +0000
474 +++ b/subdir/f2 Thu Jan 01 00:00:18 1970 +0000
473 @@ -1,1 +1,2 @@
475 @@ -1,1 +1,2 @@
474 b
476 b
475 +b
477 +b
476
478
477 % f
479 % f
478 diff --git a/subdir/f1 b/subdir/f1
480 diff --git a/subdir/f1 b/subdir/f1
479 1 hunks, 1 lines changed
481 1 hunks, 1 lines changed
480 examine changes to 'subdir/f1'? [Ynsfdaq?]
482 examine changes to 'subdir/f1'? [Ynsfdaq?]
481 changeset: 21:1013f51ce32f
483 changeset: 21:1013f51ce32f
482 tag: tip
484 tag: tip
483 user: test
485 user: test
484 date: Thu Jan 01 00:00:19 1970 +0000
486 date: Thu Jan 01 00:00:19 1970 +0000
485 summary: y
487 summary: y
486
488
487 diff -r d2d8c25276a8 -r 1013f51ce32f subdir/f1
489 diff -r d2d8c25276a8 -r 1013f51ce32f subdir/f1
488 --- a/subdir/f1 Thu Jan 01 00:00:18 1970 +0000
490 --- a/subdir/f1 Thu Jan 01 00:00:18 1970 +0000
489 +++ b/subdir/f1 Thu Jan 01 00:00:19 1970 +0000
491 +++ b/subdir/f1 Thu Jan 01 00:00:19 1970 +0000
490 @@ -1,1 +1,2 @@
492 @@ -1,1 +1,2 @@
491 a
493 a
492 +a
494 +a
493
495
494 % preserve chmod +x
496 % preserve chmod +x
495 diff --git a/subdir/f1 b/subdir/f1
497 diff --git a/subdir/f1 b/subdir/f1
496 old mode 100644
498 old mode 100644
497 new mode 100755
499 new mode 100755
498 1 hunks, 1 lines changed
500 1 hunks, 1 lines changed
499 examine changes to 'subdir/f1'? [Ynsfdaq?] @@ -1,2 +1,3 @@
501 examine changes to 'subdir/f1'? [Ynsfdaq?] @@ -1,2 +1,3 @@
500 a
502 a
501 a
503 a
502 +a
504 +a
503 record this change to 'subdir/f1'? [Ynsfdaq?]
505 record this change to 'subdir/f1'? [Ynsfdaq?]
504 changeset: 22:5df857735621
506 changeset: 22:5df857735621
505 tag: tip
507 tag: tip
506 user: test
508 user: test
507 date: Thu Jan 01 00:00:20 1970 +0000
509 date: Thu Jan 01 00:00:20 1970 +0000
508 summary: z
510 summary: z
509
511
510 diff --git a/subdir/f1 b/subdir/f1
512 diff --git a/subdir/f1 b/subdir/f1
511 old mode 100644
513 old mode 100644
512 new mode 100755
514 new mode 100755
513 --- a/subdir/f1
515 --- a/subdir/f1
514 +++ b/subdir/f1
516 +++ b/subdir/f1
515 @@ -1,2 +1,3 @@
517 @@ -1,2 +1,3 @@
516 a
518 a
517 a
519 a
518 +a
520 +a
519
521
520 % preserve execute permission on original
522 % preserve execute permission on original
521 diff --git a/subdir/f1 b/subdir/f1
523 diff --git a/subdir/f1 b/subdir/f1
522 1 hunks, 1 lines changed
524 1 hunks, 1 lines changed
523 examine changes to 'subdir/f1'? [Ynsfdaq?] @@ -1,3 +1,4 @@
525 examine changes to 'subdir/f1'? [Ynsfdaq?] @@ -1,3 +1,4 @@
524 a
526 a
525 a
527 a
526 a
528 a
527 +b
529 +b
528 record this change to 'subdir/f1'? [Ynsfdaq?]
530 record this change to 'subdir/f1'? [Ynsfdaq?]
529 changeset: 23:a4ae36a78715
531 changeset: 23:a4ae36a78715
530 tag: tip
532 tag: tip
531 user: test
533 user: test
532 date: Thu Jan 01 00:00:21 1970 +0000
534 date: Thu Jan 01 00:00:21 1970 +0000
533 summary: aa
535 summary: aa
534
536
535 diff --git a/subdir/f1 b/subdir/f1
537 diff --git a/subdir/f1 b/subdir/f1
536 --- a/subdir/f1
538 --- a/subdir/f1
537 +++ b/subdir/f1
539 +++ b/subdir/f1
538 @@ -1,3 +1,4 @@
540 @@ -1,3 +1,4 @@
539 a
541 a
540 a
542 a
541 a
543 a
542 +b
544 +b
543
545
544 % preserve chmod -x
546 % preserve chmod -x
545 diff --git a/subdir/f1 b/subdir/f1
547 diff --git a/subdir/f1 b/subdir/f1
546 old mode 100755
548 old mode 100755
547 new mode 100644
549 new mode 100644
548 1 hunks, 1 lines changed
550 1 hunks, 1 lines changed
549 examine changes to 'subdir/f1'? [Ynsfdaq?] @@ -2,3 +2,4 @@
551 examine changes to 'subdir/f1'? [Ynsfdaq?] @@ -2,3 +2,4 @@
550 a
552 a
551 a
553 a
552 b
554 b
553 +c
555 +c
554 record this change to 'subdir/f1'? [Ynsfdaq?]
556 record this change to 'subdir/f1'? [Ynsfdaq?]
555 changeset: 24:1460f6e47966
557 changeset: 24:1460f6e47966
556 tag: tip
558 tag: tip
557 user: test
559 user: test
558 date: Thu Jan 01 00:00:22 1970 +0000
560 date: Thu Jan 01 00:00:22 1970 +0000
559 summary: ab
561 summary: ab
560
562
561 diff --git a/subdir/f1 b/subdir/f1
563 diff --git a/subdir/f1 b/subdir/f1
562 old mode 100755
564 old mode 100755
563 new mode 100644
565 new mode 100644
564 --- a/subdir/f1
566 --- a/subdir/f1
565 +++ b/subdir/f1
567 +++ b/subdir/f1
566 @@ -2,3 +2,4 @@
568 @@ -2,3 +2,4 @@
567 a
569 a
568 a
570 a
569 b
571 b
570 +c
572 +c
571
573
574 % abort early when a merge is in progress
575 1 files updated, 0 files merged, 5 files removed, 0 files unresolved
576 marked working directory as branch thatbranch
577 created new head
578 5 files updated, 0 files merged, 2 files removed, 0 files unresolved
579 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
580 (branch merge, don't forget to commit)
581
582 abort: cannot partially commit a merge (use hg commit instead)
583 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
572 % with win32ext
584 % with win32ext
573 diff --git a/subdir/f1 b/subdir/f1
585 diff --git a/subdir/f1 b/subdir/f1
574 1 hunks, 1 lines changed
586 1 hunks, 1 lines changed
575 examine changes to 'subdir/f1'? [Ynsfdaq?] @@ -3,3 +3,4 @@
587 examine changes to 'subdir/f1'? [Ynsfdaq?] @@ -3,3 +3,4 @@
576 a
588 a
577 b
589 b
578 c
590 c
579 +d
591 +d
580 record this change to 'subdir/f1'? [Ynsfdaq?]
592 record this change to 'subdir/f1'? [Ynsfdaq?]
581 changeset: 25:5bacc1f6e9cf
593 changeset: 26:5bacc1f6e9cf
582 tag: tip
594 tag: tip
595 parent: 24:1460f6e47966
583 user: test
596 user: test
584 date: Thu Jan 01 00:00:23 1970 +0000
597 date: Thu Jan 01 00:00:23 1970 +0000
585 summary: w1
598 summary: w1
586
599
587 diff -r 1460f6e47966 -r 5bacc1f6e9cf subdir/f1
600 diff -r 1460f6e47966 -r 5bacc1f6e9cf subdir/f1
588 --- a/subdir/f1 Thu Jan 01 00:00:22 1970 +0000
601 --- a/subdir/f1 Thu Jan 01 00:00:22 1970 +0000
589 +++ b/subdir/f1 Thu Jan 01 00:00:23 1970 +0000
602 +++ b/subdir/f1 Thu Jan 01 00:00:23 1970 +0000
590 @@ -3,3 +3,4 @@
603 @@ -3,3 +3,4 @@
591 a
604 a
592 b
605 b
593 c
606 c
594 +d
607 +d
595
608
General Comments 0
You need to be logged in to leave comments. Login now