##// END OF EJS Templates
extdiff: use archiver to take snapshots of committed revisions...
Matt Harbison -
r25812:68822b7c default
parent child Browse files
Show More
@@ -1,344 +1,346 b''
1 # extdiff.py - external diff program support for mercurial
1 # extdiff.py - external diff program support for mercurial
2 #
2 #
3 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
3 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.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 '''command to allow external programs to compare revisions
8 '''command to allow external programs to compare revisions
9
9
10 The extdiff Mercurial extension allows you to use external programs
10 The extdiff Mercurial extension allows you to use external programs
11 to compare revisions, or revision with working directory. The external
11 to compare revisions, or revision with working directory. The external
12 diff programs are called with a configurable set of options and two
12 diff programs are called with a configurable set of options and two
13 non-option arguments: paths to directories containing snapshots of
13 non-option arguments: paths to directories containing snapshots of
14 files to compare.
14 files to compare.
15
15
16 The extdiff extension also allows you to configure new diff commands, so
16 The extdiff extension also allows you to configure new diff commands, so
17 you do not need to type :hg:`extdiff -p kdiff3` always. ::
17 you do not need to type :hg:`extdiff -p kdiff3` always. ::
18
18
19 [extdiff]
19 [extdiff]
20 # add new command that runs GNU diff(1) in 'context diff' mode
20 # add new command that runs GNU diff(1) in 'context diff' mode
21 cdiff = gdiff -Nprc5
21 cdiff = gdiff -Nprc5
22 ## or the old way:
22 ## or the old way:
23 #cmd.cdiff = gdiff
23 #cmd.cdiff = gdiff
24 #opts.cdiff = -Nprc5
24 #opts.cdiff = -Nprc5
25
25
26 # add new command called meld, runs meld (no need to name twice). If
26 # add new command called meld, runs meld (no need to name twice). If
27 # the meld executable is not available, the meld tool in [merge-tools]
27 # the meld executable is not available, the meld tool in [merge-tools]
28 # will be used, if available
28 # will be used, if available
29 meld =
29 meld =
30
30
31 # add new command called vimdiff, runs gvimdiff with DirDiff plugin
31 # add new command called vimdiff, runs gvimdiff with DirDiff plugin
32 # (see http://www.vim.org/scripts/script.php?script_id=102) Non
32 # (see http://www.vim.org/scripts/script.php?script_id=102) Non
33 # English user, be sure to put "let g:DirDiffDynamicDiffText = 1" in
33 # English user, be sure to put "let g:DirDiffDynamicDiffText = 1" in
34 # your .vimrc
34 # your .vimrc
35 vimdiff = gvim -f "+next" \\
35 vimdiff = gvim -f "+next" \\
36 "+execute 'DirDiff' fnameescape(argv(0)) fnameescape(argv(1))"
36 "+execute 'DirDiff' fnameescape(argv(0)) fnameescape(argv(1))"
37
37
38 Tool arguments can include variables that are expanded at runtime::
38 Tool arguments can include variables that are expanded at runtime::
39
39
40 $parent1, $plabel1 - filename, descriptive label of first parent
40 $parent1, $plabel1 - filename, descriptive label of first parent
41 $child, $clabel - filename, descriptive label of child revision
41 $child, $clabel - filename, descriptive label of child revision
42 $parent2, $plabel2 - filename, descriptive label of second parent
42 $parent2, $plabel2 - filename, descriptive label of second parent
43 $root - repository root
43 $root - repository root
44 $parent is an alias for $parent1.
44 $parent is an alias for $parent1.
45
45
46 The extdiff extension will look in your [diff-tools] and [merge-tools]
46 The extdiff extension will look in your [diff-tools] and [merge-tools]
47 sections for diff tool arguments, when none are specified in [extdiff].
47 sections for diff tool arguments, when none are specified in [extdiff].
48
48
49 ::
49 ::
50
50
51 [extdiff]
51 [extdiff]
52 kdiff3 =
52 kdiff3 =
53
53
54 [diff-tools]
54 [diff-tools]
55 kdiff3.diffargs=--L1 '$plabel1' --L2 '$clabel' $parent $child
55 kdiff3.diffargs=--L1 '$plabel1' --L2 '$clabel' $parent $child
56
56
57 You can use -I/-X and list of file or directory names like normal
57 You can use -I/-X and list of file or directory names like normal
58 :hg:`diff` command. The extdiff extension makes snapshots of only
58 :hg:`diff` command. The extdiff extension makes snapshots of only
59 needed files, so running the external diff program will actually be
59 needed files, so running the external diff program will actually be
60 pretty fast (at least faster than having to compare the entire tree).
60 pretty fast (at least faster than having to compare the entire tree).
61 '''
61 '''
62
62
63 from mercurial.i18n import _
63 from mercurial.i18n import _
64 from mercurial.node import short, nullid
64 from mercurial.node import short, nullid
65 from mercurial import cmdutil, scmutil, util, commands, encoding, filemerge
65 from mercurial import cmdutil, scmutil, util, commands, encoding, filemerge
66 from mercurial import archival
66 import os, shlex, shutil, tempfile, re
67 import os, shlex, shutil, tempfile, re
67
68
68 cmdtable = {}
69 cmdtable = {}
69 command = cmdutil.command(cmdtable)
70 command = cmdutil.command(cmdtable)
70 # Note for extension authors: ONLY specify testedwith = 'internal' for
71 # Note for extension authors: ONLY specify testedwith = 'internal' for
71 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
72 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
72 # be specifying the version(s) of Mercurial they are tested with, or
73 # be specifying the version(s) of Mercurial they are tested with, or
73 # leave the attribute unspecified.
74 # leave the attribute unspecified.
74 testedwith = 'internal'
75 testedwith = 'internal'
75
76
76 def snapshot(ui, repo, files, node, tmproot):
77 def snapshot(ui, repo, files, node, tmproot):
77 '''snapshot files as of some revision
78 '''snapshot files as of some revision
78 if not using snapshot, -I/-X does not work and recursive diff
79 if not using snapshot, -I/-X does not work and recursive diff
79 in tools like kdiff3 and meld displays too many files.'''
80 in tools like kdiff3 and meld displays too many files.'''
80 dirname = os.path.basename(repo.root)
81 dirname = os.path.basename(repo.root)
81 if dirname == "":
82 if dirname == "":
82 dirname = "root"
83 dirname = "root"
83 if node is not None:
84 if node is not None:
84 dirname = '%s.%s' % (dirname, short(node))
85 dirname = '%s.%s' % (dirname, short(node))
85 base = os.path.join(tmproot, dirname)
86 base = os.path.join(tmproot, dirname)
86 os.mkdir(base)
87 os.mkdir(base)
88 fns_and_mtime = []
89
87 if node is not None:
90 if node is not None:
88 ui.note(_('making snapshot of %d files from rev %s\n') %
91 ui.note(_('making snapshot of %d files from rev %s\n') %
89 (len(files), short(node)))
92 (len(files), short(node)))
90 else:
93 else:
91 ui.note(_('making snapshot of %d files from working directory\n') %
94 ui.note(_('making snapshot of %d files from working directory\n') %
92 (len(files)))
95 (len(files)))
93 wopener = scmutil.opener(base)
96
94 fns_and_mtime = []
97 if files:
95 ctx = repo[node]
98 repo.ui.setconfig("ui", "archivemeta", False)
96 for fn in sorted(files):
99
97 wfn = util.pconvert(fn)
100 archival.archive(repo, base, node, 'files',
98 if wfn not in ctx:
101 matchfn=scmutil.matchfiles(repo, files))
99 # File doesn't exist; could be a bogus modify
102
100 continue
103 ctx = repo[node]
101 ui.note(' %s\n' % wfn)
104 for fn in sorted(files):
102 dest = os.path.join(base, wfn)
105 wfn = util.pconvert(fn)
103 fctx = ctx[wfn]
106 if wfn not in ctx:
104 data = repo.wwritedata(wfn, fctx.data())
107 # File doesn't exist; could be a bogus modify
105 if 'l' in fctx.flags():
108 continue
106 wopener.symlink(data, wfn)
109 ui.note(' %s\n' % wfn)
107 else:
110
108 wopener.write(wfn, data)
111 if node is None:
109 if 'x' in fctx.flags():
112 dest = os.path.join(base, wfn)
110 util.setflags(dest, False, True)
113
111 if node is None:
114 fns_and_mtime.append((dest, repo.wjoin(fn),
112 fns_and_mtime.append((dest, repo.wjoin(fn),
115 os.lstat(dest).st_mtime))
113 os.lstat(dest).st_mtime))
114 return dirname, fns_and_mtime
116 return dirname, fns_and_mtime
115
117
116 def dodiff(ui, repo, cmdline, pats, opts):
118 def dodiff(ui, repo, cmdline, pats, opts):
117 '''Do the actual diff:
119 '''Do the actual diff:
118
120
119 - copy to a temp structure if diffing 2 internal revisions
121 - copy to a temp structure if diffing 2 internal revisions
120 - copy to a temp structure if diffing working revision with
122 - copy to a temp structure if diffing working revision with
121 another one and more than 1 file is changed
123 another one and more than 1 file is changed
122 - just invoke the diff for a single file in the working dir
124 - just invoke the diff for a single file in the working dir
123 '''
125 '''
124
126
125 revs = opts.get('rev')
127 revs = opts.get('rev')
126 change = opts.get('change')
128 change = opts.get('change')
127 do3way = '$parent2' in cmdline
129 do3way = '$parent2' in cmdline
128
130
129 if revs and change:
131 if revs and change:
130 msg = _('cannot specify --rev and --change at the same time')
132 msg = _('cannot specify --rev and --change at the same time')
131 raise util.Abort(msg)
133 raise util.Abort(msg)
132 elif change:
134 elif change:
133 node2 = scmutil.revsingle(repo, change, None).node()
135 node2 = scmutil.revsingle(repo, change, None).node()
134 node1a, node1b = repo.changelog.parents(node2)
136 node1a, node1b = repo.changelog.parents(node2)
135 else:
137 else:
136 node1a, node2 = scmutil.revpair(repo, revs)
138 node1a, node2 = scmutil.revpair(repo, revs)
137 if not revs:
139 if not revs:
138 node1b = repo.dirstate.p2()
140 node1b = repo.dirstate.p2()
139 else:
141 else:
140 node1b = nullid
142 node1b = nullid
141
143
142 # Disable 3-way merge if there is only one parent
144 # Disable 3-way merge if there is only one parent
143 if do3way:
145 if do3way:
144 if node1b == nullid:
146 if node1b == nullid:
145 do3way = False
147 do3way = False
146
148
147 matcher = scmutil.match(repo[node2], pats, opts)
149 matcher = scmutil.match(repo[node2], pats, opts)
148 mod_a, add_a, rem_a = map(set, repo.status(node1a, node2, matcher)[:3])
150 mod_a, add_a, rem_a = map(set, repo.status(node1a, node2, matcher)[:3])
149 if do3way:
151 if do3way:
150 mod_b, add_b, rem_b = map(set, repo.status(node1b, node2, matcher)[:3])
152 mod_b, add_b, rem_b = map(set, repo.status(node1b, node2, matcher)[:3])
151 else:
153 else:
152 mod_b, add_b, rem_b = set(), set(), set()
154 mod_b, add_b, rem_b = set(), set(), set()
153 modadd = mod_a | add_a | mod_b | add_b
155 modadd = mod_a | add_a | mod_b | add_b
154 common = modadd | rem_a | rem_b
156 common = modadd | rem_a | rem_b
155 if not common:
157 if not common:
156 return 0
158 return 0
157
159
158 tmproot = tempfile.mkdtemp(prefix='extdiff.')
160 tmproot = tempfile.mkdtemp(prefix='extdiff.')
159 try:
161 try:
160 # Always make a copy of node1a (and node1b, if applicable)
162 # Always make a copy of node1a (and node1b, if applicable)
161 dir1a_files = mod_a | rem_a | ((mod_b | add_b) - add_a)
163 dir1a_files = mod_a | rem_a | ((mod_b | add_b) - add_a)
162 dir1a = snapshot(ui, repo, dir1a_files, node1a, tmproot)[0]
164 dir1a = snapshot(ui, repo, dir1a_files, node1a, tmproot)[0]
163 rev1a = '@%d' % repo[node1a].rev()
165 rev1a = '@%d' % repo[node1a].rev()
164 if do3way:
166 if do3way:
165 dir1b_files = mod_b | rem_b | ((mod_a | add_a) - add_b)
167 dir1b_files = mod_b | rem_b | ((mod_a | add_a) - add_b)
166 dir1b = snapshot(ui, repo, dir1b_files, node1b, tmproot)[0]
168 dir1b = snapshot(ui, repo, dir1b_files, node1b, tmproot)[0]
167 rev1b = '@%d' % repo[node1b].rev()
169 rev1b = '@%d' % repo[node1b].rev()
168 else:
170 else:
169 dir1b = None
171 dir1b = None
170 rev1b = ''
172 rev1b = ''
171
173
172 fns_and_mtime = []
174 fns_and_mtime = []
173
175
174 # If node2 in not the wc or there is >1 change, copy it
176 # If node2 in not the wc or there is >1 change, copy it
175 dir2root = ''
177 dir2root = ''
176 rev2 = ''
178 rev2 = ''
177 if node2:
179 if node2:
178 dir2 = snapshot(ui, repo, modadd, node2, tmproot)[0]
180 dir2 = snapshot(ui, repo, modadd, node2, tmproot)[0]
179 rev2 = '@%d' % repo[node2].rev()
181 rev2 = '@%d' % repo[node2].rev()
180 elif len(common) > 1:
182 elif len(common) > 1:
181 #we only actually need to get the files to copy back to
183 #we only actually need to get the files to copy back to
182 #the working dir in this case (because the other cases
184 #the working dir in this case (because the other cases
183 #are: diffing 2 revisions or single file -- in which case
185 #are: diffing 2 revisions or single file -- in which case
184 #the file is already directly passed to the diff tool).
186 #the file is already directly passed to the diff tool).
185 dir2, fns_and_mtime = snapshot(ui, repo, modadd, None, tmproot)
187 dir2, fns_and_mtime = snapshot(ui, repo, modadd, None, tmproot)
186 else:
188 else:
187 # This lets the diff tool open the changed file directly
189 # This lets the diff tool open the changed file directly
188 dir2 = ''
190 dir2 = ''
189 dir2root = repo.root
191 dir2root = repo.root
190
192
191 label1a = rev1a
193 label1a = rev1a
192 label1b = rev1b
194 label1b = rev1b
193 label2 = rev2
195 label2 = rev2
194
196
195 # If only one change, diff the files instead of the directories
197 # If only one change, diff the files instead of the directories
196 # Handle bogus modifies correctly by checking if the files exist
198 # Handle bogus modifies correctly by checking if the files exist
197 if len(common) == 1:
199 if len(common) == 1:
198 common_file = util.localpath(common.pop())
200 common_file = util.localpath(common.pop())
199 dir1a = os.path.join(tmproot, dir1a, common_file)
201 dir1a = os.path.join(tmproot, dir1a, common_file)
200 label1a = common_file + rev1a
202 label1a = common_file + rev1a
201 if not os.path.isfile(dir1a):
203 if not os.path.isfile(dir1a):
202 dir1a = os.devnull
204 dir1a = os.devnull
203 if do3way:
205 if do3way:
204 dir1b = os.path.join(tmproot, dir1b, common_file)
206 dir1b = os.path.join(tmproot, dir1b, common_file)
205 label1b = common_file + rev1b
207 label1b = common_file + rev1b
206 if not os.path.isfile(dir1b):
208 if not os.path.isfile(dir1b):
207 dir1b = os.devnull
209 dir1b = os.devnull
208 dir2 = os.path.join(dir2root, dir2, common_file)
210 dir2 = os.path.join(dir2root, dir2, common_file)
209 label2 = common_file + rev2
211 label2 = common_file + rev2
210
212
211 # Function to quote file/dir names in the argument string.
213 # Function to quote file/dir names in the argument string.
212 # When not operating in 3-way mode, an empty string is
214 # When not operating in 3-way mode, an empty string is
213 # returned for parent2
215 # returned for parent2
214 replace = {'parent': dir1a, 'parent1': dir1a, 'parent2': dir1b,
216 replace = {'parent': dir1a, 'parent1': dir1a, 'parent2': dir1b,
215 'plabel1': label1a, 'plabel2': label1b,
217 'plabel1': label1a, 'plabel2': label1b,
216 'clabel': label2, 'child': dir2,
218 'clabel': label2, 'child': dir2,
217 'root': repo.root}
219 'root': repo.root}
218 def quote(match):
220 def quote(match):
219 pre = match.group(2)
221 pre = match.group(2)
220 key = match.group(3)
222 key = match.group(3)
221 if not do3way and key == 'parent2':
223 if not do3way and key == 'parent2':
222 return pre
224 return pre
223 return pre + util.shellquote(replace[key])
225 return pre + util.shellquote(replace[key])
224
226
225 # Match parent2 first, so 'parent1?' will match both parent1 and parent
227 # Match parent2 first, so 'parent1?' will match both parent1 and parent
226 regex = (r'''(['"]?)([^\s'"$]*)'''
228 regex = (r'''(['"]?)([^\s'"$]*)'''
227 r'\$(parent2|parent1?|child|plabel1|plabel2|clabel|root)\1')
229 r'\$(parent2|parent1?|child|plabel1|plabel2|clabel|root)\1')
228 if not do3way and not re.search(regex, cmdline):
230 if not do3way and not re.search(regex, cmdline):
229 cmdline += ' $parent1 $child'
231 cmdline += ' $parent1 $child'
230 cmdline = re.sub(regex, quote, cmdline)
232 cmdline = re.sub(regex, quote, cmdline)
231
233
232 ui.debug('running %r in %s\n' % (cmdline, tmproot))
234 ui.debug('running %r in %s\n' % (cmdline, tmproot))
233 ui.system(cmdline, cwd=tmproot)
235 ui.system(cmdline, cwd=tmproot)
234
236
235 for copy_fn, working_fn, mtime in fns_and_mtime:
237 for copy_fn, working_fn, mtime in fns_and_mtime:
236 if os.lstat(copy_fn).st_mtime != mtime:
238 if os.lstat(copy_fn).st_mtime != mtime:
237 ui.debug('file changed while diffing. '
239 ui.debug('file changed while diffing. '
238 'Overwriting: %s (src: %s)\n' % (working_fn, copy_fn))
240 'Overwriting: %s (src: %s)\n' % (working_fn, copy_fn))
239 util.copyfile(copy_fn, working_fn)
241 util.copyfile(copy_fn, working_fn)
240
242
241 return 1
243 return 1
242 finally:
244 finally:
243 ui.note(_('cleaning up temp directory\n'))
245 ui.note(_('cleaning up temp directory\n'))
244 shutil.rmtree(tmproot)
246 shutil.rmtree(tmproot)
245
247
246 @command('extdiff',
248 @command('extdiff',
247 [('p', 'program', '',
249 [('p', 'program', '',
248 _('comparison program to run'), _('CMD')),
250 _('comparison program to run'), _('CMD')),
249 ('o', 'option', [],
251 ('o', 'option', [],
250 _('pass option to comparison program'), _('OPT')),
252 _('pass option to comparison program'), _('OPT')),
251 ('r', 'rev', [], _('revision'), _('REV')),
253 ('r', 'rev', [], _('revision'), _('REV')),
252 ('c', 'change', '', _('change made by revision'), _('REV')),
254 ('c', 'change', '', _('change made by revision'), _('REV')),
253 ] + commands.walkopts,
255 ] + commands.walkopts,
254 _('hg extdiff [OPT]... [FILE]...'),
256 _('hg extdiff [OPT]... [FILE]...'),
255 inferrepo=True)
257 inferrepo=True)
256 def extdiff(ui, repo, *pats, **opts):
258 def extdiff(ui, repo, *pats, **opts):
257 '''use external program to diff repository (or selected files)
259 '''use external program to diff repository (or selected files)
258
260
259 Show differences between revisions for the specified files, using
261 Show differences between revisions for the specified files, using
260 an external program. The default program used is diff, with
262 an external program. The default program used is diff, with
261 default options "-Npru".
263 default options "-Npru".
262
264
263 To select a different program, use the -p/--program option. The
265 To select a different program, use the -p/--program option. The
264 program will be passed the names of two directories to compare. To
266 program will be passed the names of two directories to compare. To
265 pass additional options to the program, use -o/--option. These
267 pass additional options to the program, use -o/--option. These
266 will be passed before the names of the directories to compare.
268 will be passed before the names of the directories to compare.
267
269
268 When two revision arguments are given, then changes are shown
270 When two revision arguments are given, then changes are shown
269 between those revisions. If only one revision is specified then
271 between those revisions. If only one revision is specified then
270 that revision is compared to the working directory, and, when no
272 that revision is compared to the working directory, and, when no
271 revisions are specified, the working directory files are compared
273 revisions are specified, the working directory files are compared
272 to its parent.'''
274 to its parent.'''
273 program = opts.get('program')
275 program = opts.get('program')
274 option = opts.get('option')
276 option = opts.get('option')
275 if not program:
277 if not program:
276 program = 'diff'
278 program = 'diff'
277 option = option or ['-Npru']
279 option = option or ['-Npru']
278 cmdline = ' '.join(map(util.shellquote, [program] + option))
280 cmdline = ' '.join(map(util.shellquote, [program] + option))
279 return dodiff(ui, repo, cmdline, pats, opts)
281 return dodiff(ui, repo, cmdline, pats, opts)
280
282
281 def uisetup(ui):
283 def uisetup(ui):
282 for cmd, path in ui.configitems('extdiff'):
284 for cmd, path in ui.configitems('extdiff'):
283 path = util.expandpath(path)
285 path = util.expandpath(path)
284 if cmd.startswith('cmd.'):
286 if cmd.startswith('cmd.'):
285 cmd = cmd[4:]
287 cmd = cmd[4:]
286 if not path:
288 if not path:
287 path = util.findexe(cmd)
289 path = util.findexe(cmd)
288 if path is None:
290 if path is None:
289 path = filemerge.findexternaltool(ui, cmd) or cmd
291 path = filemerge.findexternaltool(ui, cmd) or cmd
290 diffopts = ui.config('extdiff', 'opts.' + cmd, '')
292 diffopts = ui.config('extdiff', 'opts.' + cmd, '')
291 cmdline = util.shellquote(path)
293 cmdline = util.shellquote(path)
292 if diffopts:
294 if diffopts:
293 cmdline += ' ' + diffopts
295 cmdline += ' ' + diffopts
294 elif cmd.startswith('opts.'):
296 elif cmd.startswith('opts.'):
295 continue
297 continue
296 else:
298 else:
297 if path:
299 if path:
298 # case "cmd = path opts"
300 # case "cmd = path opts"
299 cmdline = path
301 cmdline = path
300 diffopts = len(shlex.split(cmdline)) > 1
302 diffopts = len(shlex.split(cmdline)) > 1
301 else:
303 else:
302 # case "cmd ="
304 # case "cmd ="
303 path = util.findexe(cmd)
305 path = util.findexe(cmd)
304 if path is None:
306 if path is None:
305 path = filemerge.findexternaltool(ui, cmd) or cmd
307 path = filemerge.findexternaltool(ui, cmd) or cmd
306 cmdline = util.shellquote(path)
308 cmdline = util.shellquote(path)
307 diffopts = False
309 diffopts = False
308 # look for diff arguments in [diff-tools] then [merge-tools]
310 # look for diff arguments in [diff-tools] then [merge-tools]
309 if not diffopts:
311 if not diffopts:
310 args = ui.config('diff-tools', cmd+'.diffargs') or \
312 args = ui.config('diff-tools', cmd+'.diffargs') or \
311 ui.config('merge-tools', cmd+'.diffargs')
313 ui.config('merge-tools', cmd+'.diffargs')
312 if args:
314 if args:
313 cmdline += ' ' + args
315 cmdline += ' ' + args
314 def save(cmdline):
316 def save(cmdline):
315 '''use closure to save diff command to use'''
317 '''use closure to save diff command to use'''
316 def mydiff(ui, repo, *pats, **opts):
318 def mydiff(ui, repo, *pats, **opts):
317 options = ' '.join(map(util.shellquote, opts['option']))
319 options = ' '.join(map(util.shellquote, opts['option']))
318 if options:
320 if options:
319 options = ' ' + options
321 options = ' ' + options
320 return dodiff(ui, repo, cmdline + options, pats, opts)
322 return dodiff(ui, repo, cmdline + options, pats, opts)
321 doc = _('''\
323 doc = _('''\
322 use %(path)s to diff repository (or selected files)
324 use %(path)s to diff repository (or selected files)
323
325
324 Show differences between revisions for the specified files, using
326 Show differences between revisions for the specified files, using
325 the %(path)s program.
327 the %(path)s program.
326
328
327 When two revision arguments are given, then changes are shown
329 When two revision arguments are given, then changes are shown
328 between those revisions. If only one revision is specified then
330 between those revisions. If only one revision is specified then
329 that revision is compared to the working directory, and, when no
331 that revision is compared to the working directory, and, when no
330 revisions are specified, the working directory files are compared
332 revisions are specified, the working directory files are compared
331 to its parent.\
333 to its parent.\
332 ''') % {'path': util.uirepr(path)}
334 ''') % {'path': util.uirepr(path)}
333
335
334 # We must translate the docstring right away since it is
336 # We must translate the docstring right away since it is
335 # used as a format string. The string will unfortunately
337 # used as a format string. The string will unfortunately
336 # be translated again in commands.helpcmd and this will
338 # be translated again in commands.helpcmd and this will
337 # fail when the docstring contains non-ASCII characters.
339 # fail when the docstring contains non-ASCII characters.
338 # Decoding the string to a Unicode string here (using the
340 # Decoding the string to a Unicode string here (using the
339 # right encoding) prevents that.
341 # right encoding) prevents that.
340 mydiff.__doc__ = doc.decode(encoding.encoding)
342 mydiff.__doc__ = doc.decode(encoding.encoding)
341 return mydiff
343 return mydiff
342 cmdtable[cmd] = (save(cmdline),
344 cmdtable[cmd] = (save(cmdline),
343 cmdtable['extdiff'][1][1:],
345 cmdtable['extdiff'][1][1:],
344 _('hg %s [OPTION]... [FILE]...') % cmd)
346 _('hg %s [OPTION]... [FILE]...') % cmd)
@@ -1,694 +1,708 b''
1 This file focuses mainly on updating largefiles in the working
1 This file focuses mainly on updating largefiles in the working
2 directory (and ".hg/largefiles/dirstate")
2 directory (and ".hg/largefiles/dirstate")
3
3
4 $ cat >> $HGRCPATH <<EOF
4 $ cat >> $HGRCPATH <<EOF
5 > [ui]
5 > [ui]
6 > merge = internal:fail
6 > merge = internal:fail
7 > [extensions]
7 > [extensions]
8 > largefiles =
8 > largefiles =
9 > EOF
9 > EOF
10
10
11 $ hg init repo
11 $ hg init repo
12 $ cd repo
12 $ cd repo
13
13
14 $ echo large1 > large1
14 $ echo large1 > large1
15 $ echo large2 > large2
15 $ echo large2 > large2
16 $ hg add --large large1 large2
16 $ hg add --large large1 large2
17 $ echo normal1 > normal1
17 $ echo normal1 > normal1
18 $ hg add normal1
18 $ hg add normal1
19 $ hg commit -m '#0'
19 $ hg commit -m '#0'
20 $ echo 'large1 in #1' > large1
20 $ echo 'large1 in #1' > large1
21 $ echo 'normal1 in #1' > normal1
21 $ echo 'normal1 in #1' > normal1
22 $ hg commit -m '#1'
22 $ hg commit -m '#1'
23 $ hg extdiff -r '.^' --config extensions.extdiff=
24 diff -Npru repo.0d9d9b8dc9a3/.hglf/large1 repo/.hglf/large1
25 --- repo.0d9d9b8dc9a3/.hglf/large1 * (glob)
26 +++ repo/.hglf/large1 * (glob)
27 @@ -1 +1 @@
28 -4669e532d5b2c093a78eca010077e708a071bb64
29 +58e24f733a964da346e2407a2bee99d9001184f5
30 diff -Npru repo.0d9d9b8dc9a3/normal1 repo/normal1
31 --- repo.0d9d9b8dc9a3/normal1 * (glob)
32 +++ repo/normal1 * (glob)
33 @@ -1 +1 @@
34 -normal1
35 +normal1 in #1
36 [1]
23 $ hg update -q -C 0
37 $ hg update -q -C 0
24 $ echo 'large2 in #2' > large2
38 $ echo 'large2 in #2' > large2
25 $ hg commit -m '#2'
39 $ hg commit -m '#2'
26 created new head
40 created new head
27
41
28 Test that update also updates the lfdirstate of 'unsure' largefiles after
42 Test that update also updates the lfdirstate of 'unsure' largefiles after
29 hashing them:
43 hashing them:
30
44
31 The previous operations will usually have left us with largefiles with a mtime
45 The previous operations will usually have left us with largefiles with a mtime
32 within the same second as the dirstate was written.
46 within the same second as the dirstate was written.
33 The lfdirstate entries will thus have been written with an invalidated/unset
47 The lfdirstate entries will thus have been written with an invalidated/unset
34 mtime to make sure further changes within the same second is detected.
48 mtime to make sure further changes within the same second is detected.
35 We will however occasionally be "lucky" and get a tick between writing
49 We will however occasionally be "lucky" and get a tick between writing
36 largefiles and writing dirstate so we get valid lfdirstate timestamps. The
50 largefiles and writing dirstate so we get valid lfdirstate timestamps. The
37 following verification is thus disabled but can be verified manually.
51 following verification is thus disabled but can be verified manually.
38
52
39 #if false
53 #if false
40 $ hg debugdirstate --large --nodate
54 $ hg debugdirstate --large --nodate
41 n 644 7 unset large1
55 n 644 7 unset large1
42 n 644 13 unset large2
56 n 644 13 unset large2
43 #endif
57 #endif
44
58
45 Wait to make sure we get a tick so the mtime of the largefiles become valid.
59 Wait to make sure we get a tick so the mtime of the largefiles become valid.
46
60
47 $ sleep 1
61 $ sleep 1
48
62
49 A linear merge will update standins before performing the actual merge. It will
63 A linear merge will update standins before performing the actual merge. It will
50 do a lfdirstate status walk and find 'unset'/'unsure' files, hash them, and
64 do a lfdirstate status walk and find 'unset'/'unsure' files, hash them, and
51 update the corresponding standins.
65 update the corresponding standins.
52 Verify that it actually marks the clean files as clean in lfdirstate so
66 Verify that it actually marks the clean files as clean in lfdirstate so
53 we don't have to hash them again next time we update.
67 we don't have to hash them again next time we update.
54
68
55 $ hg up
69 $ hg up
56 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
70 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
57 $ hg debugdirstate --large --nodate
71 $ hg debugdirstate --large --nodate
58 n 644 7 set large1
72 n 644 7 set large1
59 n 644 13 set large2
73 n 644 13 set large2
60
74
61 Test that lfdirstate keeps track of last modification of largefiles and
75 Test that lfdirstate keeps track of last modification of largefiles and
62 prevents unnecessary hashing of content - also after linear/noop update
76 prevents unnecessary hashing of content - also after linear/noop update
63
77
64 $ sleep 1
78 $ sleep 1
65 $ hg st
79 $ hg st
66 $ hg debugdirstate --large --nodate
80 $ hg debugdirstate --large --nodate
67 n 644 7 set large1
81 n 644 7 set large1
68 n 644 13 set large2
82 n 644 13 set large2
69 $ hg up
83 $ hg up
70 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
84 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
71 $ hg debugdirstate --large --nodate
85 $ hg debugdirstate --large --nodate
72 n 644 7 set large1
86 n 644 7 set large1
73 n 644 13 set large2
87 n 644 13 set large2
74
88
75 Test that "hg merge" updates largefiles from "other" correctly
89 Test that "hg merge" updates largefiles from "other" correctly
76
90
77 (getting largefiles from "other" normally)
91 (getting largefiles from "other" normally)
78
92
79 $ hg status -A large1
93 $ hg status -A large1
80 C large1
94 C large1
81 $ cat large1
95 $ cat large1
82 large1
96 large1
83 $ cat .hglf/large1
97 $ cat .hglf/large1
84 4669e532d5b2c093a78eca010077e708a071bb64
98 4669e532d5b2c093a78eca010077e708a071bb64
85 $ hg merge --config debug.dirstate.delaywrite=2
99 $ hg merge --config debug.dirstate.delaywrite=2
86 getting changed largefiles
100 getting changed largefiles
87 1 largefiles updated, 0 removed
101 1 largefiles updated, 0 removed
88 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
102 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
89 (branch merge, don't forget to commit)
103 (branch merge, don't forget to commit)
90 $ hg status -A large1
104 $ hg status -A large1
91 M large1
105 M large1
92 $ cat large1
106 $ cat large1
93 large1 in #1
107 large1 in #1
94 $ cat .hglf/large1
108 $ cat .hglf/large1
95 58e24f733a964da346e2407a2bee99d9001184f5
109 58e24f733a964da346e2407a2bee99d9001184f5
96 $ hg diff -c 1 --nodates .hglf/large1 | grep '^[+-][0-9a-z]'
110 $ hg diff -c 1 --nodates .hglf/large1 | grep '^[+-][0-9a-z]'
97 -4669e532d5b2c093a78eca010077e708a071bb64
111 -4669e532d5b2c093a78eca010077e708a071bb64
98 +58e24f733a964da346e2407a2bee99d9001184f5
112 +58e24f733a964da346e2407a2bee99d9001184f5
99
113
100 (getting largefiles from "other" via conflict prompt)
114 (getting largefiles from "other" via conflict prompt)
101
115
102 $ hg update -q -C 2
116 $ hg update -q -C 2
103 $ echo 'large1 in #3' > large1
117 $ echo 'large1 in #3' > large1
104 $ echo 'normal1 in #3' > normal1
118 $ echo 'normal1 in #3' > normal1
105 $ hg commit -m '#3'
119 $ hg commit -m '#3'
106 $ cat .hglf/large1
120 $ cat .hglf/large1
107 e5bb990443d6a92aaf7223813720f7566c9dd05b
121 e5bb990443d6a92aaf7223813720f7566c9dd05b
108 $ hg merge --config debug.dirstate.delaywrite=2 --config ui.interactive=True <<EOF
122 $ hg merge --config debug.dirstate.delaywrite=2 --config ui.interactive=True <<EOF
109 > o
123 > o
110 > EOF
124 > EOF
111 largefile large1 has a merge conflict
125 largefile large1 has a merge conflict
112 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
126 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
113 keep (l)ocal e5bb990443d6a92aaf7223813720f7566c9dd05b or
127 keep (l)ocal e5bb990443d6a92aaf7223813720f7566c9dd05b or
114 take (o)ther 58e24f733a964da346e2407a2bee99d9001184f5? o
128 take (o)ther 58e24f733a964da346e2407a2bee99d9001184f5? o
115 merging normal1
129 merging normal1
116 warning: conflicts during merge.
130 warning: conflicts during merge.
117 merging normal1 incomplete! (edit conflicts, then use 'hg resolve --mark')
131 merging normal1 incomplete! (edit conflicts, then use 'hg resolve --mark')
118 getting changed largefiles
132 getting changed largefiles
119 1 largefiles updated, 0 removed
133 1 largefiles updated, 0 removed
120 0 files updated, 1 files merged, 0 files removed, 1 files unresolved
134 0 files updated, 1 files merged, 0 files removed, 1 files unresolved
121 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
135 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
122 [1]
136 [1]
123 $ hg status -A large1
137 $ hg status -A large1
124 M large1
138 M large1
125 $ cat large1
139 $ cat large1
126 large1 in #1
140 large1 in #1
127 $ cat .hglf/large1
141 $ cat .hglf/large1
128 58e24f733a964da346e2407a2bee99d9001184f5
142 58e24f733a964da346e2407a2bee99d9001184f5
129
143
130 Test that "hg revert -r REV" updates largefiles from "REV" correctly
144 Test that "hg revert -r REV" updates largefiles from "REV" correctly
131
145
132 $ hg update -q -C 3
146 $ hg update -q -C 3
133 $ hg status -A large1
147 $ hg status -A large1
134 C large1
148 C large1
135 $ cat large1
149 $ cat large1
136 large1 in #3
150 large1 in #3
137 $ cat .hglf/large1
151 $ cat .hglf/large1
138 e5bb990443d6a92aaf7223813720f7566c9dd05b
152 e5bb990443d6a92aaf7223813720f7566c9dd05b
139 $ hg diff -c 1 --nodates .hglf/large1 | grep '^[+-][0-9a-z]'
153 $ hg diff -c 1 --nodates .hglf/large1 | grep '^[+-][0-9a-z]'
140 -4669e532d5b2c093a78eca010077e708a071bb64
154 -4669e532d5b2c093a78eca010077e708a071bb64
141 +58e24f733a964da346e2407a2bee99d9001184f5
155 +58e24f733a964da346e2407a2bee99d9001184f5
142 $ hg revert --no-backup -r 1 --config debug.dirstate.delaywrite=2 large1
156 $ hg revert --no-backup -r 1 --config debug.dirstate.delaywrite=2 large1
143 $ hg status -A large1
157 $ hg status -A large1
144 M large1
158 M large1
145 $ cat large1
159 $ cat large1
146 large1 in #1
160 large1 in #1
147 $ cat .hglf/large1
161 $ cat .hglf/large1
148 58e24f733a964da346e2407a2bee99d9001184f5
162 58e24f733a964da346e2407a2bee99d9001184f5
149
163
150 Test that "hg rollback" restores status of largefiles correctly
164 Test that "hg rollback" restores status of largefiles correctly
151
165
152 $ hg update -C -q
166 $ hg update -C -q
153 $ hg remove large1
167 $ hg remove large1
154 $ test -f .hglf/large1
168 $ test -f .hglf/large1
155 [1]
169 [1]
156 $ hg forget large2
170 $ hg forget large2
157 $ test -f .hglf/large2
171 $ test -f .hglf/large2
158 [1]
172 [1]
159 $ echo largeX > largeX
173 $ echo largeX > largeX
160 $ hg add --large largeX
174 $ hg add --large largeX
161 $ cat .hglf/largeX
175 $ cat .hglf/largeX
162
176
163 $ hg commit -m 'will be rollback-ed soon'
177 $ hg commit -m 'will be rollback-ed soon'
164 $ echo largeY > largeY
178 $ echo largeY > largeY
165 $ hg add --large largeY
179 $ hg add --large largeY
166 #if windows
180 #if windows
167 $ hg status -A large1
181 $ hg status -A large1
168 large1: * (glob)
182 large1: * (glob)
169 #else
183 #else
170 $ hg status -A large1
184 $ hg status -A large1
171 large1: No such file or directory
185 large1: No such file or directory
172 #endif
186 #endif
173 $ hg status -A large2
187 $ hg status -A large2
174 ? large2
188 ? large2
175 $ hg status -A largeX
189 $ hg status -A largeX
176 C largeX
190 C largeX
177 $ hg status -A largeY
191 $ hg status -A largeY
178 A largeY
192 A largeY
179 $ hg rollback
193 $ hg rollback
180 repository tip rolled back to revision 3 (undo commit)
194 repository tip rolled back to revision 3 (undo commit)
181 working directory now based on revision 3
195 working directory now based on revision 3
182 $ hg status -A large1
196 $ hg status -A large1
183 R large1
197 R large1
184 $ test -f .hglf/large1
198 $ test -f .hglf/large1
185 [1]
199 [1]
186 $ hg status -A large2
200 $ hg status -A large2
187 R large2
201 R large2
188 $ test -f .hglf/large2
202 $ test -f .hglf/large2
189 [1]
203 [1]
190 $ hg status -A largeX
204 $ hg status -A largeX
191 A largeX
205 A largeX
192 $ cat .hglf/largeX
206 $ cat .hglf/largeX
193
207
194 $ hg status -A largeY
208 $ hg status -A largeY
195 ? largeY
209 ? largeY
196 $ test -f .hglf/largeY
210 $ test -f .hglf/largeY
197 [1]
211 [1]
198
212
199 Test that "hg rollback" restores standins correctly
213 Test that "hg rollback" restores standins correctly
200
214
201 $ hg commit -m 'will be rollback-ed soon'
215 $ hg commit -m 'will be rollback-ed soon'
202 $ hg update -q -C 2
216 $ hg update -q -C 2
203 $ cat large1
217 $ cat large1
204 large1
218 large1
205 $ cat .hglf/large1
219 $ cat .hglf/large1
206 4669e532d5b2c093a78eca010077e708a071bb64
220 4669e532d5b2c093a78eca010077e708a071bb64
207 $ cat large2
221 $ cat large2
208 large2 in #2
222 large2 in #2
209 $ cat .hglf/large2
223 $ cat .hglf/large2
210 3cfce6277e7668985707b6887ce56f9f62f6ccd9
224 3cfce6277e7668985707b6887ce56f9f62f6ccd9
211
225
212 $ hg rollback -q -f
226 $ hg rollback -q -f
213 $ cat large1
227 $ cat large1
214 large1
228 large1
215 $ cat .hglf/large1
229 $ cat .hglf/large1
216 4669e532d5b2c093a78eca010077e708a071bb64
230 4669e532d5b2c093a78eca010077e708a071bb64
217 $ cat large2
231 $ cat large2
218 large2 in #2
232 large2 in #2
219 $ cat .hglf/large2
233 $ cat .hglf/large2
220 3cfce6277e7668985707b6887ce56f9f62f6ccd9
234 3cfce6277e7668985707b6887ce56f9f62f6ccd9
221
235
222 (rollback the parent of the working directory, when the parent of it
236 (rollback the parent of the working directory, when the parent of it
223 is not branch-tip)
237 is not branch-tip)
224
238
225 $ hg update -q -C 1
239 $ hg update -q -C 1
226 $ cat .hglf/large1
240 $ cat .hglf/large1
227 58e24f733a964da346e2407a2bee99d9001184f5
241 58e24f733a964da346e2407a2bee99d9001184f5
228 $ cat .hglf/large2
242 $ cat .hglf/large2
229 1deebade43c8c498a3c8daddac0244dc55d1331d
243 1deebade43c8c498a3c8daddac0244dc55d1331d
230
244
231 $ echo normalX > normalX
245 $ echo normalX > normalX
232 $ hg add normalX
246 $ hg add normalX
233 $ hg commit -m 'will be rollback-ed soon'
247 $ hg commit -m 'will be rollback-ed soon'
234 $ hg rollback -q
248 $ hg rollback -q
235
249
236 $ cat .hglf/large1
250 $ cat .hglf/large1
237 58e24f733a964da346e2407a2bee99d9001184f5
251 58e24f733a964da346e2407a2bee99d9001184f5
238 $ cat .hglf/large2
252 $ cat .hglf/large2
239 1deebade43c8c498a3c8daddac0244dc55d1331d
253 1deebade43c8c498a3c8daddac0244dc55d1331d
240
254
241 Test that "hg status" shows status of largefiles correctly just after
255 Test that "hg status" shows status of largefiles correctly just after
242 automated commit like rebase/transplant
256 automated commit like rebase/transplant
243
257
244 $ cat >> .hg/hgrc <<EOF
258 $ cat >> .hg/hgrc <<EOF
245 > [extensions]
259 > [extensions]
246 > rebase =
260 > rebase =
247 > strip =
261 > strip =
248 > transplant =
262 > transplant =
249 > EOF
263 > EOF
250 $ hg update -q -C 1
264 $ hg update -q -C 1
251 $ hg remove large1
265 $ hg remove large1
252 $ echo largeX > largeX
266 $ echo largeX > largeX
253 $ hg add --large largeX
267 $ hg add --large largeX
254 $ hg commit -m '#4'
268 $ hg commit -m '#4'
255
269
256 $ hg rebase -s 1 -d 2 --keep
270 $ hg rebase -s 1 -d 2 --keep
257 rebasing 1:72518492caa6 "#1"
271 rebasing 1:72518492caa6 "#1"
258 rebasing 4:07d6153b5c04 "#4" (tip)
272 rebasing 4:07d6153b5c04 "#4" (tip)
259 #if windows
273 #if windows
260 $ hg status -A large1
274 $ hg status -A large1
261 large1: * (glob)
275 large1: * (glob)
262 #else
276 #else
263 $ hg status -A large1
277 $ hg status -A large1
264 large1: No such file or directory
278 large1: No such file or directory
265 #endif
279 #endif
266 $ hg status -A largeX
280 $ hg status -A largeX
267 C largeX
281 C largeX
268 $ hg strip -q 5
282 $ hg strip -q 5
269
283
270 $ hg update -q -C 2
284 $ hg update -q -C 2
271 $ hg transplant -q 1 4
285 $ hg transplant -q 1 4
272 #if windows
286 #if windows
273 $ hg status -A large1
287 $ hg status -A large1
274 large1: * (glob)
288 large1: * (glob)
275 #else
289 #else
276 $ hg status -A large1
290 $ hg status -A large1
277 large1: No such file or directory
291 large1: No such file or directory
278 #endif
292 #endif
279 $ hg status -A largeX
293 $ hg status -A largeX
280 C largeX
294 C largeX
281 $ hg strip -q 5
295 $ hg strip -q 5
282
296
283 $ hg update -q -C 2
297 $ hg update -q -C 2
284 $ hg transplant -q --merge 1 --merge 4
298 $ hg transplant -q --merge 1 --merge 4
285 #if windows
299 #if windows
286 $ hg status -A large1
300 $ hg status -A large1
287 large1: * (glob)
301 large1: * (glob)
288 #else
302 #else
289 $ hg status -A large1
303 $ hg status -A large1
290 large1: No such file or directory
304 large1: No such file or directory
291 #endif
305 #endif
292 $ hg status -A largeX
306 $ hg status -A largeX
293 C largeX
307 C largeX
294 $ hg strip -q 5
308 $ hg strip -q 5
295
309
296 Test that linear merge can detect modification (and conflict) correctly
310 Test that linear merge can detect modification (and conflict) correctly
297
311
298 (linear merge without conflict)
312 (linear merge without conflict)
299
313
300 $ echo 'large2 for linear merge (no conflict)' > large2
314 $ echo 'large2 for linear merge (no conflict)' > large2
301 $ hg update 3 --config debug.dirstate.delaywrite=2
315 $ hg update 3 --config debug.dirstate.delaywrite=2
302 getting changed largefiles
316 getting changed largefiles
303 1 largefiles updated, 0 removed
317 1 largefiles updated, 0 removed
304 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
318 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
305 $ hg status -A large2
319 $ hg status -A large2
306 M large2
320 M large2
307 $ cat large2
321 $ cat large2
308 large2 for linear merge (no conflict)
322 large2 for linear merge (no conflict)
309 $ cat .hglf/large2
323 $ cat .hglf/large2
310 9c4bf8f1b33536d6e5f89447e10620cfe52ea710
324 9c4bf8f1b33536d6e5f89447e10620cfe52ea710
311
325
312 (linear merge with conflict, choosing "other")
326 (linear merge with conflict, choosing "other")
313
327
314 $ hg update -q -C 2
328 $ hg update -q -C 2
315 $ echo 'large1 for linear merge (conflict)' > large1
329 $ echo 'large1 for linear merge (conflict)' > large1
316 $ hg update 3 --config ui.interactive=True <<EOF
330 $ hg update 3 --config ui.interactive=True <<EOF
317 > o
331 > o
318 > EOF
332 > EOF
319 largefile large1 has a merge conflict
333 largefile large1 has a merge conflict
320 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
334 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
321 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
335 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
322 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? o
336 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? o
323 getting changed largefiles
337 getting changed largefiles
324 1 largefiles updated, 0 removed
338 1 largefiles updated, 0 removed
325 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
339 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
326 $ hg status -A large1
340 $ hg status -A large1
327 C large1
341 C large1
328 $ cat large1
342 $ cat large1
329 large1 in #3
343 large1 in #3
330 $ cat .hglf/large1
344 $ cat .hglf/large1
331 e5bb990443d6a92aaf7223813720f7566c9dd05b
345 e5bb990443d6a92aaf7223813720f7566c9dd05b
332
346
333 (linear merge with conflict, choosing "local")
347 (linear merge with conflict, choosing "local")
334
348
335 $ hg update -q -C 2
349 $ hg update -q -C 2
336 $ echo 'large1 for linear merge (conflict)' > large1
350 $ echo 'large1 for linear merge (conflict)' > large1
337 $ hg update 3 --config debug.dirstate.delaywrite=2
351 $ hg update 3 --config debug.dirstate.delaywrite=2
338 largefile large1 has a merge conflict
352 largefile large1 has a merge conflict
339 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
353 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
340 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
354 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
341 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l
355 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l
342 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
356 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
343 $ hg status -A large1
357 $ hg status -A large1
344 M large1
358 M large1
345 $ cat large1
359 $ cat large1
346 large1 for linear merge (conflict)
360 large1 for linear merge (conflict)
347 $ cat .hglf/large1
361 $ cat .hglf/large1
348 ba94c2efe5b7c5e0af8d189295ce00553b0612b7
362 ba94c2efe5b7c5e0af8d189295ce00553b0612b7
349
363
350 Test a linear merge to a revision containing same-name normal file
364 Test a linear merge to a revision containing same-name normal file
351
365
352 $ hg update -q -C 3
366 $ hg update -q -C 3
353 $ hg remove large2
367 $ hg remove large2
354 $ echo 'large2 as normal file' > large2
368 $ echo 'large2 as normal file' > large2
355 $ hg add large2
369 $ hg add large2
356 $ echo 'large3 as normal file' > large3
370 $ echo 'large3 as normal file' > large3
357 $ hg add large3
371 $ hg add large3
358 $ hg commit -m '#5'
372 $ hg commit -m '#5'
359 $ hg manifest
373 $ hg manifest
360 .hglf/large1
374 .hglf/large1
361 large2
375 large2
362 large3
376 large3
363 normal1
377 normal1
364
378
365 (modified largefile is already switched to normal)
379 (modified largefile is already switched to normal)
366
380
367 $ hg update -q -C 2
381 $ hg update -q -C 2
368 $ echo 'modified large2 for linear merge' > large2
382 $ echo 'modified large2 for linear merge' > large2
369 $ hg update -q 5
383 $ hg update -q 5
370 remote turned local largefile large2 into a normal file
384 remote turned local largefile large2 into a normal file
371 keep (l)argefile or use (n)ormal file? l
385 keep (l)argefile or use (n)ormal file? l
372 $ hg debugdirstate --nodates | grep large2
386 $ hg debugdirstate --nodates | grep large2
373 a 0 -1 unset .hglf/large2
387 a 0 -1 unset .hglf/large2
374 r 0 0 set large2
388 r 0 0 set large2
375 $ hg status -A large2
389 $ hg status -A large2
376 A large2
390 A large2
377 $ cat large2
391 $ cat large2
378 modified large2 for linear merge
392 modified large2 for linear merge
379
393
380 (added largefile is already committed as normal)
394 (added largefile is already committed as normal)
381
395
382 $ hg update -q -C 2
396 $ hg update -q -C 2
383 $ echo 'large3 as large file for linear merge' > large3
397 $ echo 'large3 as large file for linear merge' > large3
384 $ hg add --large large3
398 $ hg add --large large3
385 $ hg update -q 5
399 $ hg update -q 5
386 remote turned local largefile large3 into a normal file
400 remote turned local largefile large3 into a normal file
387 keep (l)argefile or use (n)ormal file? l
401 keep (l)argefile or use (n)ormal file? l
388 $ hg debugdirstate --nodates | grep large3
402 $ hg debugdirstate --nodates | grep large3
389 a 0 -1 unset .hglf/large3
403 a 0 -1 unset .hglf/large3
390 r 0 0 set large3
404 r 0 0 set large3
391 $ hg status -A large3
405 $ hg status -A large3
392 A large3
406 A large3
393 $ cat large3
407 $ cat large3
394 large3 as large file for linear merge
408 large3 as large file for linear merge
395 $ rm -f large3 .hglf/large3
409 $ rm -f large3 .hglf/large3
396
410
397 Test that the internal linear merging works correctly
411 Test that the internal linear merging works correctly
398 (both heads are stripped to keep pairing of revision number and commit log)
412 (both heads are stripped to keep pairing of revision number and commit log)
399
413
400 $ hg update -q -C 2
414 $ hg update -q -C 2
401 $ hg strip 3 4
415 $ hg strip 3 4
402 saved backup bundle to $TESTTMP/repo/.hg/strip-backup/9530e27857f7-2e7b195d-backup.hg (glob)
416 saved backup bundle to $TESTTMP/repo/.hg/strip-backup/9530e27857f7-2e7b195d-backup.hg (glob)
403 $ mv .hg/strip-backup/9530e27857f7-2e7b195d-backup.hg $TESTTMP
417 $ mv .hg/strip-backup/9530e27857f7-2e7b195d-backup.hg $TESTTMP
404
418
405 (internal linear merging at "hg pull --update")
419 (internal linear merging at "hg pull --update")
406
420
407 $ echo 'large1 for linear merge (conflict)' > large1
421 $ echo 'large1 for linear merge (conflict)' > large1
408 $ echo 'large2 for linear merge (conflict with normal file)' > large2
422 $ echo 'large2 for linear merge (conflict with normal file)' > large2
409 $ hg pull --update --config debug.dirstate.delaywrite=2 $TESTTMP/9530e27857f7-2e7b195d-backup.hg
423 $ hg pull --update --config debug.dirstate.delaywrite=2 $TESTTMP/9530e27857f7-2e7b195d-backup.hg
410 pulling from $TESTTMP/9530e27857f7-2e7b195d-backup.hg (glob)
424 pulling from $TESTTMP/9530e27857f7-2e7b195d-backup.hg (glob)
411 searching for changes
425 searching for changes
412 adding changesets
426 adding changesets
413 adding manifests
427 adding manifests
414 adding file changes
428 adding file changes
415 added 3 changesets with 5 changes to 5 files
429 added 3 changesets with 5 changes to 5 files
416 remote turned local largefile large2 into a normal file
430 remote turned local largefile large2 into a normal file
417 keep (l)argefile or use (n)ormal file? l
431 keep (l)argefile or use (n)ormal file? l
418 largefile large1 has a merge conflict
432 largefile large1 has a merge conflict
419 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
433 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
420 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
434 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
421 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l
435 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l
422 2 files updated, 1 files merged, 0 files removed, 0 files unresolved
436 2 files updated, 1 files merged, 0 files removed, 0 files unresolved
423
437
424 $ hg status -A large1
438 $ hg status -A large1
425 M large1
439 M large1
426 $ cat large1
440 $ cat large1
427 large1 for linear merge (conflict)
441 large1 for linear merge (conflict)
428 $ cat .hglf/large1
442 $ cat .hglf/large1
429 ba94c2efe5b7c5e0af8d189295ce00553b0612b7
443 ba94c2efe5b7c5e0af8d189295ce00553b0612b7
430 $ hg status -A large2
444 $ hg status -A large2
431 A large2
445 A large2
432 $ cat large2
446 $ cat large2
433 large2 for linear merge (conflict with normal file)
447 large2 for linear merge (conflict with normal file)
434 $ cat .hglf/large2
448 $ cat .hglf/large2
435 d7591fe9be0f6227d90bddf3e4f52ff41fc1f544
449 d7591fe9be0f6227d90bddf3e4f52ff41fc1f544
436
450
437 (internal linear merging at "hg unbundle --update")
451 (internal linear merging at "hg unbundle --update")
438
452
439 $ hg update -q -C 2
453 $ hg update -q -C 2
440 $ hg rollback -q
454 $ hg rollback -q
441
455
442 $ echo 'large1 for linear merge (conflict)' > large1
456 $ echo 'large1 for linear merge (conflict)' > large1
443 $ echo 'large2 for linear merge (conflict with normal file)' > large2
457 $ echo 'large2 for linear merge (conflict with normal file)' > large2
444 $ hg unbundle --update --config debug.dirstate.delaywrite=2 $TESTTMP/9530e27857f7-2e7b195d-backup.hg
458 $ hg unbundle --update --config debug.dirstate.delaywrite=2 $TESTTMP/9530e27857f7-2e7b195d-backup.hg
445 adding changesets
459 adding changesets
446 adding manifests
460 adding manifests
447 adding file changes
461 adding file changes
448 added 3 changesets with 5 changes to 5 files
462 added 3 changesets with 5 changes to 5 files
449 remote turned local largefile large2 into a normal file
463 remote turned local largefile large2 into a normal file
450 keep (l)argefile or use (n)ormal file? l
464 keep (l)argefile or use (n)ormal file? l
451 largefile large1 has a merge conflict
465 largefile large1 has a merge conflict
452 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
466 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
453 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
467 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
454 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l
468 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l
455 2 files updated, 1 files merged, 0 files removed, 0 files unresolved
469 2 files updated, 1 files merged, 0 files removed, 0 files unresolved
456
470
457 $ hg status -A large1
471 $ hg status -A large1
458 M large1
472 M large1
459 $ cat large1
473 $ cat large1
460 large1 for linear merge (conflict)
474 large1 for linear merge (conflict)
461 $ cat .hglf/large1
475 $ cat .hglf/large1
462 ba94c2efe5b7c5e0af8d189295ce00553b0612b7
476 ba94c2efe5b7c5e0af8d189295ce00553b0612b7
463 $ hg status -A large2
477 $ hg status -A large2
464 A large2
478 A large2
465 $ cat large2
479 $ cat large2
466 large2 for linear merge (conflict with normal file)
480 large2 for linear merge (conflict with normal file)
467 $ cat .hglf/large2
481 $ cat .hglf/large2
468 d7591fe9be0f6227d90bddf3e4f52ff41fc1f544
482 d7591fe9be0f6227d90bddf3e4f52ff41fc1f544
469
483
470 (internal linear merging in subrepo at "hg update")
484 (internal linear merging in subrepo at "hg update")
471
485
472 $ cd ..
486 $ cd ..
473 $ hg init subparent
487 $ hg init subparent
474 $ cd subparent
488 $ cd subparent
475
489
476 $ hg clone -q -u 2 ../repo sub
490 $ hg clone -q -u 2 ../repo sub
477 $ cat > .hgsub <<EOF
491 $ cat > .hgsub <<EOF
478 > sub = sub
492 > sub = sub
479 > EOF
493 > EOF
480 $ hg add .hgsub
494 $ hg add .hgsub
481 $ hg commit -m '#0@parent'
495 $ hg commit -m '#0@parent'
482 $ cat .hgsubstate
496 $ cat .hgsubstate
483 f74e50bd9e5594b7cf1e6c5cbab86ddd25f3ca2f sub
497 f74e50bd9e5594b7cf1e6c5cbab86ddd25f3ca2f sub
484 $ hg -R sub update -q
498 $ hg -R sub update -q
485 $ hg commit -m '#1@parent'
499 $ hg commit -m '#1@parent'
486 $ cat .hgsubstate
500 $ cat .hgsubstate
487 d65e59e952a9638e2ce863b41a420ca723dd3e8d sub
501 d65e59e952a9638e2ce863b41a420ca723dd3e8d sub
488 $ hg update -q 0
502 $ hg update -q 0
489
503
490 $ echo 'large1 for linear merge (conflict)' > sub/large1
504 $ echo 'large1 for linear merge (conflict)' > sub/large1
491 $ echo 'large2 for linear merge (conflict with normal file)' > sub/large2
505 $ echo 'large2 for linear merge (conflict with normal file)' > sub/large2
492 $ hg update --config ui.interactive=True --config debug.dirstate.delaywrite=2 <<EOF
506 $ hg update --config ui.interactive=True --config debug.dirstate.delaywrite=2 <<EOF
493 > m
507 > m
494 > r
508 > r
495 > l
509 > l
496 > l
510 > l
497 > EOF
511 > EOF
498 subrepository sub diverged (local revision: f74e50bd9e55, remote revision: d65e59e952a9)
512 subrepository sub diverged (local revision: f74e50bd9e55, remote revision: d65e59e952a9)
499 (M)erge, keep (l)ocal or keep (r)emote? m
513 (M)erge, keep (l)ocal or keep (r)emote? m
500 subrepository sources for sub differ (in checked out version)
514 subrepository sources for sub differ (in checked out version)
501 use (l)ocal source (f74e50bd9e55) or (r)emote source (d65e59e952a9)? r
515 use (l)ocal source (f74e50bd9e55) or (r)emote source (d65e59e952a9)? r
502 remote turned local largefile large2 into a normal file
516 remote turned local largefile large2 into a normal file
503 keep (l)argefile or use (n)ormal file? l
517 keep (l)argefile or use (n)ormal file? l
504 largefile large1 has a merge conflict
518 largefile large1 has a merge conflict
505 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
519 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
506 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
520 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
507 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l
521 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l
508 2 files updated, 1 files merged, 0 files removed, 0 files unresolved
522 2 files updated, 1 files merged, 0 files removed, 0 files unresolved
509 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
523 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
510
524
511 $ hg -R sub status -A sub/large1
525 $ hg -R sub status -A sub/large1
512 M sub/large1
526 M sub/large1
513 $ cat sub/large1
527 $ cat sub/large1
514 large1 for linear merge (conflict)
528 large1 for linear merge (conflict)
515 $ cat sub/.hglf/large1
529 $ cat sub/.hglf/large1
516 ba94c2efe5b7c5e0af8d189295ce00553b0612b7
530 ba94c2efe5b7c5e0af8d189295ce00553b0612b7
517 $ hg -R sub status -A sub/large2
531 $ hg -R sub status -A sub/large2
518 A sub/large2
532 A sub/large2
519 $ cat sub/large2
533 $ cat sub/large2
520 large2 for linear merge (conflict with normal file)
534 large2 for linear merge (conflict with normal file)
521 $ cat sub/.hglf/large2
535 $ cat sub/.hglf/large2
522 d7591fe9be0f6227d90bddf3e4f52ff41fc1f544
536 d7591fe9be0f6227d90bddf3e4f52ff41fc1f544
523
537
524 $ cd ..
538 $ cd ..
525 $ cd repo
539 $ cd repo
526
540
527 Test that rebase updates largefiles in the working directory even if
541 Test that rebase updates largefiles in the working directory even if
528 it is aborted by conflict.
542 it is aborted by conflict.
529
543
530 $ hg update -q -C 3
544 $ hg update -q -C 3
531 $ cat .hglf/large1
545 $ cat .hglf/large1
532 e5bb990443d6a92aaf7223813720f7566c9dd05b
546 e5bb990443d6a92aaf7223813720f7566c9dd05b
533 $ cat large1
547 $ cat large1
534 large1 in #3
548 large1 in #3
535 $ hg rebase -s 1 -d 3 --keep --config ui.interactive=True <<EOF
549 $ hg rebase -s 1 -d 3 --keep --config ui.interactive=True <<EOF
536 > o
550 > o
537 > EOF
551 > EOF
538 rebasing 1:72518492caa6 "#1"
552 rebasing 1:72518492caa6 "#1"
539 largefile large1 has a merge conflict
553 largefile large1 has a merge conflict
540 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
554 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
541 keep (l)ocal e5bb990443d6a92aaf7223813720f7566c9dd05b or
555 keep (l)ocal e5bb990443d6a92aaf7223813720f7566c9dd05b or
542 take (o)ther 58e24f733a964da346e2407a2bee99d9001184f5? o
556 take (o)ther 58e24f733a964da346e2407a2bee99d9001184f5? o
543 merging normal1
557 merging normal1
544 warning: conflicts during merge.
558 warning: conflicts during merge.
545 merging normal1 incomplete! (edit conflicts, then use 'hg resolve --mark')
559 merging normal1 incomplete! (edit conflicts, then use 'hg resolve --mark')
546 unresolved conflicts (see hg resolve, then hg rebase --continue)
560 unresolved conflicts (see hg resolve, then hg rebase --continue)
547 [1]
561 [1]
548 $ cat .hglf/large1
562 $ cat .hglf/large1
549 58e24f733a964da346e2407a2bee99d9001184f5
563 58e24f733a964da346e2407a2bee99d9001184f5
550 $ cat large1
564 $ cat large1
551 large1 in #1
565 large1 in #1
552
566
553 Test that rebase updates standins for manually modified largefiles at
567 Test that rebase updates standins for manually modified largefiles at
554 the 1st commit of resuming.
568 the 1st commit of resuming.
555
569
556 $ echo "manually modified before 'hg rebase --continue'" > large1
570 $ echo "manually modified before 'hg rebase --continue'" > large1
557 $ hg resolve -m normal1
571 $ hg resolve -m normal1
558 (no more unresolved files)
572 (no more unresolved files)
559 $ hg rebase --continue --config ui.interactive=True <<EOF
573 $ hg rebase --continue --config ui.interactive=True <<EOF
560 > c
574 > c
561 > EOF
575 > EOF
562 rebasing 1:72518492caa6 "#1"
576 rebasing 1:72518492caa6 "#1"
563 rebasing 4:07d6153b5c04 "#4"
577 rebasing 4:07d6153b5c04 "#4"
564 local changed .hglf/large1 which remote deleted
578 local changed .hglf/large1 which remote deleted
565 use (c)hanged version or (d)elete? c
579 use (c)hanged version or (d)elete? c
566
580
567 $ hg diff -c "tip~1" --nodates .hglf/large1 | grep '^[+-][0-9a-z]'
581 $ hg diff -c "tip~1" --nodates .hglf/large1 | grep '^[+-][0-9a-z]'
568 -e5bb990443d6a92aaf7223813720f7566c9dd05b
582 -e5bb990443d6a92aaf7223813720f7566c9dd05b
569 +8a4f783556e7dea21139ca0466eafce954c75c13
583 +8a4f783556e7dea21139ca0466eafce954c75c13
570 $ rm -f large1
584 $ rm -f large1
571 $ hg update -q -C tip
585 $ hg update -q -C tip
572 $ cat large1
586 $ cat large1
573 manually modified before 'hg rebase --continue'
587 manually modified before 'hg rebase --continue'
574
588
575 Test that transplant updates largefiles, of which standins are safely
589 Test that transplant updates largefiles, of which standins are safely
576 changed, even if it is aborted by conflict of other.
590 changed, even if it is aborted by conflict of other.
577
591
578 $ hg update -q -C 5
592 $ hg update -q -C 5
579 $ cat .hglf/large1
593 $ cat .hglf/large1
580 e5bb990443d6a92aaf7223813720f7566c9dd05b
594 e5bb990443d6a92aaf7223813720f7566c9dd05b
581 $ cat large1
595 $ cat large1
582 large1 in #3
596 large1 in #3
583 $ hg diff -c 4 .hglf/largeX | grep '^[+-][0-9a-z]'
597 $ hg diff -c 4 .hglf/largeX | grep '^[+-][0-9a-z]'
584 +fa44618ea25181aff4f48b70428294790cec9f61
598 +fa44618ea25181aff4f48b70428294790cec9f61
585 $ hg transplant 4
599 $ hg transplant 4
586 applying 07d6153b5c04
600 applying 07d6153b5c04
587 patching file .hglf/large1
601 patching file .hglf/large1
588 Hunk #1 FAILED at 0
602 Hunk #1 FAILED at 0
589 1 out of 1 hunks FAILED -- saving rejects to file .hglf/large1.rej
603 1 out of 1 hunks FAILED -- saving rejects to file .hglf/large1.rej
590 patch failed to apply
604 patch failed to apply
591 abort: fix up the merge and run hg transplant --continue
605 abort: fix up the merge and run hg transplant --continue
592 [255]
606 [255]
593 $ hg status -A large1
607 $ hg status -A large1
594 C large1
608 C large1
595 $ cat .hglf/large1
609 $ cat .hglf/large1
596 e5bb990443d6a92aaf7223813720f7566c9dd05b
610 e5bb990443d6a92aaf7223813720f7566c9dd05b
597 $ cat large1
611 $ cat large1
598 large1 in #3
612 large1 in #3
599 $ hg status -A largeX
613 $ hg status -A largeX
600 A largeX
614 A largeX
601 $ cat .hglf/largeX
615 $ cat .hglf/largeX
602 fa44618ea25181aff4f48b70428294790cec9f61
616 fa44618ea25181aff4f48b70428294790cec9f61
603 $ cat largeX
617 $ cat largeX
604 largeX
618 largeX
605
619
606 Test that transplant updates standins for manually modified largefiles
620 Test that transplant updates standins for manually modified largefiles
607 at the 1st commit of resuming.
621 at the 1st commit of resuming.
608
622
609 $ echo "manually modified before 'hg transplant --continue'" > large1
623 $ echo "manually modified before 'hg transplant --continue'" > large1
610 $ hg transplant --continue
624 $ hg transplant --continue
611 07d6153b5c04 transplanted as f1bf30eb88cc
625 07d6153b5c04 transplanted as f1bf30eb88cc
612 $ hg diff -c tip .hglf/large1 | grep '^[+-][0-9a-z]'
626 $ hg diff -c tip .hglf/large1 | grep '^[+-][0-9a-z]'
613 -e5bb990443d6a92aaf7223813720f7566c9dd05b
627 -e5bb990443d6a92aaf7223813720f7566c9dd05b
614 +6a4f36d4075fbe0f30ec1d26ca44e63c05903671
628 +6a4f36d4075fbe0f30ec1d26ca44e63c05903671
615 $ rm -f large1
629 $ rm -f large1
616 $ hg update -q -C tip
630 $ hg update -q -C tip
617 $ cat large1
631 $ cat large1
618 manually modified before 'hg transplant --continue'
632 manually modified before 'hg transplant --continue'
619
633
620 Test that "hg status" doesn't show removal of largefiles not managed
634 Test that "hg status" doesn't show removal of largefiles not managed
621 in the target context.
635 in the target context.
622
636
623 $ hg update -q -C 4
637 $ hg update -q -C 4
624 $ hg remove largeX
638 $ hg remove largeX
625 $ hg status -A largeX
639 $ hg status -A largeX
626 R largeX
640 R largeX
627 $ hg status -A --rev '.^1' largeX
641 $ hg status -A --rev '.^1' largeX
628
642
629 #if execbit
643 #if execbit
630
644
631 Test that "hg status" against revisions other than parent notices exec
645 Test that "hg status" against revisions other than parent notices exec
632 bit changes of largefiles.
646 bit changes of largefiles.
633
647
634 $ hg update -q -C 4
648 $ hg update -q -C 4
635
649
636 (the case that large2 doesn't have exec bit in the target context but
650 (the case that large2 doesn't have exec bit in the target context but
637 in the working context)
651 in the working context)
638
652
639 $ chmod +x large2
653 $ chmod +x large2
640 $ hg status -A --rev 0 large2
654 $ hg status -A --rev 0 large2
641 M large2
655 M large2
642 $ hg commit -m 'chmod +x large2'
656 $ hg commit -m 'chmod +x large2'
643
657
644 (the case that large2 has exec bit in the target context but not in
658 (the case that large2 has exec bit in the target context but not in
645 the working context)
659 the working context)
646
660
647 $ echo dummy > dummy
661 $ echo dummy > dummy
648 $ hg add dummy
662 $ hg add dummy
649 $ hg commit -m 'revision for separation'
663 $ hg commit -m 'revision for separation'
650 $ chmod -x large2
664 $ chmod -x large2
651 $ hg status -A --rev '.^1' large2
665 $ hg status -A --rev '.^1' large2
652 M large2
666 M large2
653
667
654 #else
668 #else
655
669
656 Test that "hg status" against revisions other than parent ignores exec
670 Test that "hg status" against revisions other than parent ignores exec
657 bit correctly on the platform being unaware of it.
671 bit correctly on the platform being unaware of it.
658
672
659 $ hg update -q -C 4
673 $ hg update -q -C 4
660
674
661 $ cat > exec-bit.patch <<EOF
675 $ cat > exec-bit.patch <<EOF
662 > # HG changeset patch
676 > # HG changeset patch
663 > # User test
677 > # User test
664 > # Date 0 0
678 > # Date 0 0
665 > # Thu Jan 01 00:00:00 1970 +0000
679 > # Thu Jan 01 00:00:00 1970 +0000
666 > # Node ID be1b433a65b12b27b5519d92213e14f7e1769b90
680 > # Node ID be1b433a65b12b27b5519d92213e14f7e1769b90
667 > # Parent 07d6153b5c04313efb75deec9ba577de7faeb727
681 > # Parent 07d6153b5c04313efb75deec9ba577de7faeb727
668 > chmod +x large2
682 > chmod +x large2
669 >
683 >
670 > diff --git a/.hglf/large2 b/.hglf/large2
684 > diff --git a/.hglf/large2 b/.hglf/large2
671 > old mode 100644
685 > old mode 100644
672 > new mode 100755
686 > new mode 100755
673 > EOF
687 > EOF
674 $ hg import --exact --bypass exec-bit.patch
688 $ hg import --exact --bypass exec-bit.patch
675 applying exec-bit.patch
689 applying exec-bit.patch
676 $ hg status -A --rev tip large2
690 $ hg status -A --rev tip large2
677 C large2
691 C large2
678
692
679 #endif
693 #endif
680
694
681 $ cd ..
695 $ cd ..
682
696
683 Test that "hg convert" avoids copying largefiles from the working
697 Test that "hg convert" avoids copying largefiles from the working
684 directory into store, because "hg convert" doesn't update largefiles
698 directory into store, because "hg convert" doesn't update largefiles
685 in the working directory (removing files under ".cache/largefiles"
699 in the working directory (removing files under ".cache/largefiles"
686 forces "hg convert" to copy corresponding largefiles)
700 forces "hg convert" to copy corresponding largefiles)
687
701
688 $ cat >> $HGRCPATH <<EOF
702 $ cat >> $HGRCPATH <<EOF
689 > [extensions]
703 > [extensions]
690 > convert =
704 > convert =
691 > EOF
705 > EOF
692
706
693 $ rm $TESTTMP/.cache/largefiles/6a4f36d4075fbe0f30ec1d26ca44e63c05903671
707 $ rm $TESTTMP/.cache/largefiles/6a4f36d4075fbe0f30ec1d26ca44e63c05903671
694 $ hg convert -q repo repo.converted
708 $ hg convert -q repo repo.converted
General Comments 0
You need to be logged in to leave comments. Login now