##// END OF EJS Templates
Add record extension, giving darcs-like interactive hunk picking
Bryan O'Sullivan -
r5037:b2607267 default
parent child Browse files
Show More
@@ -0,0 +1,381 b''
1 # record.py
2 #
3 # Copyright 2007 Bryan O'Sullivan <bos@serpentine.com>
4 #
5 # This software may be used and distributed according to the terms of
6 # the GNU General Public License, incorporated herein by reference.
7
8 '''interactive change selection during commit'''
9
10 from mercurial.i18n import _
11 from mercurial import cmdutil, commands, cmdutil, hg, mdiff, patch, revlog
12 from mercurial import util
13 import copy, cStringIO, errno, operator, os, re, shutil, tempfile
14
15 lines_re = re.compile(r'@@ -(\d+),(\d+) \+(\d+),(\d+) @@\s*(.*)')
16
17 def scanpatch(fp):
18 lr = patch.linereader(fp)
19
20 def scanwhile(first, p):
21 lines = [first]
22 while True:
23 line = lr.readline()
24 if not line:
25 break
26 if p(line):
27 lines.append(line)
28 else:
29 lr.push(line)
30 break
31 return lines
32
33 while True:
34 line = lr.readline()
35 if not line:
36 break
37 if line.startswith('diff --git a/'):
38 def notheader(line):
39 s = line.split(None, 1)
40 return not s or s[0] not in ('---', 'diff')
41 header = scanwhile(line, notheader)
42 fromfile = lr.readline()
43 if fromfile.startswith('---'):
44 tofile = lr.readline()
45 header += [fromfile, tofile]
46 else:
47 lr.push(fromfile)
48 yield 'file', header
49 elif line[0] == ' ':
50 yield 'context', scanwhile(line, lambda l: l[0] in ' \\')
51 elif line[0] in '-+':
52 yield 'hunk', scanwhile(line, lambda l: l[0] in '-+\\')
53 else:
54 m = lines_re.match(line)
55 if m:
56 yield 'range', m.groups()
57 else:
58 raise patch.PatchError('unknown patch content: %r' % line)
59
60 class header(object):
61 diff_re = re.compile('diff --git a/(.*) b/(.*)$')
62 allhunks_re = re.compile('(?:index|new file|deleted file) ')
63 pretty_re = re.compile('(?:new file|deleted file) ')
64 special_re = re.compile('(?:index|new|deleted|copy|rename) ')
65
66 def __init__(self, header):
67 self.header = header
68 self.hunks = []
69
70 def binary(self):
71 for h in self.header:
72 if h.startswith('index '):
73 return True
74
75 def pretty(self, fp):
76 for h in self.header:
77 if h.startswith('index '):
78 fp.write(_('this modifies a binary file (all or nothing)\n'))
79 break
80 if self.pretty_re.match(h):
81 fp.write(h)
82 if self.binary():
83 fp.write(_('this is a binary file\n'))
84 break
85 if h.startswith('---'):
86 fp.write(_('%d hunks, %d lines changed\n') %
87 (len(self.hunks),
88 sum([h.added + h.removed for h in self.hunks])))
89 break
90 fp.write(h)
91
92 def write(self, fp):
93 fp.write(''.join(self.header))
94
95 def allhunks(self):
96 for h in self.header:
97 if self.allhunks_re.match(h):
98 return True
99
100 def files(self):
101 fromfile, tofile = self.diff_re.match(self.header[0]).groups()
102 if fromfile == tofile:
103 return [fromfile]
104 return [fromfile, tofile]
105
106 def filename(self):
107 return self.files()[-1]
108
109 def __repr__(self):
110 return '<header %s>' % (' '.join(map(repr, self.files())))
111
112 def special(self):
113 for h in self.header:
114 if self.special_re.match(h):
115 return True
116
117 def countchanges(hunk):
118 add = len([h for h in hunk if h[0] == '+'])
119 rem = len([h for h in hunk if h[0] == '-'])
120 return add, rem
121
122 class hunk(object):
123 maxcontext = 3
124
125 def __init__(self, header, fromline, toline, proc, before, hunk, after):
126 def trimcontext(number, lines):
127 delta = len(lines) - self.maxcontext
128 if False and delta > 0:
129 return number + delta, lines[:self.maxcontext]
130 return number, lines
131
132 self.header = header
133 self.fromline, self.before = trimcontext(fromline, before)
134 self.toline, self.after = trimcontext(toline, after)
135 self.proc = proc
136 self.hunk = hunk
137 self.added, self.removed = countchanges(self.hunk)
138
139 def write(self, fp):
140 delta = len(self.before) + len(self.after)
141 fromlen = delta + self.removed
142 tolen = delta + self.added
143 fp.write('@@ -%d,%d +%d,%d @@%s\n' %
144 (self.fromline, fromlen, self.toline, tolen,
145 self.proc and (' ' + self.proc)))
146 fp.write(''.join(self.before + self.hunk + self.after))
147
148 pretty = write
149
150 def filename(self):
151 return self.header.filename()
152
153 def __repr__(self):
154 return '<hunk %r@%d>' % (self.filename(), self.fromline)
155
156 def parsepatch(fp):
157 class parser(object):
158 def __init__(self):
159 self.fromline = 0
160 self.toline = 0
161 self.proc = ''
162 self.header = None
163 self.context = []
164 self.before = []
165 self.hunk = []
166 self.stream = []
167
168 def addrange(self, (fromstart, fromend, tostart, toend, proc)):
169 self.fromline = int(fromstart)
170 self.toline = int(tostart)
171 self.proc = proc
172
173 def addcontext(self, context):
174 if self.hunk:
175 h = hunk(self.header, self.fromline, self.toline, self.proc,
176 self.before, self.hunk, context)
177 self.header.hunks.append(h)
178 self.stream.append(h)
179 self.fromline += len(self.before) + h.removed
180 self.toline += len(self.before) + h.added
181 self.before = []
182 self.hunk = []
183 self.proc = ''
184 self.context = context
185
186 def addhunk(self, hunk):
187 if self.context:
188 self.before = self.context
189 self.context = []
190 self.hunk = data
191
192 def newfile(self, hdr):
193 self.addcontext([])
194 h = header(hdr)
195 self.stream.append(h)
196 self.header = h
197
198 def finished(self):
199 self.addcontext([])
200 return self.stream
201
202 transitions = {
203 'file': {'context': addcontext,
204 'file': newfile,
205 'hunk': addhunk,
206 'range': addrange},
207 'context': {'file': newfile,
208 'hunk': addhunk,
209 'range': addrange},
210 'hunk': {'context': addcontext,
211 'file': newfile,
212 'range': addrange},
213 'range': {'context': addcontext,
214 'hunk': addhunk},
215 }
216
217 p = parser()
218
219 state = 'context'
220 for newstate, data in scanpatch(fp):
221 try:
222 p.transitions[state][newstate](p, data)
223 except KeyError:
224 raise patch.PatchError('unhandled transition: %s -> %s' %
225 (state, newstate))
226 state = newstate
227 return p.finished()
228
229 def filterpatch(ui, chunks):
230 chunks = list(chunks)
231 chunks.reverse()
232 seen = {}
233 def consumefile():
234 consumed = []
235 while chunks:
236 if isinstance(chunks[-1], header):
237 break
238 else:
239 consumed.append(chunks.pop())
240 return consumed
241 resp = None
242 applied = {}
243 while chunks:
244 chunk = chunks.pop()
245 if isinstance(chunk, header):
246 fixoffset = 0
247 hdr = ''.join(chunk.header)
248 if hdr in seen:
249 consumefile()
250 continue
251 seen[hdr] = True
252 if not resp:
253 chunk.pretty(ui)
254 r = resp or ui.prompt(_('record changes to %s? [y]es [n]o') %
255 _(' and ').join(map(repr, chunk.files())),
256 '(?:|[yYnNqQaA])$') or 'y'
257 if r in 'aA':
258 r = 'y'
259 resp = 'y'
260 if r in 'qQ':
261 raise util.Abort(_('user quit'))
262 if r in 'yY':
263 applied[chunk.filename()] = [chunk]
264 if chunk.allhunks():
265 applied[chunk.filename()] += consumefile()
266 else:
267 consumefile()
268 else:
269 if not resp:
270 chunk.pretty(ui)
271 r = resp or ui.prompt(_('record this change to %r? [y]es [n]o') %
272 chunk.filename(), '(?:|[yYnNqQaA])$') or 'y'
273 if r in 'aA':
274 r = 'y'
275 resp = 'y'
276 if r in 'qQ':
277 raise util.Abort(_('user quit'))
278 if r in 'yY':
279 if fixoffset:
280 chunk = copy.copy(chunk)
281 chunk.toline += fixoffset
282 applied[chunk.filename()].append(chunk)
283 else:
284 fixoffset += chunk.removed - chunk.added
285 return reduce(operator.add, [h for h in applied.itervalues()
286 if h[0].special() or len(h) > 1], [])
287
288 def record(ui, repo, *pats, **opts):
289 '''interactively select changes to commit'''
290
291 if not ui.interactive:
292 raise util.Abort(_('running non-interactively, use commit instead'))
293
294 def recordfunc(ui, repo, files, message, match, opts):
295 if files:
296 changes = None
297 else:
298 changes = repo.status(files=files, match=match)[:5]
299 modified, added, removed = changes[:3]
300 files = modified + added + removed
301 diffopts = mdiff.diffopts(git=True, nodates=True)
302 fp = cStringIO.StringIO()
303 patch.diff(repo, repo.dirstate.parents()[0], files=files,
304 match=match, changes=changes, opts=diffopts, fp=fp)
305 fp.seek(0)
306
307 chunks = filterpatch(ui, parsepatch(fp))
308 del fp
309
310 contenders = {}
311 for h in chunks:
312 try: contenders.update(dict.fromkeys(h.files()))
313 except AttributeError: pass
314
315 newfiles = [f for f in files if f in contenders]
316
317 if not newfiles:
318 ui.status(_('no changes to record\n'))
319 return 0
320
321 if changes is None:
322 changes = repo.status(files=newfiles, match=match)[:5]
323 modified = dict.fromkeys(changes[0])
324
325 backups = {}
326 backupdir = repo.join('record-backups')
327 try:
328 os.mkdir(backupdir)
329 except OSError, err:
330 if err.errno == errno.EEXIST:
331 pass
332 try:
333 for f in newfiles:
334 if f not in modified:
335 continue
336 fd, tmpname = tempfile.mkstemp(prefix=f.replace('/', '_')+'.',
337 dir=backupdir)
338 os.close(fd)
339 ui.debug('backup %r as %r\n' % (f, tmpname))
340 util.copyfile(repo.wjoin(f), tmpname)
341 backups[f] = tmpname
342
343 fp = cStringIO.StringIO()
344 for c in chunks:
345 if c.filename() in backups:
346 c.write(fp)
347 dopatch = fp.tell()
348 fp.seek(0)
349
350 if backups:
351 hg.revert(repo, repo.dirstate.parents()[0], backups.has_key)
352
353 if dopatch:
354 ui.debug('applying patch\n')
355 ui.debug(fp.getvalue())
356 patch.internalpatch(fp, ui, 1, repo.root)
357 del fp
358
359 repo.commit(newfiles, message, opts['user'], opts['date'], match,
360 force_editor=opts.get('force_editor'))
361 return 0
362 finally:
363 try:
364 for realname, tmpname in backups.iteritems():
365 ui.debug('restoring %r to %r\n' % (tmpname, realname))
366 util.copyfile(tmpname, realname)
367 os.unlink(tmpname)
368 os.rmdir(backupdir)
369 except OSError:
370 pass
371 return cmdutil.commit(ui, repo, recordfunc, pats, opts)
372
373 cmdtable = {
374 'record':
375 (record, [('A', 'addremove', None,
376 _('mark new/missing files as added/removed before committing')),
377 ('d', 'date', '', _('record datecode as commit date')),
378 ('u', 'user', '', _('record user as commiter')),
379 ] + commands.walkopts + commands.commitopts,
380 _('hg record [FILE]...')),
381 }
@@ -0,0 +1,204 b''
1 #!/bin/sh
2
3 echo "[ui]" >> $HGRCPATH
4 echo "interactive=true" >> $HGRCPATH
5 echo "[extensions]" >> $HGRCPATH
6 echo "record=" >> $HGRCPATH
7
8 echo % help
9
10 hg help record
11
12 hg init a
13 cd a
14
15 echo % select no files
16
17 touch empty-rw
18 hg add empty-rw
19 hg record empty-rw<<EOF
20 n
21 EOF
22 echo; hg tip -p
23
24 echo % select files but no hunks
25
26 hg record empty-rw<<EOF
27 y
28 n
29 EOF
30 echo; hg tip -p
31
32 echo % record empty file
33
34 hg record -d '0 0' -m empty empty-rw<<EOF
35 y
36 y
37 EOF
38 echo; hg tip -p
39
40 echo % rename empty file
41
42 hg mv empty-rw empty-rename
43 hg record -d '1 0' -m rename<<EOF
44 y
45 EOF
46 echo; hg tip -p
47
48 echo % copy empty file
49
50 hg cp empty-rename empty-copy
51 hg record -d '2 0' -m copy<<EOF
52 y
53 EOF
54 echo; hg tip -p
55
56 echo % delete empty file
57
58 hg rm empty-copy
59 hg record -d '3 0' -m delete<<EOF
60 y
61 EOF
62 echo; hg tip -p
63
64 echo % add binary file
65
66 hg bundle --base -2 tip.bundle
67 hg add tip.bundle
68 hg record -d '4 0' -m binary<<EOF
69 y
70 EOF
71 echo; hg tip -p
72
73 echo % change binary file
74
75 hg bundle --base -2 tip.bundle
76 hg record -d '5 0' -m binary-change<<EOF
77 y
78 EOF
79 echo; hg tip -p
80
81 echo % rename and change binary file
82
83 hg mv tip.bundle top.bundle
84 hg bundle --base -2 top.bundle
85 hg record -d '6 0' -m binary-change-rename<<EOF
86 y
87 EOF
88 echo; hg tip -p
89
90 echo % add plain file
91
92 for i in 1 2 3 4 5 6 7 8 9 10; do
93 echo $i >> plain
94 done
95
96 hg add plain
97 hg record -d '7 0' -m plain plain<<EOF
98 y
99 y
100 EOF
101 echo; hg tip -p
102
103 echo % modify end of plain file
104
105 echo 11 >> plain
106 hg record -d '8 0' -m end plain <<EOF
107 y
108 y
109 EOF
110
111 echo % modify end of plain file, no EOL
112
113 hg tip --template '{node}' >> plain
114 hg record -d '9 0' -m noeol plain <<EOF
115 y
116 y
117 EOF
118
119 echo % modify end of plain file, add EOL
120
121 echo >> plain
122 hg record -d '10 0' -m eol plain <<EOF
123 y
124 y
125 y
126 EOF
127
128 echo % modify beginning, trim end, record both
129
130 rm plain
131 for i in 2 2 3 4 5 6 7 8 9 10; do
132 echo $i >> plain
133 done
134
135 hg record -d '10 0' -m begin-and-end plain <<EOF
136 y
137 y
138 y
139 EOF
140 echo; hg tip -p
141
142 echo % trim beginning, modify end
143
144 rm plain
145 for i in 4 5 6 7 8 9 10.new; do
146 echo $i >> plain
147 done
148
149 echo % record end
150
151 hg record -d '11 0' -m end-only plain <<EOF
152 y
153 n
154 y
155 EOF
156 echo; hg tip -p
157
158 echo % record beginning
159
160 hg record -d '12 0' -m begin-only plain <<EOF
161 y
162 y
163 EOF
164 echo; hg tip -p
165
166 echo % add to beginning, trim from end
167
168 rm plain
169 for i in 1 2 3 4 5 6 7 8 9; do
170 echo $i >> plain
171 done
172
173 echo % record end
174
175 hg record --traceback -d '13 0' -m end-again plain<<EOF
176 y
177 n
178 y
179 EOF
180
181 echo % add to beginning, middle, end
182
183 rm plain
184 for i in 1 2 3 4 5 5.new 5.reallynew 6 7 8 9 10 11; do
185 echo $i >> plain
186 done
187
188 echo % record beginning, middle
189
190 hg record -d '14 0' -m middle-only plain <<EOF
191 y
192 y
193 y
194 n
195 EOF
196 echo; hg tip -p
197
198 echo % record end
199
200 hg record -d '15 0' -m end-only plain <<EOF
201 y
202 y
203 EOF
204 echo; hg tip -p
@@ -0,0 +1,383 b''
1 % help
2 hg record [FILE]...
3
4 interactively select changes to commit
5
6 options:
7
8 -A --addremove mark new/missing files as added/removed before committing
9 -d --date record datecode as commit date
10 -u --user record user as commiter
11 -I --include include names matching the given patterns
12 -X --exclude exclude names matching the given patterns
13 -m --message use <text> as commit message
14 -l --logfile read commit message from <file>
15
16 use "hg -v help record" to show global options
17 % select no files
18 diff --git a/empty-rw b/empty-rw
19 new file mode 100644
20 record changes to 'empty-rw'? [y]es [n]o no changes to record
21
22 changeset: -1:000000000000
23 tag: tip
24 user:
25 date: Thu Jan 01 00:00:00 1970 +0000
26
27
28 % select files but no hunks
29 diff --git a/empty-rw b/empty-rw
30 new file mode 100644
31 record changes to 'empty-rw'? [y]es [n]o transaction abort!
32 rollback completed
33
34 changeset: -1:000000000000
35 tag: tip
36 user:
37 date: Thu Jan 01 00:00:00 1970 +0000
38
39
40 % record empty file
41 diff --git a/empty-rw b/empty-rw
42 new file mode 100644
43 record changes to 'empty-rw'? [y]es [n]o
44 changeset: 0:c0708cf4e46e
45 tag: tip
46 user: test
47 date: Thu Jan 01 00:00:00 1970 +0000
48 summary: empty
49
50
51 % rename empty file
52 diff --git a/empty-rw b/empty-rename
53 rename from empty-rw
54 rename to empty-rename
55 record changes to 'empty-rw' and 'empty-rename'? [y]es [n]o
56 changeset: 1:df251d174da3
57 tag: tip
58 user: test
59 date: Thu Jan 01 00:00:01 1970 +0000
60 summary: rename
61
62
63 % copy empty file
64 diff --git a/empty-rename b/empty-copy
65 copy from empty-rename
66 copy to empty-copy
67 record changes to 'empty-rename' and 'empty-copy'? [y]es [n]o
68 changeset: 2:b63ea3939f8d
69 tag: tip
70 user: test
71 date: Thu Jan 01 00:00:02 1970 +0000
72 summary: copy
73
74
75 % delete empty file
76 diff --git a/empty-copy b/empty-copy
77 deleted file mode 100644
78 record changes to 'empty-copy'? [y]es [n]o
79 changeset: 3:a2546574bce9
80 tag: tip
81 user: test
82 date: Thu Jan 01 00:00:03 1970 +0000
83 summary: delete
84
85
86 % add binary file
87 diff --git a/tip.bundle b/tip.bundle
88 new file mode 100644
89 this is a binary file
90 record changes to 'tip.bundle'? [y]es [n]o
91 changeset: 4:9e998a545a8b
92 tag: tip
93 user: test
94 date: Thu Jan 01 00:00:04 1970 +0000
95 summary: binary
96
97 diff -r a2546574bce9 -r 9e998a545a8b tip.bundle
98 Binary file tip.bundle has changed
99
100 % change binary file
101 diff --git a/tip.bundle b/tip.bundle
102 this modifies a binary file (all or nothing)
103 record changes to 'tip.bundle'? [y]es [n]o
104 changeset: 5:93d05561507d
105 tag: tip
106 user: test
107 date: Thu Jan 01 00:00:05 1970 +0000
108 summary: binary-change
109
110 diff -r 9e998a545a8b -r 93d05561507d tip.bundle
111 Binary file tip.bundle has changed
112
113 % rename and change binary file
114 diff --git a/tip.bundle b/top.bundle
115 rename from tip.bundle
116 rename to top.bundle
117 this modifies a binary file (all or nothing)
118 record changes to 'tip.bundle' and 'top.bundle'? [y]es [n]o
119 changeset: 6:699cc1bea9aa
120 tag: tip
121 user: test
122 date: Thu Jan 01 00:00:06 1970 +0000
123 summary: binary-change-rename
124
125 diff -r 93d05561507d -r 699cc1bea9aa tip.bundle
126 Binary file tip.bundle has changed
127 diff -r 93d05561507d -r 699cc1bea9aa top.bundle
128 Binary file top.bundle has changed
129
130 % add plain file
131 diff --git a/plain b/plain
132 new file mode 100644
133 record changes to 'plain'? [y]es [n]o
134 changeset: 7:118ed744216b
135 tag: tip
136 user: test
137 date: Thu Jan 01 00:00:07 1970 +0000
138 summary: plain
139
140 diff -r 699cc1bea9aa -r 118ed744216b plain
141 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
142 +++ b/plain Thu Jan 01 00:00:07 1970 +0000
143 @@ -0,0 +1,10 @@
144 +1
145 +2
146 +3
147 +4
148 +5
149 +6
150 +7
151 +8
152 +9
153 +10
154
155 % modify end of plain file
156 diff --git a/plain b/plain
157 1 hunks, 1 lines changed
158 record changes to 'plain'? [y]es [n]o @@ -8,3 +8,4 @@ 8
159 8
160 9
161 10
162 +11
163 record this change to 'plain'? [y]es [n]o % modify end of plain file, no EOL
164 diff --git a/plain b/plain
165 1 hunks, 1 lines changed
166 record changes to 'plain'? [y]es [n]o @@ -9,3 +9,4 @@ 9
167 9
168 10
169 11
170 +cf81a2760718a74d44c0c2eecb72f659e63a69c5
171 \ No newline at end of file
172 record this change to 'plain'? [y]es [n]o % modify end of plain file, add EOL
173 diff --git a/plain b/plain
174 1 hunks, 2 lines changed
175 record changes to 'plain'? [y]es [n]o @@ -9,4 +9,4 @@ 9
176 9
177 10
178 11
179 -cf81a2760718a74d44c0c2eecb72f659e63a69c5
180 \ No newline at end of file
181 +cf81a2760718a74d44c0c2eecb72f659e63a69c5
182 record this change to 'plain'? [y]es [n]o % modify beginning, trim end, record both
183 diff --git a/plain b/plain
184 2 hunks, 4 lines changed
185 record changes to 'plain'? [y]es [n]o @@ -1,4 +1,4 @@ 1
186 -1
187 +2
188 2
189 3
190 4
191 record this change to 'plain'? [y]es [n]o @@ -8,5 +8,3 @@ 8
192 8
193 9
194 10
195 -11
196 -cf81a2760718a74d44c0c2eecb72f659e63a69c5
197 record this change to 'plain'? [y]es [n]o
198 changeset: 11:d09ab1967dab
199 tag: tip
200 user: test
201 date: Thu Jan 01 00:00:10 1970 +0000
202 summary: begin-and-end
203
204 diff -r e2ecd9b0b78d -r d09ab1967dab plain
205 --- a/plain Thu Jan 01 00:00:10 1970 +0000
206 +++ b/plain Thu Jan 01 00:00:10 1970 +0000
207 @@ -1,4 +1,4 @@ 1
208 -1
209 +2
210 2
211 3
212 4
213 @@ -8,5 +8,3 @@ 8
214 8
215 9
216 10
217 -11
218 -cf81a2760718a74d44c0c2eecb72f659e63a69c5
219
220 % trim beginning, modify end
221 % record end
222 diff --git a/plain b/plain
223 2 hunks, 5 lines changed
224 record changes to 'plain'? [y]es [n]o @@ -1,9 +1,6 @@ 2
225 -2
226 -2
227 -3
228 4
229 5
230 6
231 7
232 8
233 9
234 record this change to 'plain'? [y]es [n]o @@ -4,7 +1,7 @@
235 4
236 5
237 6
238 7
239 8
240 9
241 -10
242 +10.new
243 record this change to 'plain'? [y]es [n]o
244 changeset: 12:44516c9708ae
245 tag: tip
246 user: test
247 date: Thu Jan 01 00:00:11 1970 +0000
248 summary: end-only
249
250 diff -r d09ab1967dab -r 44516c9708ae plain
251 --- a/plain Thu Jan 01 00:00:10 1970 +0000
252 +++ b/plain Thu Jan 01 00:00:11 1970 +0000
253 @@ -7,4 +7,4 @@ 7
254 7
255 8
256 9
257 -10
258 +10.new
259
260 % record beginning
261 diff --git a/plain b/plain
262 1 hunks, 3 lines changed
263 record changes to 'plain'? [y]es [n]o @@ -1,6 +1,3 @@ 2
264 -2
265 -2
266 -3
267 4
268 5
269 6
270 record this change to 'plain'? [y]es [n]o
271 changeset: 13:3ebbace64a8d
272 tag: tip
273 user: test
274 date: Thu Jan 01 00:00:12 1970 +0000
275 summary: begin-only
276
277 diff -r 44516c9708ae -r 3ebbace64a8d plain
278 --- a/plain Thu Jan 01 00:00:11 1970 +0000
279 +++ b/plain Thu Jan 01 00:00:12 1970 +0000
280 @@ -1,6 +1,3 @@ 2
281 -2
282 -2
283 -3
284 4
285 5
286 6
287
288 % add to beginning, trim from end
289 % record end
290 diff --git a/plain b/plain
291 2 hunks, 4 lines changed
292 record changes to 'plain'? [y]es [n]o @@ -1,6 +1,9 @@ 4
293 +1
294 +2
295 +3
296 4
297 5
298 6
299 7
300 8
301 9
302 record this change to 'plain'? [y]es [n]o @@ -1,7 +4,6 @@
303 4
304 5
305 6
306 7
307 8
308 9
309 -10.new
310 record this change to 'plain'? [y]es [n]o % add to beginning, middle, end
311 % record beginning, middle
312 diff --git a/plain b/plain
313 3 hunks, 7 lines changed
314 record changes to 'plain'? [y]es [n]o @@ -1,2 +1,5 @@ 4
315 +1
316 +2
317 +3
318 4
319 5
320 record this change to 'plain'? [y]es [n]o @@ -1,6 +4,8 @@
321 4
322 5
323 +5.new
324 +5.reallynew
325 6
326 7
327 8
328 9
329 record this change to 'plain'? [y]es [n]o @@ -3,4 +8,6 @@
330 6
331 7
332 8
333 9
334 +10
335 +11
336 record this change to 'plain'? [y]es [n]o
337 changeset: 15:c1c639d8b268
338 tag: tip
339 user: test
340 date: Thu Jan 01 00:00:14 1970 +0000
341 summary: middle-only
342
343 diff -r efc0dad7bd9f -r c1c639d8b268 plain
344 --- a/plain Thu Jan 01 00:00:13 1970 +0000
345 +++ b/plain Thu Jan 01 00:00:14 1970 +0000
346 @@ -1,5 +1,10 @@ 4
347 +1
348 +2
349 +3
350 4
351 5
352 +5.new
353 +5.reallynew
354 6
355 7
356 8
357
358 % record end
359 diff --git a/plain b/plain
360 1 hunks, 2 lines changed
361 record changes to 'plain'? [y]es [n]o @@ -9,3 +9,5 @@ 7
362 7
363 8
364 9
365 +10
366 +11
367 record this change to 'plain'? [y]es [n]o
368 changeset: 16:80b74bbc7808
369 tag: tip
370 user: test
371 date: Thu Jan 01 00:00:15 1970 +0000
372 summary: end-only
373
374 diff -r c1c639d8b268 -r 80b74bbc7808 plain
375 --- a/plain Thu Jan 01 00:00:14 1970 +0000
376 +++ b/plain Thu Jan 01 00:00:15 1970 +0000
377 @@ -9,3 +9,5 @@ 7
378 7
379 8
380 9
381 +10
382 +11
383
General Comments 0
You need to be logged in to leave comments. Login now