##// END OF EJS Templates
record: separate each hunk with a blank line...
Martin Geisler -
r10694:d7732d2d default
parent child Browse files
Show More
@@ -1,552 +1,553 b''
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 ui.write("\n")
296 if r == 7: # ?
297 if r == 7: # ?
297 doc = gettext(record.__doc__)
298 doc = gettext(record.__doc__)
298 c = doc.find(_('y - record this change'))
299 c = doc.find(_('y - record this change'))
299 for l in doc[c:].splitlines():
300 for l in doc[c:].splitlines():
300 if l:
301 if l:
301 ui.write(l.strip(), '\n')
302 ui.write(l.strip(), '\n')
302 continue
303 continue
303 elif r == 0: # yes
304 elif r == 0: # yes
304 ret = True
305 ret = True
305 elif r == 1: # no
306 elif r == 1: # no
306 ret = False
307 ret = False
307 elif r == 2: # Skip
308 elif r == 2: # Skip
308 ret = resp_file[0] = False
309 ret = resp_file[0] = False
309 elif r == 3: # file (Record remaining)
310 elif r == 3: # file (Record remaining)
310 ret = resp_file[0] = True
311 ret = resp_file[0] = True
311 elif r == 4: # done, skip remaining
312 elif r == 4: # done, skip remaining
312 ret = resp_all[0] = False
313 ret = resp_all[0] = False
313 elif r == 5: # all
314 elif r == 5: # all
314 ret = resp_all[0] = True
315 ret = resp_all[0] = True
315 elif r == 6: # quit
316 elif r == 6: # quit
316 raise util.Abort(_('user quit'))
317 raise util.Abort(_('user quit'))
317 return ret
318 return ret
318 pos, total = 0, len(chunks) - 1
319 pos, total = 0, len(chunks) - 1
319 while chunks:
320 while chunks:
320 pos = total - len(chunks) + 1
321 pos = total - len(chunks) + 1
321 chunk = chunks.pop()
322 chunk = chunks.pop()
322 if isinstance(chunk, header):
323 if isinstance(chunk, header):
323 # new-file mark
324 # new-file mark
324 resp_file = [None]
325 resp_file = [None]
325 fixoffset = 0
326 fixoffset = 0
326 hdr = ''.join(chunk.header)
327 hdr = ''.join(chunk.header)
327 if hdr in seen:
328 if hdr in seen:
328 consumefile()
329 consumefile()
329 continue
330 continue
330 seen.add(hdr)
331 seen.add(hdr)
331 if resp_all[0] is None:
332 if resp_all[0] is None:
332 chunk.pretty(ui)
333 chunk.pretty(ui)
333 r = prompt(_('examine changes to %s?') %
334 r = prompt(_('examine changes to %s?') %
334 _(' and ').join(map(repr, chunk.files())))
335 _(' and ').join(map(repr, chunk.files())))
335 if r:
336 if r:
336 applied[chunk.filename()] = [chunk]
337 applied[chunk.filename()] = [chunk]
337 if chunk.allhunks():
338 if chunk.allhunks():
338 applied[chunk.filename()] += consumefile()
339 applied[chunk.filename()] += consumefile()
339 else:
340 else:
340 consumefile()
341 consumefile()
341 else:
342 else:
342 # new hunk
343 # new hunk
343 if resp_file[0] is None and resp_all[0] is None:
344 if resp_file[0] is None and resp_all[0] is None:
344 chunk.pretty(ui)
345 chunk.pretty(ui)
345 r = total == 1 and prompt(_('record this change to %r?') %
346 r = total == 1 and prompt(_('record this change to %r?') %
346 chunk.filename()) \
347 chunk.filename()) \
347 or prompt(_('record change %d/%d to %r?') %
348 or prompt(_('record change %d/%d to %r?') %
348 (pos, total, chunk.filename()))
349 (pos, total, chunk.filename()))
349 if r:
350 if r:
350 if fixoffset:
351 if fixoffset:
351 chunk = copy.copy(chunk)
352 chunk = copy.copy(chunk)
352 chunk.toline += fixoffset
353 chunk.toline += fixoffset
353 applied[chunk.filename()].append(chunk)
354 applied[chunk.filename()].append(chunk)
354 else:
355 else:
355 fixoffset += chunk.removed - chunk.added
356 fixoffset += chunk.removed - chunk.added
356 return reduce(operator.add, [h for h in applied.itervalues()
357 return reduce(operator.add, [h for h in applied.itervalues()
357 if h[0].special() or len(h) > 1], [])
358 if h[0].special() or len(h) > 1], [])
358
359
359 def record(ui, repo, *pats, **opts):
360 def record(ui, repo, *pats, **opts):
360 '''interactively select changes to commit
361 '''interactively select changes to commit
361
362
362 If a list of files is omitted, all changes reported by "hg status"
363 If a list of files is omitted, all changes reported by "hg status"
363 will be candidates for recording.
364 will be candidates for recording.
364
365
365 See 'hg help dates' for a list of formats valid for -d/--date.
366 See 'hg help dates' for a list of formats valid for -d/--date.
366
367
367 You will be prompted for whether to record changes to each
368 You will be prompted for whether to record changes to each
368 modified file, and for files with multiple changes, for each
369 modified file, and for files with multiple changes, for each
369 change to use. For each query, the following responses are
370 change to use. For each query, the following responses are
370 possible::
371 possible::
371
372
372 y - record this change
373 y - record this change
373 n - skip this change
374 n - skip this change
374
375
375 s - skip remaining changes to this file
376 s - skip remaining changes to this file
376 f - record remaining changes to this file
377 f - record remaining changes to this file
377
378
378 d - done, skip remaining changes and files
379 d - done, skip remaining changes and files
379 a - record all changes to all remaining files
380 a - record all changes to all remaining files
380 q - quit, recording no changes
381 q - quit, recording no changes
381
382
382 ? - display help'''
383 ? - display help'''
383
384
384 dorecord(ui, repo, commands.commit, *pats, **opts)
385 dorecord(ui, repo, commands.commit, *pats, **opts)
385
386
386
387
387 def qrecord(ui, repo, patch, *pats, **opts):
388 def qrecord(ui, repo, patch, *pats, **opts):
388 '''interactively record a new patch
389 '''interactively record a new patch
389
390
390 See 'hg help qnew' & 'hg help record' for more information and
391 See 'hg help qnew' & 'hg help record' for more information and
391 usage.
392 usage.
392 '''
393 '''
393
394
394 try:
395 try:
395 mq = extensions.find('mq')
396 mq = extensions.find('mq')
396 except KeyError:
397 except KeyError:
397 raise util.Abort(_("'mq' extension not loaded"))
398 raise util.Abort(_("'mq' extension not loaded"))
398
399
399 def committomq(ui, repo, *pats, **opts):
400 def committomq(ui, repo, *pats, **opts):
400 mq.new(ui, repo, patch, *pats, **opts)
401 mq.new(ui, repo, patch, *pats, **opts)
401
402
402 opts = opts.copy()
403 opts = opts.copy()
403 opts['force'] = True # always 'qnew -f'
404 opts['force'] = True # always 'qnew -f'
404 dorecord(ui, repo, committomq, *pats, **opts)
405 dorecord(ui, repo, committomq, *pats, **opts)
405
406
406
407
407 def dorecord(ui, repo, commitfunc, *pats, **opts):
408 def dorecord(ui, repo, commitfunc, *pats, **opts):
408 if not ui.interactive():
409 if not ui.interactive():
409 raise util.Abort(_('running non-interactively, use commit instead'))
410 raise util.Abort(_('running non-interactively, use commit instead'))
410
411
411 def recordfunc(ui, repo, message, match, opts):
412 def recordfunc(ui, repo, message, match, opts):
412 """This is generic record driver.
413 """This is generic record driver.
413
414
414 Its job is to interactively filter local changes, and accordingly
415 Its job is to interactively filter local changes, and accordingly
415 prepare working dir into a state, where the job can be delegated to
416 prepare working dir into a state, where the job can be delegated to
416 non-interactive commit command such as 'commit' or 'qrefresh'.
417 non-interactive commit command such as 'commit' or 'qrefresh'.
417
418
418 After the actual job is done by non-interactive command, working dir
419 After the actual job is done by non-interactive command, working dir
419 state is restored to original.
420 state is restored to original.
420
421
421 In the end we'll record intresting changes, and everything else will be
422 In the end we'll record intresting changes, and everything else will be
422 left in place, so the user can continue his work.
423 left in place, so the user can continue his work.
423 """
424 """
424
425
425 changes = repo.status(match=match)[:3]
426 changes = repo.status(match=match)[:3]
426 diffopts = mdiff.diffopts(git=True, nodates=True)
427 diffopts = mdiff.diffopts(git=True, nodates=True)
427 chunks = patch.diff(repo, changes=changes, opts=diffopts)
428 chunks = patch.diff(repo, changes=changes, opts=diffopts)
428 fp = cStringIO.StringIO()
429 fp = cStringIO.StringIO()
429 fp.write(''.join(chunks))
430 fp.write(''.join(chunks))
430 fp.seek(0)
431 fp.seek(0)
431
432
432 # 1. filter patch, so we have intending-to apply subset of it
433 # 1. filter patch, so we have intending-to apply subset of it
433 chunks = filterpatch(ui, parsepatch(fp))
434 chunks = filterpatch(ui, parsepatch(fp))
434 del fp
435 del fp
435
436
436 contenders = set()
437 contenders = set()
437 for h in chunks:
438 for h in chunks:
438 try:
439 try:
439 contenders.update(set(h.files()))
440 contenders.update(set(h.files()))
440 except AttributeError:
441 except AttributeError:
441 pass
442 pass
442
443
443 changed = changes[0] + changes[1] + changes[2]
444 changed = changes[0] + changes[1] + changes[2]
444 newfiles = [f for f in changed if f in contenders]
445 newfiles = [f for f in changed if f in contenders]
445 if not newfiles:
446 if not newfiles:
446 ui.status(_('no changes to record\n'))
447 ui.status(_('no changes to record\n'))
447 return 0
448 return 0
448
449
449 modified = set(changes[0])
450 modified = set(changes[0])
450
451
451 # 2. backup changed files, so we can restore them in the end
452 # 2. backup changed files, so we can restore them in the end
452 backups = {}
453 backups = {}
453 backupdir = repo.join('record-backups')
454 backupdir = repo.join('record-backups')
454 try:
455 try:
455 os.mkdir(backupdir)
456 os.mkdir(backupdir)
456 except OSError, err:
457 except OSError, err:
457 if err.errno != errno.EEXIST:
458 if err.errno != errno.EEXIST:
458 raise
459 raise
459 try:
460 try:
460 # backup continues
461 # backup continues
461 for f in newfiles:
462 for f in newfiles:
462 if f not in modified:
463 if f not in modified:
463 continue
464 continue
464 fd, tmpname = tempfile.mkstemp(prefix=f.replace('/', '_')+'.',
465 fd, tmpname = tempfile.mkstemp(prefix=f.replace('/', '_')+'.',
465 dir=backupdir)
466 dir=backupdir)
466 os.close(fd)
467 os.close(fd)
467 ui.debug('backup %r as %r\n' % (f, tmpname))
468 ui.debug('backup %r as %r\n' % (f, tmpname))
468 util.copyfile(repo.wjoin(f), tmpname)
469 util.copyfile(repo.wjoin(f), tmpname)
469 backups[f] = tmpname
470 backups[f] = tmpname
470
471
471 fp = cStringIO.StringIO()
472 fp = cStringIO.StringIO()
472 for c in chunks:
473 for c in chunks:
473 if c.filename() in backups:
474 if c.filename() in backups:
474 c.write(fp)
475 c.write(fp)
475 dopatch = fp.tell()
476 dopatch = fp.tell()
476 fp.seek(0)
477 fp.seek(0)
477
478
478 # 3a. apply filtered patch to clean repo (clean)
479 # 3a. apply filtered patch to clean repo (clean)
479 if backups:
480 if backups:
480 hg.revert(repo, repo.dirstate.parents()[0], backups.has_key)
481 hg.revert(repo, repo.dirstate.parents()[0], backups.has_key)
481
482
482 # 3b. (apply)
483 # 3b. (apply)
483 if dopatch:
484 if dopatch:
484 try:
485 try:
485 ui.debug('applying patch\n')
486 ui.debug('applying patch\n')
486 ui.debug(fp.getvalue())
487 ui.debug(fp.getvalue())
487 pfiles = {}
488 pfiles = {}
488 patch.internalpatch(fp, ui, 1, repo.root, files=pfiles,
489 patch.internalpatch(fp, ui, 1, repo.root, files=pfiles,
489 eolmode=None)
490 eolmode=None)
490 patch.updatedir(ui, repo, pfiles)
491 patch.updatedir(ui, repo, pfiles)
491 except patch.PatchError, err:
492 except patch.PatchError, err:
492 s = str(err)
493 s = str(err)
493 if s:
494 if s:
494 raise util.Abort(s)
495 raise util.Abort(s)
495 else:
496 else:
496 raise util.Abort(_('patch failed to apply'))
497 raise util.Abort(_('patch failed to apply'))
497 del fp
498 del fp
498
499
499 # 4. We prepared working directory according to filtered patch.
500 # 4. We prepared working directory according to filtered patch.
500 # Now is the time to delegate the job to commit/qrefresh or the like!
501 # Now is the time to delegate the job to commit/qrefresh or the like!
501
502
502 # it is important to first chdir to repo root -- we'll call a
503 # it is important to first chdir to repo root -- we'll call a
503 # highlevel command with list of pathnames relative to repo root
504 # highlevel command with list of pathnames relative to repo root
504 cwd = os.getcwd()
505 cwd = os.getcwd()
505 os.chdir(repo.root)
506 os.chdir(repo.root)
506 try:
507 try:
507 commitfunc(ui, repo, *newfiles, **opts)
508 commitfunc(ui, repo, *newfiles, **opts)
508 finally:
509 finally:
509 os.chdir(cwd)
510 os.chdir(cwd)
510
511
511 return 0
512 return 0
512 finally:
513 finally:
513 # 5. finally restore backed-up files
514 # 5. finally restore backed-up files
514 try:
515 try:
515 for realname, tmpname in backups.iteritems():
516 for realname, tmpname in backups.iteritems():
516 ui.debug('restoring %r to %r\n' % (tmpname, realname))
517 ui.debug('restoring %r to %r\n' % (tmpname, realname))
517 util.copyfile(tmpname, repo.wjoin(realname))
518 util.copyfile(tmpname, repo.wjoin(realname))
518 os.unlink(tmpname)
519 os.unlink(tmpname)
519 os.rmdir(backupdir)
520 os.rmdir(backupdir)
520 except OSError:
521 except OSError:
521 pass
522 pass
522 return cmdutil.commit(ui, repo, recordfunc, pats, opts)
523 return cmdutil.commit(ui, repo, recordfunc, pats, opts)
523
524
524 cmdtable = {
525 cmdtable = {
525 "record":
526 "record":
526 (record,
527 (record,
527
528
528 # add commit options
529 # add commit options
529 commands.table['^commit|ci'][1],
530 commands.table['^commit|ci'][1],
530
531
531 _('hg record [OPTION]... [FILE]...')),
532 _('hg record [OPTION]... [FILE]...')),
532 }
533 }
533
534
534
535
535 def uisetup(ui):
536 def uisetup(ui):
536 try:
537 try:
537 mq = extensions.find('mq')
538 mq = extensions.find('mq')
538 except KeyError:
539 except KeyError:
539 return
540 return
540
541
541 qcmdtable = {
542 qcmdtable = {
542 "qrecord":
543 "qrecord":
543 (qrecord,
544 (qrecord,
544
545
545 # add qnew options, except '--force'
546 # add qnew options, except '--force'
546 [opt for opt in mq.cmdtable['qnew'][1] if opt[1] != 'force'],
547 [opt for opt in mq.cmdtable['qnew'][1] if opt[1] != 'force'],
547
548
548 _('hg qrecord [OPTION]... PATCH [FILE]...')),
549 _('hg qrecord [OPTION]... PATCH [FILE]...')),
549 }
550 }
550
551
551 cmdtable.update(qcmdtable)
552 cmdtable.update(qcmdtable)
552
553
@@ -1,59 +1,63 b''
1 adding a
1 adding a
2 % default context
2 % default context
3 diff -r cf9f4ba66af2 a
3 diff -r cf9f4ba66af2 a
4 --- a/a
4 --- a/a
5 +++ b/a
5 +++ b/a
6 @@ -2,7 +2,7 @@
6 @@ -2,7 +2,7 @@
7 c
7 c
8 a
8 a
9 a
9 a
10 -b
10 -b
11 +dd
11 +dd
12 a
12 a
13 a
13 a
14 c
14 c
15 % --unified=2
15 % --unified=2
16 diff -r cf9f4ba66af2 a
16 diff -r cf9f4ba66af2 a
17 --- a/a
17 --- a/a
18 +++ b/a
18 +++ b/a
19 @@ -3,5 +3,5 @@
19 @@ -3,5 +3,5 @@
20 a
20 a
21 a
21 a
22 -b
22 -b
23 +dd
23 +dd
24 a
24 a
25 a
25 a
26 % diffstat
26 % diffstat
27 a | 2 +-
27 a | 2 +-
28 1 files changed, 1 insertions(+), 1 deletions(-)
28 1 files changed, 1 insertions(+), 1 deletions(-)
29 % record
29 % record
30 diff --git a/a b/a
30 diff --git a/a b/a
31 old mode 100644
31 old mode 100644
32 new mode 100755
32 new mode 100755
33 1 hunks, 2 lines changed
33 1 hunks, 2 lines changed
34 examine changes to 'a'? [Ynsfdaq?] @@ -2,7 +2,7 @@
34 examine changes to 'a'? [Ynsfdaq?]
35 @@ -2,7 +2,7 @@
35 c
36 c
36 a
37 a
37 a
38 a
38 -b
39 -b
39 +dd
40 +dd
40 a
41 a
41 a
42 a
42 c
43 c
43 record this change to 'a'? [Ynsfdaq?]
44 record this change to 'a'? [Ynsfdaq?]
45
44 rolling back last transaction
46 rolling back last transaction
45 % qrecord
47 % qrecord
46 diff --git a/a b/a
48 diff --git a/a b/a
47 old mode 100644
49 old mode 100644
48 new mode 100755
50 new mode 100755
49 1 hunks, 2 lines changed
51 1 hunks, 2 lines changed
50 examine changes to 'a'? [Ynsfdaq?] @@ -2,7 +2,7 @@
52 examine changes to 'a'? [Ynsfdaq?]
53 @@ -2,7 +2,7 @@
51 c
54 c
52 a
55 a
53 a
56 a
54 -b
57 -b
55 +dd
58 +dd
56 a
59 a
57 a
60 a
58 c
61 c
59 record this change to 'a'? [Ynsfdaq?]
62 record this change to 'a'? [Ynsfdaq?]
63
@@ -1,208 +1,218 b''
1 % help (no mq, so no qrecord)
1 % help (no mq, so no qrecord)
2 hg: unknown command 'qrecord'
2 hg: unknown command 'qrecord'
3 Mercurial Distributed SCM
3 Mercurial Distributed SCM
4
4
5 basic commands:
5 basic commands:
6
6
7 add add the specified files on the next commit
7 add add the specified files on the next commit
8 annotate show changeset information by line for each file
8 annotate show changeset information by line for each file
9 clone make a copy of an existing repository
9 clone make a copy of an existing repository
10 commit commit the specified files or all outstanding changes
10 commit commit the specified files or all outstanding changes
11 diff diff repository (or selected files)
11 diff diff repository (or selected files)
12 export dump the header and diffs for one or more changesets
12 export dump the header and diffs for one or more changesets
13 forget forget the specified files on the next commit
13 forget forget the specified files on the next commit
14 init create a new repository in the given directory
14 init create a new repository in the given directory
15 log show revision history of entire repository or files
15 log show revision history of entire repository or files
16 merge merge working directory with another revision
16 merge merge working directory with another revision
17 pull pull changes from the specified source
17 pull pull changes from the specified source
18 push push changes to the specified destination
18 push push changes to the specified destination
19 remove remove the specified files on the next commit
19 remove remove the specified files on the next commit
20 serve export the repository via HTTP
20 serve export the repository via HTTP
21 status show changed files in the working directory
21 status show changed files in the working directory
22 summary summarize working directory state
22 summary summarize working directory state
23 update update working directory
23 update update working directory
24
24
25 use "hg help" for the full list of commands or "hg -v" for details
25 use "hg help" for the full list of commands or "hg -v" for details
26 % help (mq present)
26 % help (mq present)
27 hg qrecord [OPTION]... PATCH [FILE]...
27 hg qrecord [OPTION]... PATCH [FILE]...
28
28
29 interactively record a new patch
29 interactively record a new patch
30
30
31 See 'hg help qnew' & 'hg help record' for more information and usage.
31 See 'hg help qnew' & 'hg help record' for more information and usage.
32
32
33 options:
33 options:
34
34
35 -e --edit edit commit message
35 -e --edit edit commit message
36 -g --git use git extended diff format
36 -g --git use git extended diff format
37 -U --currentuser add "From: <current user>" to patch
37 -U --currentuser add "From: <current user>" to patch
38 -u --user add "From: <given user>" to patch
38 -u --user add "From: <given user>" to patch
39 -D --currentdate add "Date: <current date>" to patch
39 -D --currentdate add "Date: <current date>" to patch
40 -d --date add "Date: <given date>" to patch
40 -d --date add "Date: <given date>" to patch
41 -I --include include names matching the given patterns
41 -I --include include names matching the given patterns
42 -X --exclude exclude names matching the given patterns
42 -X --exclude exclude names matching the given patterns
43 -m --message use <text> as commit message
43 -m --message use <text> as commit message
44 -l --logfile read commit message from <file>
44 -l --logfile read commit message from <file>
45
45
46 use "hg -v help qrecord" to show global options
46 use "hg -v help qrecord" to show global options
47 % base commit
47 % base commit
48 % changing files
48 % changing files
49 % whole diff
49 % whole diff
50 diff -r 1057167b20ef 1.txt
50 diff -r 1057167b20ef 1.txt
51 --- a/1.txt
51 --- a/1.txt
52 +++ b/1.txt
52 +++ b/1.txt
53 @@ -1,5 +1,5 @@
53 @@ -1,5 +1,5 @@
54 1
54 1
55 -2
55 -2
56 +2 2
56 +2 2
57 3
57 3
58 -4
58 -4
59 +4 4
59 +4 4
60 5
60 5
61 diff -r 1057167b20ef 2.txt
61 diff -r 1057167b20ef 2.txt
62 --- a/2.txt
62 --- a/2.txt
63 +++ b/2.txt
63 +++ b/2.txt
64 @@ -1,5 +1,5 @@
64 @@ -1,5 +1,5 @@
65 a
65 a
66 -b
66 -b
67 +b b
67 +b b
68 c
68 c
69 d
69 d
70 e
70 e
71 diff -r 1057167b20ef dir/a.txt
71 diff -r 1057167b20ef dir/a.txt
72 --- a/dir/a.txt
72 --- a/dir/a.txt
73 +++ b/dir/a.txt
73 +++ b/dir/a.txt
74 @@ -1,4 +1,4 @@
74 @@ -1,4 +1,4 @@
75 -hello world
75 -hello world
76 +hello world!
76 +hello world!
77
77
78 someone
78 someone
79 up
79 up
80 % qrecord a.patch
80 % qrecord a.patch
81 diff --git a/1.txt b/1.txt
81 diff --git a/1.txt b/1.txt
82 2 hunks, 4 lines changed
82 2 hunks, 4 lines changed
83 examine changes to '1.txt'? [Ynsfdaq?] @@ -1,3 +1,3 @@
83 examine changes to '1.txt'? [Ynsfdaq?]
84 @@ -1,3 +1,3 @@
84 1
85 1
85 -2
86 -2
86 +2 2
87 +2 2
87 3
88 3
88 record change 1/6 to '1.txt'? [Ynsfdaq?] @@ -3,3 +3,3 @@
89 record change 1/6 to '1.txt'? [Ynsfdaq?]
90 @@ -3,3 +3,3 @@
89 3
91 3
90 -4
92 -4
91 +4 4
93 +4 4
92 5
94 5
93 record change 2/6 to '1.txt'? [Ynsfdaq?] diff --git a/2.txt b/2.txt
95 record change 2/6 to '1.txt'? [Ynsfdaq?]
96 diff --git a/2.txt b/2.txt
94 1 hunks, 2 lines changed
97 1 hunks, 2 lines changed
95 examine changes to '2.txt'? [Ynsfdaq?] @@ -1,5 +1,5 @@
98 examine changes to '2.txt'? [Ynsfdaq?]
99 @@ -1,5 +1,5 @@
96 a
100 a
97 -b
101 -b
98 +b b
102 +b b
99 c
103 c
100 d
104 d
101 e
105 e
102 record change 4/6 to '2.txt'? [Ynsfdaq?] diff --git a/dir/a.txt b/dir/a.txt
106 record change 4/6 to '2.txt'? [Ynsfdaq?]
107 diff --git a/dir/a.txt b/dir/a.txt
103 1 hunks, 2 lines changed
108 1 hunks, 2 lines changed
104 examine changes to 'dir/a.txt'? [Ynsfdaq?]
109 examine changes to 'dir/a.txt'? [Ynsfdaq?]
110
105 % after qrecord a.patch 'tip'
111 % after qrecord a.patch 'tip'
106 changeset: 1:5d1ca63427ee
112 changeset: 1:5d1ca63427ee
107 tag: qtip
113 tag: qtip
108 tag: tip
114 tag: tip
109 tag: a.patch
115 tag: a.patch
110 tag: qbase
116 tag: qbase
111 user: test
117 user: test
112 date: Thu Jan 01 00:00:00 1970 +0000
118 date: Thu Jan 01 00:00:00 1970 +0000
113 summary: aaa
119 summary: aaa
114
120
115 diff -r 1057167b20ef -r 5d1ca63427ee 1.txt
121 diff -r 1057167b20ef -r 5d1ca63427ee 1.txt
116 --- a/1.txt Thu Jan 01 00:00:00 1970 +0000
122 --- a/1.txt Thu Jan 01 00:00:00 1970 +0000
117 +++ b/1.txt Thu Jan 01 00:00:00 1970 +0000
123 +++ b/1.txt Thu Jan 01 00:00:00 1970 +0000
118 @@ -1,5 +1,5 @@
124 @@ -1,5 +1,5 @@
119 1
125 1
120 -2
126 -2
121 +2 2
127 +2 2
122 3
128 3
123 4
129 4
124 5
130 5
125 diff -r 1057167b20ef -r 5d1ca63427ee 2.txt
131 diff -r 1057167b20ef -r 5d1ca63427ee 2.txt
126 --- a/2.txt Thu Jan 01 00:00:00 1970 +0000
132 --- a/2.txt Thu Jan 01 00:00:00 1970 +0000
127 +++ b/2.txt Thu Jan 01 00:00:00 1970 +0000
133 +++ b/2.txt Thu Jan 01 00:00:00 1970 +0000
128 @@ -1,5 +1,5 @@
134 @@ -1,5 +1,5 @@
129 a
135 a
130 -b
136 -b
131 +b b
137 +b b
132 c
138 c
133 d
139 d
134 e
140 e
135
141
136
142
137 % after qrecord a.patch 'diff'
143 % after qrecord a.patch 'diff'
138 diff -r 5d1ca63427ee 1.txt
144 diff -r 5d1ca63427ee 1.txt
139 --- a/1.txt
145 --- a/1.txt
140 +++ b/1.txt
146 +++ b/1.txt
141 @@ -1,5 +1,5 @@
147 @@ -1,5 +1,5 @@
142 1
148 1
143 2 2
149 2 2
144 3
150 3
145 -4
151 -4
146 +4 4
152 +4 4
147 5
153 5
148 diff -r 5d1ca63427ee dir/a.txt
154 diff -r 5d1ca63427ee dir/a.txt
149 --- a/dir/a.txt
155 --- a/dir/a.txt
150 +++ b/dir/a.txt
156 +++ b/dir/a.txt
151 @@ -1,4 +1,4 @@
157 @@ -1,4 +1,4 @@
152 -hello world
158 -hello world
153 +hello world!
159 +hello world!
154
160
155 someone
161 someone
156 up
162 up
157 % qrecord b.patch
163 % qrecord b.patch
158 diff --git a/1.txt b/1.txt
164 diff --git a/1.txt b/1.txt
159 1 hunks, 2 lines changed
165 1 hunks, 2 lines changed
160 examine changes to '1.txt'? [Ynsfdaq?] @@ -1,5 +1,5 @@
166 examine changes to '1.txt'? [Ynsfdaq?]
167 @@ -1,5 +1,5 @@
161 1
168 1
162 2 2
169 2 2
163 3
170 3
164 -4
171 -4
165 +4 4
172 +4 4
166 5
173 5
167 record change 1/3 to '1.txt'? [Ynsfdaq?] diff --git a/dir/a.txt b/dir/a.txt
174 record change 1/3 to '1.txt'? [Ynsfdaq?]
175 diff --git a/dir/a.txt b/dir/a.txt
168 1 hunks, 2 lines changed
176 1 hunks, 2 lines changed
169 examine changes to 'dir/a.txt'? [Ynsfdaq?] @@ -1,4 +1,4 @@
177 examine changes to 'dir/a.txt'? [Ynsfdaq?]
178 @@ -1,4 +1,4 @@
170 -hello world
179 -hello world
171 +hello world!
180 +hello world!
172
181
173 someone
182 someone
174 up
183 up
175 record change 3/3 to 'dir/a.txt'? [Ynsfdaq?]
184 record change 3/3 to 'dir/a.txt'? [Ynsfdaq?]
185
176 % after qrecord b.patch 'tip'
186 % after qrecord b.patch 'tip'
177 changeset: 2:b056198bf878
187 changeset: 2:b056198bf878
178 tag: qtip
188 tag: qtip
179 tag: tip
189 tag: tip
180 tag: b.patch
190 tag: b.patch
181 user: test
191 user: test
182 date: Thu Jan 01 00:00:00 1970 +0000
192 date: Thu Jan 01 00:00:00 1970 +0000
183 summary: bbb
193 summary: bbb
184
194
185 diff -r 5d1ca63427ee -r b056198bf878 1.txt
195 diff -r 5d1ca63427ee -r b056198bf878 1.txt
186 --- a/1.txt Thu Jan 01 00:00:00 1970 +0000
196 --- a/1.txt Thu Jan 01 00:00:00 1970 +0000
187 +++ b/1.txt Thu Jan 01 00:00:00 1970 +0000
197 +++ b/1.txt Thu Jan 01 00:00:00 1970 +0000
188 @@ -1,5 +1,5 @@
198 @@ -1,5 +1,5 @@
189 1
199 1
190 2 2
200 2 2
191 3
201 3
192 -4
202 -4
193 +4 4
203 +4 4
194 5
204 5
195 diff -r 5d1ca63427ee -r b056198bf878 dir/a.txt
205 diff -r 5d1ca63427ee -r b056198bf878 dir/a.txt
196 --- a/dir/a.txt Thu Jan 01 00:00:00 1970 +0000
206 --- a/dir/a.txt Thu Jan 01 00:00:00 1970 +0000
197 +++ b/dir/a.txt Thu Jan 01 00:00:00 1970 +0000
207 +++ b/dir/a.txt Thu Jan 01 00:00:00 1970 +0000
198 @@ -1,4 +1,4 @@
208 @@ -1,4 +1,4 @@
199 -hello world
209 -hello world
200 +hello world!
210 +hello world!
201
211
202 someone
212 someone
203 up
213 up
204
214
205
215
206 % after qrecord b.patch 'diff'
216 % after qrecord b.patch 'diff'
207
217
208 % --- end ---
218 % --- end ---
@@ -1,595 +1,647 b''
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 options:
27 options:
28
28
29 -A --addremove mark new/missing files as added/removed before committing
29 -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
30 --close-branch mark a branch as closed, hiding it from the branch list
31 -I --include include names matching the given patterns
31 -I --include include names matching the given patterns
32 -X --exclude exclude names matching the given patterns
32 -X --exclude exclude names matching the given patterns
33 -m --message use <text> as commit message
33 -m --message use <text> as commit message
34 -l --logfile read commit message from <file>
34 -l --logfile read commit message from <file>
35 -d --date record datecode as commit date
35 -d --date record datecode as commit date
36 -u --user record the specified user as committer
36 -u --user record the specified user as committer
37
37
38 use "hg -v help record" to show global options
38 use "hg -v help record" to show global options
39 % select no files
39 % select no files
40 diff --git a/empty-rw b/empty-rw
40 diff --git a/empty-rw b/empty-rw
41 new file mode 100644
41 new file mode 100644
42 examine changes to 'empty-rw'? [Ynsfdaq?] no changes to record
42 examine changes to 'empty-rw'? [Ynsfdaq?]
43 no changes to record
43
44
44 changeset: -1:000000000000
45 changeset: -1:000000000000
45 tag: tip
46 tag: tip
46 user:
47 user:
47 date: Thu Jan 01 00:00:00 1970 +0000
48 date: Thu Jan 01 00:00:00 1970 +0000
48
49
49
50
50 % select files but no hunks
51 % select files but no hunks
51 diff --git a/empty-rw b/empty-rw
52 diff --git a/empty-rw b/empty-rw
52 new file mode 100644
53 new file mode 100644
53 examine changes to 'empty-rw'? [Ynsfdaq?] abort: empty commit message
54 examine changes to 'empty-rw'? [Ynsfdaq?]
55 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?]
67
65 changeset: 0:c0708cf4e46e
68 changeset: 0:c0708cf4e46e
66 tag: tip
69 tag: tip
67 user: test
70 user: test
68 date: Thu Jan 01 00:00:00 1970 +0000
71 date: Thu Jan 01 00:00:00 1970 +0000
69 summary: empty
72 summary: empty
70
73
71
74
72 % rename empty file
75 % rename empty file
73 diff --git a/empty-rw b/empty-rename
76 diff --git a/empty-rw b/empty-rename
74 rename from empty-rw
77 rename from empty-rw
75 rename to empty-rename
78 rename to empty-rename
76 examine changes to 'empty-rw' and 'empty-rename'? [Ynsfdaq?]
79 examine changes to 'empty-rw' and 'empty-rename'? [Ynsfdaq?]
80
77 changeset: 1:d695e8dcb197
81 changeset: 1:d695e8dcb197
78 tag: tip
82 tag: tip
79 user: test
83 user: test
80 date: Thu Jan 01 00:00:01 1970 +0000
84 date: Thu Jan 01 00:00:01 1970 +0000
81 summary: rename
85 summary: rename
82
86
83
87
84 % copy empty file
88 % copy empty file
85 diff --git a/empty-rename b/empty-copy
89 diff --git a/empty-rename b/empty-copy
86 copy from empty-rename
90 copy from empty-rename
87 copy to empty-copy
91 copy to empty-copy
88 examine changes to 'empty-rename' and 'empty-copy'? [Ynsfdaq?]
92 examine changes to 'empty-rename' and 'empty-copy'? [Ynsfdaq?]
93
89 changeset: 2:1d4b90bea524
94 changeset: 2:1d4b90bea524
90 tag: tip
95 tag: tip
91 user: test
96 user: test
92 date: Thu Jan 01 00:00:02 1970 +0000
97 date: Thu Jan 01 00:00:02 1970 +0000
93 summary: copy
98 summary: copy
94
99
95
100
96 % delete empty file
101 % delete empty file
97 diff --git a/empty-copy b/empty-copy
102 diff --git a/empty-copy b/empty-copy
98 deleted file mode 100644
103 deleted file mode 100644
99 examine changes to 'empty-copy'? [Ynsfdaq?]
104 examine changes to 'empty-copy'? [Ynsfdaq?]
105
100 changeset: 3:b39a238f01a1
106 changeset: 3:b39a238f01a1
101 tag: tip
107 tag: tip
102 user: test
108 user: test
103 date: Thu Jan 01 00:00:03 1970 +0000
109 date: Thu Jan 01 00:00:03 1970 +0000
104 summary: delete
110 summary: delete
105
111
106
112
107 % add binary file
113 % add binary file
108 1 changesets found
114 1 changesets found
109 diff --git a/tip.bundle b/tip.bundle
115 diff --git a/tip.bundle b/tip.bundle
110 new file mode 100644
116 new file mode 100644
111 this is a binary file
117 this is a binary file
112 examine changes to 'tip.bundle'? [Ynsfdaq?]
118 examine changes to 'tip.bundle'? [Ynsfdaq?]
119
113 changeset: 4:ad816da3711e
120 changeset: 4:ad816da3711e
114 tag: tip
121 tag: tip
115 user: test
122 user: test
116 date: Thu Jan 01 00:00:04 1970 +0000
123 date: Thu Jan 01 00:00:04 1970 +0000
117 summary: binary
124 summary: binary
118
125
119 diff -r b39a238f01a1 -r ad816da3711e tip.bundle
126 diff -r b39a238f01a1 -r ad816da3711e tip.bundle
120 Binary file tip.bundle has changed
127 Binary file tip.bundle has changed
121
128
122 % change binary file
129 % change binary file
123 1 changesets found
130 1 changesets found
124 diff --git a/tip.bundle b/tip.bundle
131 diff --git a/tip.bundle b/tip.bundle
125 this modifies a binary file (all or nothing)
132 this modifies a binary file (all or nothing)
126 examine changes to 'tip.bundle'? [Ynsfdaq?]
133 examine changes to 'tip.bundle'? [Ynsfdaq?]
134
127 changeset: 5:dccd6f3eb485
135 changeset: 5:dccd6f3eb485
128 tag: tip
136 tag: tip
129 user: test
137 user: test
130 date: Thu Jan 01 00:00:05 1970 +0000
138 date: Thu Jan 01 00:00:05 1970 +0000
131 summary: binary-change
139 summary: binary-change
132
140
133 diff -r ad816da3711e -r dccd6f3eb485 tip.bundle
141 diff -r ad816da3711e -r dccd6f3eb485 tip.bundle
134 Binary file tip.bundle has changed
142 Binary file tip.bundle has changed
135
143
136 % rename and change binary file
144 % rename and change binary file
137 1 changesets found
145 1 changesets found
138 diff --git a/tip.bundle b/top.bundle
146 diff --git a/tip.bundle b/top.bundle
139 rename from tip.bundle
147 rename from tip.bundle
140 rename to top.bundle
148 rename to top.bundle
141 this modifies a binary file (all or nothing)
149 this modifies a binary file (all or nothing)
142 examine changes to 'tip.bundle' and 'top.bundle'? [Ynsfdaq?]
150 examine changes to 'tip.bundle' and 'top.bundle'? [Ynsfdaq?]
151
143 changeset: 6:7fa44105f5b3
152 changeset: 6:7fa44105f5b3
144 tag: tip
153 tag: tip
145 user: test
154 user: test
146 date: Thu Jan 01 00:00:06 1970 +0000
155 date: Thu Jan 01 00:00:06 1970 +0000
147 summary: binary-change-rename
156 summary: binary-change-rename
148
157
149 diff -r dccd6f3eb485 -r 7fa44105f5b3 tip.bundle
158 diff -r dccd6f3eb485 -r 7fa44105f5b3 tip.bundle
150 Binary file tip.bundle has changed
159 Binary file tip.bundle has changed
151 diff -r dccd6f3eb485 -r 7fa44105f5b3 top.bundle
160 diff -r dccd6f3eb485 -r 7fa44105f5b3 top.bundle
152 Binary file top.bundle has changed
161 Binary file top.bundle has changed
153
162
154 % add plain file
163 % add plain file
155 diff --git a/plain b/plain
164 diff --git a/plain b/plain
156 new file mode 100644
165 new file mode 100644
157 examine changes to 'plain'? [Ynsfdaq?]
166 examine changes to 'plain'? [Ynsfdaq?]
167
158 changeset: 7:11fb457c1be4
168 changeset: 7:11fb457c1be4
159 tag: tip
169 tag: tip
160 user: test
170 user: test
161 date: Thu Jan 01 00:00:07 1970 +0000
171 date: Thu Jan 01 00:00:07 1970 +0000
162 summary: plain
172 summary: plain
163
173
164 diff -r 7fa44105f5b3 -r 11fb457c1be4 plain
174 diff -r 7fa44105f5b3 -r 11fb457c1be4 plain
165 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
175 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
166 +++ b/plain Thu Jan 01 00:00:07 1970 +0000
176 +++ b/plain Thu Jan 01 00:00:07 1970 +0000
167 @@ -0,0 +1,10 @@
177 @@ -0,0 +1,10 @@
168 +1
178 +1
169 +2
179 +2
170 +3
180 +3
171 +4
181 +4
172 +5
182 +5
173 +6
183 +6
174 +7
184 +7
175 +8
185 +8
176 +9
186 +9
177 +10
187 +10
178
188
179 % modify end of plain file
189 % modify end of plain file
180 diff --git a/plain b/plain
190 diff --git a/plain b/plain
181 1 hunks, 1 lines changed
191 1 hunks, 1 lines changed
182 examine changes to 'plain'? [Ynsfdaq?] @@ -8,3 +8,4 @@
192 examine changes to 'plain'? [Ynsfdaq?]
193 @@ -8,3 +8,4 @@
183 8
194 8
184 9
195 9
185 10
196 10
186 +11
197 +11
187 record this change to 'plain'? [Ynsfdaq?] % modify end of plain file, no EOL
198 record this change to 'plain'? [Ynsfdaq?]
199 % modify end of plain file, no EOL
188 diff --git a/plain b/plain
200 diff --git a/plain b/plain
189 1 hunks, 1 lines changed
201 1 hunks, 1 lines changed
190 examine changes to 'plain'? [Ynsfdaq?] @@ -9,3 +9,4 @@
202 examine changes to 'plain'? [Ynsfdaq?]
203 @@ -9,3 +9,4 @@
191 9
204 9
192 10
205 10
193 11
206 11
194 +7264f99c5f5ff3261504828afa4fb4d406c3af54
207 +7264f99c5f5ff3261504828afa4fb4d406c3af54
195 \ No newline at end of file
208 \ No newline at end of file
196 record this change to 'plain'? [Ynsfdaq?] % modify end of plain file, add EOL
209 record this change to 'plain'? [Ynsfdaq?]
210 % modify end of plain file, add EOL
197 diff --git a/plain b/plain
211 diff --git a/plain b/plain
198 1 hunks, 2 lines changed
212 1 hunks, 2 lines changed
199 examine changes to 'plain'? [Ynsfdaq?] @@ -9,4 +9,4 @@
213 examine changes to 'plain'? [Ynsfdaq?]
214 @@ -9,4 +9,4 @@
200 9
215 9
201 10
216 10
202 11
217 11
203 -7264f99c5f5ff3261504828afa4fb4d406c3af54
218 -7264f99c5f5ff3261504828afa4fb4d406c3af54
204 \ No newline at end of file
219 \ No newline at end of file
205 +7264f99c5f5ff3261504828afa4fb4d406c3af54
220 +7264f99c5f5ff3261504828afa4fb4d406c3af54
206 record this change to 'plain'? [Ynsfdaq?] % modify beginning, trim end, record both
221 record this change to 'plain'? [Ynsfdaq?]
222 % modify beginning, trim end, record both
207 diff --git a/plain b/plain
223 diff --git a/plain b/plain
208 2 hunks, 4 lines changed
224 2 hunks, 4 lines changed
209 examine changes to 'plain'? [Ynsfdaq?] @@ -1,4 +1,4 @@
225 examine changes to 'plain'? [Ynsfdaq?]
226 @@ -1,4 +1,4 @@
210 -1
227 -1
211 +2
228 +2
212 2
229 2
213 3
230 3
214 4
231 4
215 record change 1/2 to 'plain'? [Ynsfdaq?] @@ -8,5 +8,3 @@
232 record change 1/2 to 'plain'? [Ynsfdaq?]
233 @@ -8,5 +8,3 @@
216 8
234 8
217 9
235 9
218 10
236 10
219 -11
237 -11
220 -7264f99c5f5ff3261504828afa4fb4d406c3af54
238 -7264f99c5f5ff3261504828afa4fb4d406c3af54
221 record change 2/2 to 'plain'? [Ynsfdaq?]
239 record change 2/2 to 'plain'? [Ynsfdaq?]
240
222 changeset: 11:efca65c9b09e
241 changeset: 11:efca65c9b09e
223 tag: tip
242 tag: tip
224 user: test
243 user: test
225 date: Thu Jan 01 00:00:10 1970 +0000
244 date: Thu Jan 01 00:00:10 1970 +0000
226 summary: begin-and-end
245 summary: begin-and-end
227
246
228 diff -r cd07d48e8cbe -r efca65c9b09e plain
247 diff -r cd07d48e8cbe -r efca65c9b09e plain
229 --- a/plain Thu Jan 01 00:00:10 1970 +0000
248 --- a/plain Thu Jan 01 00:00:10 1970 +0000
230 +++ b/plain Thu Jan 01 00:00:10 1970 +0000
249 +++ b/plain Thu Jan 01 00:00:10 1970 +0000
231 @@ -1,4 +1,4 @@
250 @@ -1,4 +1,4 @@
232 -1
251 -1
233 +2
252 +2
234 2
253 2
235 3
254 3
236 4
255 4
237 @@ -8,5 +8,3 @@
256 @@ -8,5 +8,3 @@
238 8
257 8
239 9
258 9
240 10
259 10
241 -11
260 -11
242 -7264f99c5f5ff3261504828afa4fb4d406c3af54
261 -7264f99c5f5ff3261504828afa4fb4d406c3af54
243
262
244 % trim beginning, modify end
263 % trim beginning, modify end
245 % record end
264 % record end
246 diff --git a/plain b/plain
265 diff --git a/plain b/plain
247 2 hunks, 5 lines changed
266 2 hunks, 5 lines changed
248 examine changes to 'plain'? [Ynsfdaq?] @@ -1,9 +1,6 @@
267 examine changes to 'plain'? [Ynsfdaq?]
268 @@ -1,9 +1,6 @@
249 -2
269 -2
250 -2
270 -2
251 -3
271 -3
252 4
272 4
253 5
273 5
254 6
274 6
255 7
275 7
256 8
276 8
257 9
277 9
258 record change 1/2 to 'plain'? [Ynsfdaq?] @@ -4,7 +1,7 @@
278 record change 1/2 to 'plain'? [Ynsfdaq?]
279 @@ -4,7 +1,7 @@
259 4
280 4
260 5
281 5
261 6
282 6
262 7
283 7
263 8
284 8
264 9
285 9
265 -10
286 -10
266 +10.new
287 +10.new
267 record change 2/2 to 'plain'? [Ynsfdaq?]
288 record change 2/2 to 'plain'? [Ynsfdaq?]
289
268 changeset: 12:7d1e66983c15
290 changeset: 12:7d1e66983c15
269 tag: tip
291 tag: tip
270 user: test
292 user: test
271 date: Thu Jan 01 00:00:11 1970 +0000
293 date: Thu Jan 01 00:00:11 1970 +0000
272 summary: end-only
294 summary: end-only
273
295
274 diff -r efca65c9b09e -r 7d1e66983c15 plain
296 diff -r efca65c9b09e -r 7d1e66983c15 plain
275 --- a/plain Thu Jan 01 00:00:10 1970 +0000
297 --- a/plain Thu Jan 01 00:00:10 1970 +0000
276 +++ b/plain Thu Jan 01 00:00:11 1970 +0000
298 +++ b/plain Thu Jan 01 00:00:11 1970 +0000
277 @@ -7,4 +7,4 @@
299 @@ -7,4 +7,4 @@
278 7
300 7
279 8
301 8
280 9
302 9
281 -10
303 -10
282 +10.new
304 +10.new
283
305
284 % record beginning
306 % record beginning
285 diff --git a/plain b/plain
307 diff --git a/plain b/plain
286 1 hunks, 3 lines changed
308 1 hunks, 3 lines changed
287 examine changes to 'plain'? [Ynsfdaq?] @@ -1,6 +1,3 @@
309 examine changes to 'plain'? [Ynsfdaq?]
310 @@ -1,6 +1,3 @@
288 -2
311 -2
289 -2
312 -2
290 -3
313 -3
291 4
314 4
292 5
315 5
293 6
316 6
294 record this change to 'plain'? [Ynsfdaq?]
317 record this change to 'plain'? [Ynsfdaq?]
318
295 changeset: 13:a09fc62a0e61
319 changeset: 13:a09fc62a0e61
296 tag: tip
320 tag: tip
297 user: test
321 user: test
298 date: Thu Jan 01 00:00:12 1970 +0000
322 date: Thu Jan 01 00:00:12 1970 +0000
299 summary: begin-only
323 summary: begin-only
300
324
301 diff -r 7d1e66983c15 -r a09fc62a0e61 plain
325 diff -r 7d1e66983c15 -r a09fc62a0e61 plain
302 --- a/plain Thu Jan 01 00:00:11 1970 +0000
326 --- a/plain Thu Jan 01 00:00:11 1970 +0000
303 +++ b/plain Thu Jan 01 00:00:12 1970 +0000
327 +++ b/plain Thu Jan 01 00:00:12 1970 +0000
304 @@ -1,6 +1,3 @@
328 @@ -1,6 +1,3 @@
305 -2
329 -2
306 -2
330 -2
307 -3
331 -3
308 4
332 4
309 5
333 5
310 6
334 6
311
335
312 % add to beginning, trim from end
336 % add to beginning, trim from end
313 % record end
337 % record end
314 diff --git a/plain b/plain
338 diff --git a/plain b/plain
315 2 hunks, 4 lines changed
339 2 hunks, 4 lines changed
316 examine changes to 'plain'? [Ynsfdaq?] @@ -1,6 +1,9 @@
340 examine changes to 'plain'? [Ynsfdaq?]
341 @@ -1,6 +1,9 @@
317 +1
342 +1
318 +2
343 +2
319 +3
344 +3
320 4
345 4
321 5
346 5
322 6
347 6
323 7
348 7
324 8
349 8
325 9
350 9
326 record change 1/2 to 'plain'? [Ynsfdaq?] @@ -1,7 +4,6 @@
351 record change 1/2 to 'plain'? [Ynsfdaq?]
352 @@ -1,7 +4,6 @@
327 4
353 4
328 5
354 5
329 6
355 6
330 7
356 7
331 8
357 8
332 9
358 9
333 -10.new
359 -10.new
334 record change 2/2 to 'plain'? [Ynsfdaq?] % add to beginning, middle, end
360 record change 2/2 to 'plain'? [Ynsfdaq?]
361 % add to beginning, middle, end
335 % record beginning, middle
362 % record beginning, middle
336 diff --git a/plain b/plain
363 diff --git a/plain b/plain
337 3 hunks, 7 lines changed
364 3 hunks, 7 lines changed
338 examine changes to 'plain'? [Ynsfdaq?] @@ -1,2 +1,5 @@
365 examine changes to 'plain'? [Ynsfdaq?]
366 @@ -1,2 +1,5 @@
339 +1
367 +1
340 +2
368 +2
341 +3
369 +3
342 4
370 4
343 5
371 5
344 record change 1/3 to 'plain'? [Ynsfdaq?] @@ -1,6 +4,8 @@
372 record change 1/3 to 'plain'? [Ynsfdaq?]
373 @@ -1,6 +4,8 @@
345 4
374 4
346 5
375 5
347 +5.new
376 +5.new
348 +5.reallynew
377 +5.reallynew
349 6
378 6
350 7
379 7
351 8
380 8
352 9
381 9
353 record change 2/3 to 'plain'? [Ynsfdaq?] @@ -3,4 +8,6 @@
382 record change 2/3 to 'plain'? [Ynsfdaq?]
383 @@ -3,4 +8,6 @@
354 6
384 6
355 7
385 7
356 8
386 8
357 9
387 9
358 +10
388 +10
359 +11
389 +11
360 record change 3/3 to 'plain'? [Ynsfdaq?]
390 record change 3/3 to 'plain'? [Ynsfdaq?]
391
361 changeset: 15:7d137997f3a6
392 changeset: 15:7d137997f3a6
362 tag: tip
393 tag: tip
363 user: test
394 user: test
364 date: Thu Jan 01 00:00:14 1970 +0000
395 date: Thu Jan 01 00:00:14 1970 +0000
365 summary: middle-only
396 summary: middle-only
366
397
367 diff -r c0b8e5fb0be6 -r 7d137997f3a6 plain
398 diff -r c0b8e5fb0be6 -r 7d137997f3a6 plain
368 --- a/plain Thu Jan 01 00:00:13 1970 +0000
399 --- a/plain Thu Jan 01 00:00:13 1970 +0000
369 +++ b/plain Thu Jan 01 00:00:14 1970 +0000
400 +++ b/plain Thu Jan 01 00:00:14 1970 +0000
370 @@ -1,5 +1,10 @@
401 @@ -1,5 +1,10 @@
371 +1
402 +1
372 +2
403 +2
373 +3
404 +3
374 4
405 4
375 5
406 5
376 +5.new
407 +5.new
377 +5.reallynew
408 +5.reallynew
378 6
409 6
379 7
410 7
380 8
411 8
381
412
382 % record end
413 % record end
383 diff --git a/plain b/plain
414 diff --git a/plain b/plain
384 1 hunks, 2 lines changed
415 1 hunks, 2 lines changed
385 examine changes to 'plain'? [Ynsfdaq?] @@ -9,3 +9,5 @@
416 examine changes to 'plain'? [Ynsfdaq?]
417 @@ -9,3 +9,5 @@
386 7
418 7
387 8
419 8
388 9
420 9
389 +10
421 +10
390 +11
422 +11
391 record this change to 'plain'? [Ynsfdaq?]
423 record this change to 'plain'? [Ynsfdaq?]
424
392 changeset: 16:4959e3ff13eb
425 changeset: 16:4959e3ff13eb
393 tag: tip
426 tag: tip
394 user: test
427 user: test
395 date: Thu Jan 01 00:00:15 1970 +0000
428 date: Thu Jan 01 00:00:15 1970 +0000
396 summary: end-only
429 summary: end-only
397
430
398 diff -r 7d137997f3a6 -r 4959e3ff13eb plain
431 diff -r 7d137997f3a6 -r 4959e3ff13eb plain
399 --- a/plain Thu Jan 01 00:00:14 1970 +0000
432 --- a/plain Thu Jan 01 00:00:14 1970 +0000
400 +++ b/plain Thu Jan 01 00:00:15 1970 +0000
433 +++ b/plain Thu Jan 01 00:00:15 1970 +0000
401 @@ -9,3 +9,5 @@
434 @@ -9,3 +9,5 @@
402 7
435 7
403 8
436 8
404 9
437 9
405 +10
438 +10
406 +11
439 +11
407
440
408 adding subdir/a
441 adding subdir/a
409 diff --git a/subdir/a b/subdir/a
442 diff --git a/subdir/a b/subdir/a
410 1 hunks, 1 lines changed
443 1 hunks, 1 lines changed
411 examine changes to 'subdir/a'? [Ynsfdaq?] @@ -1,1 +1,2 @@
444 examine changes to 'subdir/a'? [Ynsfdaq?]
445 @@ -1,1 +1,2 @@
412 a
446 a
413 +a
447 +a
414 record this change to 'subdir/a'? [Ynsfdaq?]
448 record this change to 'subdir/a'? [Ynsfdaq?]
449
415 changeset: 18:40698cd490b2
450 changeset: 18:40698cd490b2
416 tag: tip
451 tag: tip
417 user: test
452 user: test
418 date: Thu Jan 01 00:00:16 1970 +0000
453 date: Thu Jan 01 00:00:16 1970 +0000
419 summary: subdir-change
454 summary: subdir-change
420
455
421 diff -r 661eacdc08b9 -r 40698cd490b2 subdir/a
456 diff -r 661eacdc08b9 -r 40698cd490b2 subdir/a
422 --- a/subdir/a Thu Jan 01 00:00:16 1970 +0000
457 --- a/subdir/a Thu Jan 01 00:00:16 1970 +0000
423 +++ b/subdir/a Thu Jan 01 00:00:16 1970 +0000
458 +++ b/subdir/a Thu Jan 01 00:00:16 1970 +0000
424 @@ -1,1 +1,2 @@
459 @@ -1,1 +1,2 @@
425 a
460 a
426 +a
461 +a
427
462
428 % help, quit
463 % help, quit
429 diff --git a/subdir/f1 b/subdir/f1
464 diff --git a/subdir/f1 b/subdir/f1
430 1 hunks, 1 lines changed
465 1 hunks, 1 lines changed
431 examine changes to 'subdir/f1'? [Ynsfdaq?] y - record this change
466 examine changes to 'subdir/f1'? [Ynsfdaq?]
467 y - record this change
432 n - skip this change
468 n - skip this change
433 s - skip remaining changes to this file
469 s - skip remaining changes to this file
434 f - record remaining changes to this file
470 f - record remaining changes to this file
435 d - done, skip remaining changes and files
471 d - done, skip remaining changes and files
436 a - record all changes to all remaining files
472 a - record all changes to all remaining files
437 q - quit, recording no changes
473 q - quit, recording no changes
438 ? - display help
474 ? - display help
439 examine changes to 'subdir/f1'? [Ynsfdaq?] abort: user quit
475 examine changes to 'subdir/f1'? [Ynsfdaq?]
476 abort: user quit
440 % skip
477 % skip
441 diff --git a/subdir/f1 b/subdir/f1
478 diff --git a/subdir/f1 b/subdir/f1
442 1 hunks, 1 lines changed
479 1 hunks, 1 lines changed
443 examine changes to 'subdir/f1'? [Ynsfdaq?] diff --git a/subdir/f2 b/subdir/f2
480 examine changes to 'subdir/f1'? [Ynsfdaq?]
481 diff --git a/subdir/f2 b/subdir/f2
444 1 hunks, 1 lines changed
482 1 hunks, 1 lines changed
445 examine changes to 'subdir/f2'? [Ynsfdaq?] abort: response expected
483 examine changes to 'subdir/f2'? [Ynsfdaq?] abort: response expected
446 % no
484 % no
447 diff --git a/subdir/f1 b/subdir/f1
485 diff --git a/subdir/f1 b/subdir/f1
448 1 hunks, 1 lines changed
486 1 hunks, 1 lines changed
449 examine changes to 'subdir/f1'? [Ynsfdaq?] diff --git a/subdir/f2 b/subdir/f2
487 examine changes to 'subdir/f1'? [Ynsfdaq?]
488 diff --git a/subdir/f2 b/subdir/f2
450 1 hunks, 1 lines changed
489 1 hunks, 1 lines changed
451 examine changes to 'subdir/f2'? [Ynsfdaq?] abort: response expected
490 examine changes to 'subdir/f2'? [Ynsfdaq?] abort: response expected
452 % f, quit
491 % f, quit
453 diff --git a/subdir/f1 b/subdir/f1
492 diff --git a/subdir/f1 b/subdir/f1
454 1 hunks, 1 lines changed
493 1 hunks, 1 lines changed
455 examine changes to 'subdir/f1'? [Ynsfdaq?] diff --git a/subdir/f2 b/subdir/f2
494 examine changes to 'subdir/f1'? [Ynsfdaq?]
495 diff --git a/subdir/f2 b/subdir/f2
456 1 hunks, 1 lines changed
496 1 hunks, 1 lines changed
457 examine changes to 'subdir/f2'? [Ynsfdaq?] abort: user quit
497 examine changes to 'subdir/f2'? [Ynsfdaq?]
498 abort: user quit
458 % s, all
499 % s, all
459 diff --git a/subdir/f1 b/subdir/f1
500 diff --git a/subdir/f1 b/subdir/f1
460 1 hunks, 1 lines changed
501 1 hunks, 1 lines changed
461 examine changes to 'subdir/f1'? [Ynsfdaq?] diff --git a/subdir/f2 b/subdir/f2
502 examine changes to 'subdir/f1'? [Ynsfdaq?]
503 diff --git a/subdir/f2 b/subdir/f2
462 1 hunks, 1 lines changed
504 1 hunks, 1 lines changed
463 examine changes to 'subdir/f2'? [Ynsfdaq?]
505 examine changes to 'subdir/f2'? [Ynsfdaq?]
506
464 changeset: 20:d2d8c25276a8
507 changeset: 20:d2d8c25276a8
465 tag: tip
508 tag: tip
466 user: test
509 user: test
467 date: Thu Jan 01 00:00:18 1970 +0000
510 date: Thu Jan 01 00:00:18 1970 +0000
468 summary: x
511 summary: x
469
512
470 diff -r 25eb2a7694fb -r d2d8c25276a8 subdir/f2
513 diff -r 25eb2a7694fb -r d2d8c25276a8 subdir/f2
471 --- a/subdir/f2 Thu Jan 01 00:00:17 1970 +0000
514 --- a/subdir/f2 Thu Jan 01 00:00:17 1970 +0000
472 +++ b/subdir/f2 Thu Jan 01 00:00:18 1970 +0000
515 +++ b/subdir/f2 Thu Jan 01 00:00:18 1970 +0000
473 @@ -1,1 +1,2 @@
516 @@ -1,1 +1,2 @@
474 b
517 b
475 +b
518 +b
476
519
477 % f
520 % f
478 diff --git a/subdir/f1 b/subdir/f1
521 diff --git a/subdir/f1 b/subdir/f1
479 1 hunks, 1 lines changed
522 1 hunks, 1 lines changed
480 examine changes to 'subdir/f1'? [Ynsfdaq?]
523 examine changes to 'subdir/f1'? [Ynsfdaq?]
524
481 changeset: 21:1013f51ce32f
525 changeset: 21:1013f51ce32f
482 tag: tip
526 tag: tip
483 user: test
527 user: test
484 date: Thu Jan 01 00:00:19 1970 +0000
528 date: Thu Jan 01 00:00:19 1970 +0000
485 summary: y
529 summary: y
486
530
487 diff -r d2d8c25276a8 -r 1013f51ce32f subdir/f1
531 diff -r d2d8c25276a8 -r 1013f51ce32f subdir/f1
488 --- a/subdir/f1 Thu Jan 01 00:00:18 1970 +0000
532 --- a/subdir/f1 Thu Jan 01 00:00:18 1970 +0000
489 +++ b/subdir/f1 Thu Jan 01 00:00:19 1970 +0000
533 +++ b/subdir/f1 Thu Jan 01 00:00:19 1970 +0000
490 @@ -1,1 +1,2 @@
534 @@ -1,1 +1,2 @@
491 a
535 a
492 +a
536 +a
493
537
494 % preserve chmod +x
538 % preserve chmod +x
495 diff --git a/subdir/f1 b/subdir/f1
539 diff --git a/subdir/f1 b/subdir/f1
496 old mode 100644
540 old mode 100644
497 new mode 100755
541 new mode 100755
498 1 hunks, 1 lines changed
542 1 hunks, 1 lines changed
499 examine changes to 'subdir/f1'? [Ynsfdaq?] @@ -1,2 +1,3 @@
543 examine changes to 'subdir/f1'? [Ynsfdaq?]
544 @@ -1,2 +1,3 @@
500 a
545 a
501 a
546 a
502 +a
547 +a
503 record this change to 'subdir/f1'? [Ynsfdaq?]
548 record this change to 'subdir/f1'? [Ynsfdaq?]
549
504 changeset: 22:5df857735621
550 changeset: 22:5df857735621
505 tag: tip
551 tag: tip
506 user: test
552 user: test
507 date: Thu Jan 01 00:00:20 1970 +0000
553 date: Thu Jan 01 00:00:20 1970 +0000
508 summary: z
554 summary: z
509
555
510 diff --git a/subdir/f1 b/subdir/f1
556 diff --git a/subdir/f1 b/subdir/f1
511 old mode 100644
557 old mode 100644
512 new mode 100755
558 new mode 100755
513 --- a/subdir/f1
559 --- a/subdir/f1
514 +++ b/subdir/f1
560 +++ b/subdir/f1
515 @@ -1,2 +1,3 @@
561 @@ -1,2 +1,3 @@
516 a
562 a
517 a
563 a
518 +a
564 +a
519
565
520 % preserve execute permission on original
566 % preserve execute permission on original
521 diff --git a/subdir/f1 b/subdir/f1
567 diff --git a/subdir/f1 b/subdir/f1
522 1 hunks, 1 lines changed
568 1 hunks, 1 lines changed
523 examine changes to 'subdir/f1'? [Ynsfdaq?] @@ -1,3 +1,4 @@
569 examine changes to 'subdir/f1'? [Ynsfdaq?]
570 @@ -1,3 +1,4 @@
524 a
571 a
525 a
572 a
526 a
573 a
527 +b
574 +b
528 record this change to 'subdir/f1'? [Ynsfdaq?]
575 record this change to 'subdir/f1'? [Ynsfdaq?]
576
529 changeset: 23:a4ae36a78715
577 changeset: 23:a4ae36a78715
530 tag: tip
578 tag: tip
531 user: test
579 user: test
532 date: Thu Jan 01 00:00:21 1970 +0000
580 date: Thu Jan 01 00:00:21 1970 +0000
533 summary: aa
581 summary: aa
534
582
535 diff --git a/subdir/f1 b/subdir/f1
583 diff --git a/subdir/f1 b/subdir/f1
536 --- a/subdir/f1
584 --- a/subdir/f1
537 +++ b/subdir/f1
585 +++ b/subdir/f1
538 @@ -1,3 +1,4 @@
586 @@ -1,3 +1,4 @@
539 a
587 a
540 a
588 a
541 a
589 a
542 +b
590 +b
543
591
544 % preserve chmod -x
592 % preserve chmod -x
545 diff --git a/subdir/f1 b/subdir/f1
593 diff --git a/subdir/f1 b/subdir/f1
546 old mode 100755
594 old mode 100755
547 new mode 100644
595 new mode 100644
548 1 hunks, 1 lines changed
596 1 hunks, 1 lines changed
549 examine changes to 'subdir/f1'? [Ynsfdaq?] @@ -2,3 +2,4 @@
597 examine changes to 'subdir/f1'? [Ynsfdaq?]
598 @@ -2,3 +2,4 @@
550 a
599 a
551 a
600 a
552 b
601 b
553 +c
602 +c
554 record this change to 'subdir/f1'? [Ynsfdaq?]
603 record this change to 'subdir/f1'? [Ynsfdaq?]
604
555 changeset: 24:1460f6e47966
605 changeset: 24:1460f6e47966
556 tag: tip
606 tag: tip
557 user: test
607 user: test
558 date: Thu Jan 01 00:00:22 1970 +0000
608 date: Thu Jan 01 00:00:22 1970 +0000
559 summary: ab
609 summary: ab
560
610
561 diff --git a/subdir/f1 b/subdir/f1
611 diff --git a/subdir/f1 b/subdir/f1
562 old mode 100755
612 old mode 100755
563 new mode 100644
613 new mode 100644
564 --- a/subdir/f1
614 --- a/subdir/f1
565 +++ b/subdir/f1
615 +++ b/subdir/f1
566 @@ -2,3 +2,4 @@
616 @@ -2,3 +2,4 @@
567 a
617 a
568 a
618 a
569 b
619 b
570 +c
620 +c
571
621
572 % with win32ext
622 % with win32ext
573 diff --git a/subdir/f1 b/subdir/f1
623 diff --git a/subdir/f1 b/subdir/f1
574 1 hunks, 1 lines changed
624 1 hunks, 1 lines changed
575 examine changes to 'subdir/f1'? [Ynsfdaq?] @@ -3,3 +3,4 @@
625 examine changes to 'subdir/f1'? [Ynsfdaq?]
626 @@ -3,3 +3,4 @@
576 a
627 a
577 b
628 b
578 c
629 c
579 +d
630 +d
580 record this change to 'subdir/f1'? [Ynsfdaq?]
631 record this change to 'subdir/f1'? [Ynsfdaq?]
632
581 changeset: 25:5bacc1f6e9cf
633 changeset: 25:5bacc1f6e9cf
582 tag: tip
634 tag: tip
583 user: test
635 user: test
584 date: Thu Jan 01 00:00:23 1970 +0000
636 date: Thu Jan 01 00:00:23 1970 +0000
585 summary: w1
637 summary: w1
586
638
587 diff -r 1460f6e47966 -r 5bacc1f6e9cf subdir/f1
639 diff -r 1460f6e47966 -r 5bacc1f6e9cf subdir/f1
588 --- a/subdir/f1 Thu Jan 01 00:00:22 1970 +0000
640 --- a/subdir/f1 Thu Jan 01 00:00:22 1970 +0000
589 +++ b/subdir/f1 Thu Jan 01 00:00:23 1970 +0000
641 +++ b/subdir/f1 Thu Jan 01 00:00:23 1970 +0000
590 @@ -3,3 +3,4 @@
642 @@ -3,3 +3,4 @@
591 a
643 a
592 b
644 b
593 c
645 c
594 +d
646 +d
595
647
General Comments 0
You need to be logged in to leave comments. Login now