##// END OF EJS Templates
largefiles: specify where .orig files are kept...
Christian Delahousse -
r26944:ef5bab63 default
parent child Browse files
Show More
@@ -1,550 +1,552 b''
1 # Copyright 2009-2010 Gregory P. Ward
1 # Copyright 2009-2010 Gregory P. Ward
2 # Copyright 2009-2010 Intelerad Medical Systems Incorporated
2 # Copyright 2009-2010 Intelerad Medical Systems Incorporated
3 # Copyright 2010-2011 Fog Creek Software
3 # Copyright 2010-2011 Fog Creek Software
4 # Copyright 2010-2011 Unity Technologies
4 # Copyright 2010-2011 Unity Technologies
5 #
5 #
6 # This software may be used and distributed according to the terms of the
6 # This software may be used and distributed according to the terms of the
7 # GNU General Public License version 2 or any later version.
7 # GNU General Public License version 2 or any later version.
8
8
9 '''High-level command function for lfconvert, plus the cmdtable.'''
9 '''High-level command function for lfconvert, plus the cmdtable.'''
10
10
11 import os, errno
11 import os, errno
12 import shutil
12 import shutil
13
13
14 from mercurial import util, match as match_, hg, node, context, error, \
14 from mercurial import util, match as match_, hg, node, context, error, \
15 cmdutil, scmutil, commands
15 cmdutil, scmutil, commands
16 from mercurial.i18n import _
16 from mercurial.i18n import _
17 from mercurial.lock import release
17 from mercurial.lock import release
18
18
19 from hgext.convert import convcmd
19 from hgext.convert import convcmd
20 from hgext.convert import filemap
20 from hgext.convert import filemap
21
21
22 import lfutil
22 import lfutil
23 import basestore
23 import basestore
24
24
25 # -- Commands ----------------------------------------------------------
25 # -- Commands ----------------------------------------------------------
26
26
27 cmdtable = {}
27 cmdtable = {}
28 command = cmdutil.command(cmdtable)
28 command = cmdutil.command(cmdtable)
29
29
30 @command('lfconvert',
30 @command('lfconvert',
31 [('s', 'size', '',
31 [('s', 'size', '',
32 _('minimum size (MB) for files to be converted as largefiles'), 'SIZE'),
32 _('minimum size (MB) for files to be converted as largefiles'), 'SIZE'),
33 ('', 'to-normal', False,
33 ('', 'to-normal', False,
34 _('convert from a largefiles repo to a normal repo')),
34 _('convert from a largefiles repo to a normal repo')),
35 ],
35 ],
36 _('hg lfconvert SOURCE DEST [FILE ...]'),
36 _('hg lfconvert SOURCE DEST [FILE ...]'),
37 norepo=True,
37 norepo=True,
38 inferrepo=True)
38 inferrepo=True)
39 def lfconvert(ui, src, dest, *pats, **opts):
39 def lfconvert(ui, src, dest, *pats, **opts):
40 '''convert a normal repository to a largefiles repository
40 '''convert a normal repository to a largefiles repository
41
41
42 Convert repository SOURCE to a new repository DEST, identical to
42 Convert repository SOURCE to a new repository DEST, identical to
43 SOURCE except that certain files will be converted as largefiles:
43 SOURCE except that certain files will be converted as largefiles:
44 specifically, any file that matches any PATTERN *or* whose size is
44 specifically, any file that matches any PATTERN *or* whose size is
45 above the minimum size threshold is converted as a largefile. The
45 above the minimum size threshold is converted as a largefile. The
46 size used to determine whether or not to track a file as a
46 size used to determine whether or not to track a file as a
47 largefile is the size of the first version of the file. The
47 largefile is the size of the first version of the file. The
48 minimum size can be specified either with --size or in
48 minimum size can be specified either with --size or in
49 configuration as ``largefiles.size``.
49 configuration as ``largefiles.size``.
50
50
51 After running this command you will need to make sure that
51 After running this command you will need to make sure that
52 largefiles is enabled anywhere you intend to push the new
52 largefiles is enabled anywhere you intend to push the new
53 repository.
53 repository.
54
54
55 Use --to-normal to convert largefiles back to normal files; after
55 Use --to-normal to convert largefiles back to normal files; after
56 this, the DEST repository can be used without largefiles at all.'''
56 this, the DEST repository can be used without largefiles at all.'''
57
57
58 if opts['to_normal']:
58 if opts['to_normal']:
59 tolfile = False
59 tolfile = False
60 else:
60 else:
61 tolfile = True
61 tolfile = True
62 size = lfutil.getminsize(ui, True, opts.get('size'), default=None)
62 size = lfutil.getminsize(ui, True, opts.get('size'), default=None)
63
63
64 if not hg.islocal(src):
64 if not hg.islocal(src):
65 raise error.Abort(_('%s is not a local Mercurial repo') % src)
65 raise error.Abort(_('%s is not a local Mercurial repo') % src)
66 if not hg.islocal(dest):
66 if not hg.islocal(dest):
67 raise error.Abort(_('%s is not a local Mercurial repo') % dest)
67 raise error.Abort(_('%s is not a local Mercurial repo') % dest)
68
68
69 rsrc = hg.repository(ui, src)
69 rsrc = hg.repository(ui, src)
70 ui.status(_('initializing destination %s\n') % dest)
70 ui.status(_('initializing destination %s\n') % dest)
71 rdst = hg.repository(ui, dest, create=True)
71 rdst = hg.repository(ui, dest, create=True)
72
72
73 success = False
73 success = False
74 dstwlock = dstlock = None
74 dstwlock = dstlock = None
75 try:
75 try:
76 # Get a list of all changesets in the source. The easy way to do this
76 # Get a list of all changesets in the source. The easy way to do this
77 # is to simply walk the changelog, using changelog.nodesbetween().
77 # is to simply walk the changelog, using changelog.nodesbetween().
78 # Take a look at mercurial/revlog.py:639 for more details.
78 # Take a look at mercurial/revlog.py:639 for more details.
79 # Use a generator instead of a list to decrease memory usage
79 # Use a generator instead of a list to decrease memory usage
80 ctxs = (rsrc[ctx] for ctx in rsrc.changelog.nodesbetween(None,
80 ctxs = (rsrc[ctx] for ctx in rsrc.changelog.nodesbetween(None,
81 rsrc.heads())[0])
81 rsrc.heads())[0])
82 revmap = {node.nullid: node.nullid}
82 revmap = {node.nullid: node.nullid}
83 if tolfile:
83 if tolfile:
84 # Lock destination to prevent modification while it is converted to.
84 # Lock destination to prevent modification while it is converted to.
85 # Don't need to lock src because we are just reading from its
85 # Don't need to lock src because we are just reading from its
86 # history which can't change.
86 # history which can't change.
87 dstwlock = rdst.wlock()
87 dstwlock = rdst.wlock()
88 dstlock = rdst.lock()
88 dstlock = rdst.lock()
89
89
90 lfiles = set()
90 lfiles = set()
91 normalfiles = set()
91 normalfiles = set()
92 if not pats:
92 if not pats:
93 pats = ui.configlist(lfutil.longname, 'patterns', default=[])
93 pats = ui.configlist(lfutil.longname, 'patterns', default=[])
94 if pats:
94 if pats:
95 matcher = match_.match(rsrc.root, '', list(pats))
95 matcher = match_.match(rsrc.root, '', list(pats))
96 else:
96 else:
97 matcher = None
97 matcher = None
98
98
99 lfiletohash = {}
99 lfiletohash = {}
100 for ctx in ctxs:
100 for ctx in ctxs:
101 ui.progress(_('converting revisions'), ctx.rev(),
101 ui.progress(_('converting revisions'), ctx.rev(),
102 unit=_('revision'), total=rsrc['tip'].rev())
102 unit=_('revision'), total=rsrc['tip'].rev())
103 _lfconvert_addchangeset(rsrc, rdst, ctx, revmap,
103 _lfconvert_addchangeset(rsrc, rdst, ctx, revmap,
104 lfiles, normalfiles, matcher, size, lfiletohash)
104 lfiles, normalfiles, matcher, size, lfiletohash)
105 ui.progress(_('converting revisions'), None)
105 ui.progress(_('converting revisions'), None)
106
106
107 if os.path.exists(rdst.wjoin(lfutil.shortname)):
107 if os.path.exists(rdst.wjoin(lfutil.shortname)):
108 shutil.rmtree(rdst.wjoin(lfutil.shortname))
108 shutil.rmtree(rdst.wjoin(lfutil.shortname))
109
109
110 for f in lfiletohash.keys():
110 for f in lfiletohash.keys():
111 if os.path.isfile(rdst.wjoin(f)):
111 if os.path.isfile(rdst.wjoin(f)):
112 os.unlink(rdst.wjoin(f))
112 os.unlink(rdst.wjoin(f))
113 try:
113 try:
114 os.removedirs(os.path.dirname(rdst.wjoin(f)))
114 os.removedirs(os.path.dirname(rdst.wjoin(f)))
115 except OSError:
115 except OSError:
116 pass
116 pass
117
117
118 # If there were any files converted to largefiles, add largefiles
118 # If there were any files converted to largefiles, add largefiles
119 # to the destination repository's requirements.
119 # to the destination repository's requirements.
120 if lfiles:
120 if lfiles:
121 rdst.requirements.add('largefiles')
121 rdst.requirements.add('largefiles')
122 rdst._writerequirements()
122 rdst._writerequirements()
123 else:
123 else:
124 class lfsource(filemap.filemap_source):
124 class lfsource(filemap.filemap_source):
125 def __init__(self, ui, source):
125 def __init__(self, ui, source):
126 super(lfsource, self).__init__(ui, source, None)
126 super(lfsource, self).__init__(ui, source, None)
127 self.filemapper.rename[lfutil.shortname] = '.'
127 self.filemapper.rename[lfutil.shortname] = '.'
128
128
129 def getfile(self, name, rev):
129 def getfile(self, name, rev):
130 realname, realrev = rev
130 realname, realrev = rev
131 f = super(lfsource, self).getfile(name, rev)
131 f = super(lfsource, self).getfile(name, rev)
132
132
133 if (not realname.startswith(lfutil.shortnameslash)
133 if (not realname.startswith(lfutil.shortnameslash)
134 or f[0] is None):
134 or f[0] is None):
135 return f
135 return f
136
136
137 # Substitute in the largefile data for the hash
137 # Substitute in the largefile data for the hash
138 hash = f[0].strip()
138 hash = f[0].strip()
139 path = lfutil.findfile(rsrc, hash)
139 path = lfutil.findfile(rsrc, hash)
140
140
141 if path is None:
141 if path is None:
142 raise error.Abort(_("missing largefile for '%s' in %s")
142 raise error.Abort(_("missing largefile for '%s' in %s")
143 % (realname, realrev))
143 % (realname, realrev))
144 fp = open(path, 'rb')
144 fp = open(path, 'rb')
145
145
146 try:
146 try:
147 return (fp.read(), f[1])
147 return (fp.read(), f[1])
148 finally:
148 finally:
149 fp.close()
149 fp.close()
150
150
151 class converter(convcmd.converter):
151 class converter(convcmd.converter):
152 def __init__(self, ui, source, dest, revmapfile, opts):
152 def __init__(self, ui, source, dest, revmapfile, opts):
153 src = lfsource(ui, source)
153 src = lfsource(ui, source)
154
154
155 super(converter, self).__init__(ui, src, dest, revmapfile,
155 super(converter, self).__init__(ui, src, dest, revmapfile,
156 opts)
156 opts)
157
157
158 found, missing = downloadlfiles(ui, rsrc)
158 found, missing = downloadlfiles(ui, rsrc)
159 if missing != 0:
159 if missing != 0:
160 raise error.Abort(_("all largefiles must be present locally"))
160 raise error.Abort(_("all largefiles must be present locally"))
161
161
162 orig = convcmd.converter
162 orig = convcmd.converter
163 convcmd.converter = converter
163 convcmd.converter = converter
164
164
165 try:
165 try:
166 convcmd.convert(ui, src, dest)
166 convcmd.convert(ui, src, dest)
167 finally:
167 finally:
168 convcmd.converter = orig
168 convcmd.converter = orig
169 success = True
169 success = True
170 finally:
170 finally:
171 if tolfile:
171 if tolfile:
172 rdst.dirstate.clear()
172 rdst.dirstate.clear()
173 release(dstlock, dstwlock)
173 release(dstlock, dstwlock)
174 if not success:
174 if not success:
175 # we failed, remove the new directory
175 # we failed, remove the new directory
176 shutil.rmtree(rdst.root)
176 shutil.rmtree(rdst.root)
177
177
178 def _lfconvert_addchangeset(rsrc, rdst, ctx, revmap, lfiles, normalfiles,
178 def _lfconvert_addchangeset(rsrc, rdst, ctx, revmap, lfiles, normalfiles,
179 matcher, size, lfiletohash):
179 matcher, size, lfiletohash):
180 # Convert src parents to dst parents
180 # Convert src parents to dst parents
181 parents = _convertparents(ctx, revmap)
181 parents = _convertparents(ctx, revmap)
182
182
183 # Generate list of changed files
183 # Generate list of changed files
184 files = _getchangedfiles(ctx, parents)
184 files = _getchangedfiles(ctx, parents)
185
185
186 dstfiles = []
186 dstfiles = []
187 for f in files:
187 for f in files:
188 if f not in lfiles and f not in normalfiles:
188 if f not in lfiles and f not in normalfiles:
189 islfile = _islfile(f, ctx, matcher, size)
189 islfile = _islfile(f, ctx, matcher, size)
190 # If this file was renamed or copied then copy
190 # If this file was renamed or copied then copy
191 # the largefile-ness of its predecessor
191 # the largefile-ness of its predecessor
192 if f in ctx.manifest():
192 if f in ctx.manifest():
193 fctx = ctx.filectx(f)
193 fctx = ctx.filectx(f)
194 renamed = fctx.renamed()
194 renamed = fctx.renamed()
195 renamedlfile = renamed and renamed[0] in lfiles
195 renamedlfile = renamed and renamed[0] in lfiles
196 islfile |= renamedlfile
196 islfile |= renamedlfile
197 if 'l' in fctx.flags():
197 if 'l' in fctx.flags():
198 if renamedlfile:
198 if renamedlfile:
199 raise error.Abort(
199 raise error.Abort(
200 _('renamed/copied largefile %s becomes symlink')
200 _('renamed/copied largefile %s becomes symlink')
201 % f)
201 % f)
202 islfile = False
202 islfile = False
203 if islfile:
203 if islfile:
204 lfiles.add(f)
204 lfiles.add(f)
205 else:
205 else:
206 normalfiles.add(f)
206 normalfiles.add(f)
207
207
208 if f in lfiles:
208 if f in lfiles:
209 dstfiles.append(lfutil.standin(f))
209 dstfiles.append(lfutil.standin(f))
210 # largefile in manifest if it has not been removed/renamed
210 # largefile in manifest if it has not been removed/renamed
211 if f in ctx.manifest():
211 if f in ctx.manifest():
212 fctx = ctx.filectx(f)
212 fctx = ctx.filectx(f)
213 if 'l' in fctx.flags():
213 if 'l' in fctx.flags():
214 renamed = fctx.renamed()
214 renamed = fctx.renamed()
215 if renamed and renamed[0] in lfiles:
215 if renamed and renamed[0] in lfiles:
216 raise error.Abort(_('largefile %s becomes symlink') % f)
216 raise error.Abort(_('largefile %s becomes symlink') % f)
217
217
218 # largefile was modified, update standins
218 # largefile was modified, update standins
219 m = util.sha1('')
219 m = util.sha1('')
220 m.update(ctx[f].data())
220 m.update(ctx[f].data())
221 hash = m.hexdigest()
221 hash = m.hexdigest()
222 if f not in lfiletohash or lfiletohash[f] != hash:
222 if f not in lfiletohash or lfiletohash[f] != hash:
223 rdst.wwrite(f, ctx[f].data(), ctx[f].flags())
223 rdst.wwrite(f, ctx[f].data(), ctx[f].flags())
224 executable = 'x' in ctx[f].flags()
224 executable = 'x' in ctx[f].flags()
225 lfutil.writestandin(rdst, lfutil.standin(f), hash,
225 lfutil.writestandin(rdst, lfutil.standin(f), hash,
226 executable)
226 executable)
227 lfiletohash[f] = hash
227 lfiletohash[f] = hash
228 else:
228 else:
229 # normal file
229 # normal file
230 dstfiles.append(f)
230 dstfiles.append(f)
231
231
232 def getfilectx(repo, memctx, f):
232 def getfilectx(repo, memctx, f):
233 if lfutil.isstandin(f):
233 if lfutil.isstandin(f):
234 # if the file isn't in the manifest then it was removed
234 # if the file isn't in the manifest then it was removed
235 # or renamed, raise IOError to indicate this
235 # or renamed, raise IOError to indicate this
236 srcfname = lfutil.splitstandin(f)
236 srcfname = lfutil.splitstandin(f)
237 try:
237 try:
238 fctx = ctx.filectx(srcfname)
238 fctx = ctx.filectx(srcfname)
239 except error.LookupError:
239 except error.LookupError:
240 return None
240 return None
241 renamed = fctx.renamed()
241 renamed = fctx.renamed()
242 if renamed:
242 if renamed:
243 # standin is always a largefile because largefile-ness
243 # standin is always a largefile because largefile-ness
244 # doesn't change after rename or copy
244 # doesn't change after rename or copy
245 renamed = lfutil.standin(renamed[0])
245 renamed = lfutil.standin(renamed[0])
246
246
247 return context.memfilectx(repo, f, lfiletohash[srcfname] + '\n',
247 return context.memfilectx(repo, f, lfiletohash[srcfname] + '\n',
248 'l' in fctx.flags(), 'x' in fctx.flags(),
248 'l' in fctx.flags(), 'x' in fctx.flags(),
249 renamed)
249 renamed)
250 else:
250 else:
251 return _getnormalcontext(repo, ctx, f, revmap)
251 return _getnormalcontext(repo, ctx, f, revmap)
252
252
253 # Commit
253 # Commit
254 _commitcontext(rdst, parents, ctx, dstfiles, getfilectx, revmap)
254 _commitcontext(rdst, parents, ctx, dstfiles, getfilectx, revmap)
255
255
256 def _commitcontext(rdst, parents, ctx, dstfiles, getfilectx, revmap):
256 def _commitcontext(rdst, parents, ctx, dstfiles, getfilectx, revmap):
257 mctx = context.memctx(rdst, parents, ctx.description(), dstfiles,
257 mctx = context.memctx(rdst, parents, ctx.description(), dstfiles,
258 getfilectx, ctx.user(), ctx.date(), ctx.extra())
258 getfilectx, ctx.user(), ctx.date(), ctx.extra())
259 ret = rdst.commitctx(mctx)
259 ret = rdst.commitctx(mctx)
260 lfutil.copyalltostore(rdst, ret)
260 lfutil.copyalltostore(rdst, ret)
261 rdst.setparents(ret)
261 rdst.setparents(ret)
262 revmap[ctx.node()] = rdst.changelog.tip()
262 revmap[ctx.node()] = rdst.changelog.tip()
263
263
264 # Generate list of changed files
264 # Generate list of changed files
265 def _getchangedfiles(ctx, parents):
265 def _getchangedfiles(ctx, parents):
266 files = set(ctx.files())
266 files = set(ctx.files())
267 if node.nullid not in parents:
267 if node.nullid not in parents:
268 mc = ctx.manifest()
268 mc = ctx.manifest()
269 mp1 = ctx.parents()[0].manifest()
269 mp1 = ctx.parents()[0].manifest()
270 mp2 = ctx.parents()[1].manifest()
270 mp2 = ctx.parents()[1].manifest()
271 files |= (set(mp1) | set(mp2)) - set(mc)
271 files |= (set(mp1) | set(mp2)) - set(mc)
272 for f in mc:
272 for f in mc:
273 if mc[f] != mp1.get(f, None) or mc[f] != mp2.get(f, None):
273 if mc[f] != mp1.get(f, None) or mc[f] != mp2.get(f, None):
274 files.add(f)
274 files.add(f)
275 return files
275 return files
276
276
277 # Convert src parents to dst parents
277 # Convert src parents to dst parents
278 def _convertparents(ctx, revmap):
278 def _convertparents(ctx, revmap):
279 parents = []
279 parents = []
280 for p in ctx.parents():
280 for p in ctx.parents():
281 parents.append(revmap[p.node()])
281 parents.append(revmap[p.node()])
282 while len(parents) < 2:
282 while len(parents) < 2:
283 parents.append(node.nullid)
283 parents.append(node.nullid)
284 return parents
284 return parents
285
285
286 # Get memfilectx for a normal file
286 # Get memfilectx for a normal file
287 def _getnormalcontext(repo, ctx, f, revmap):
287 def _getnormalcontext(repo, ctx, f, revmap):
288 try:
288 try:
289 fctx = ctx.filectx(f)
289 fctx = ctx.filectx(f)
290 except error.LookupError:
290 except error.LookupError:
291 return None
291 return None
292 renamed = fctx.renamed()
292 renamed = fctx.renamed()
293 if renamed:
293 if renamed:
294 renamed = renamed[0]
294 renamed = renamed[0]
295
295
296 data = fctx.data()
296 data = fctx.data()
297 if f == '.hgtags':
297 if f == '.hgtags':
298 data = _converttags (repo.ui, revmap, data)
298 data = _converttags (repo.ui, revmap, data)
299 return context.memfilectx(repo, f, data, 'l' in fctx.flags(),
299 return context.memfilectx(repo, f, data, 'l' in fctx.flags(),
300 'x' in fctx.flags(), renamed)
300 'x' in fctx.flags(), renamed)
301
301
302 # Remap tag data using a revision map
302 # Remap tag data using a revision map
303 def _converttags(ui, revmap, data):
303 def _converttags(ui, revmap, data):
304 newdata = []
304 newdata = []
305 for line in data.splitlines():
305 for line in data.splitlines():
306 try:
306 try:
307 id, name = line.split(' ', 1)
307 id, name = line.split(' ', 1)
308 except ValueError:
308 except ValueError:
309 ui.warn(_('skipping incorrectly formatted tag %s\n')
309 ui.warn(_('skipping incorrectly formatted tag %s\n')
310 % line)
310 % line)
311 continue
311 continue
312 try:
312 try:
313 newid = node.bin(id)
313 newid = node.bin(id)
314 except TypeError:
314 except TypeError:
315 ui.warn(_('skipping incorrectly formatted id %s\n')
315 ui.warn(_('skipping incorrectly formatted id %s\n')
316 % id)
316 % id)
317 continue
317 continue
318 try:
318 try:
319 newdata.append('%s %s\n' % (node.hex(revmap[newid]),
319 newdata.append('%s %s\n' % (node.hex(revmap[newid]),
320 name))
320 name))
321 except KeyError:
321 except KeyError:
322 ui.warn(_('no mapping for id %s\n') % id)
322 ui.warn(_('no mapping for id %s\n') % id)
323 continue
323 continue
324 return ''.join(newdata)
324 return ''.join(newdata)
325
325
326 def _islfile(file, ctx, matcher, size):
326 def _islfile(file, ctx, matcher, size):
327 '''Return true if file should be considered a largefile, i.e.
327 '''Return true if file should be considered a largefile, i.e.
328 matcher matches it or it is larger than size.'''
328 matcher matches it or it is larger than size.'''
329 # never store special .hg* files as largefiles
329 # never store special .hg* files as largefiles
330 if file == '.hgtags' or file == '.hgignore' or file == '.hgsigs':
330 if file == '.hgtags' or file == '.hgignore' or file == '.hgsigs':
331 return False
331 return False
332 if matcher and matcher(file):
332 if matcher and matcher(file):
333 return True
333 return True
334 try:
334 try:
335 return ctx.filectx(file).size() >= size * 1024 * 1024
335 return ctx.filectx(file).size() >= size * 1024 * 1024
336 except error.LookupError:
336 except error.LookupError:
337 return False
337 return False
338
338
339 def uploadlfiles(ui, rsrc, rdst, files):
339 def uploadlfiles(ui, rsrc, rdst, files):
340 '''upload largefiles to the central store'''
340 '''upload largefiles to the central store'''
341
341
342 if not files:
342 if not files:
343 return
343 return
344
344
345 store = basestore._openstore(rsrc, rdst, put=True)
345 store = basestore._openstore(rsrc, rdst, put=True)
346
346
347 at = 0
347 at = 0
348 ui.debug("sending statlfile command for %d largefiles\n" % len(files))
348 ui.debug("sending statlfile command for %d largefiles\n" % len(files))
349 retval = store.exists(files)
349 retval = store.exists(files)
350 files = filter(lambda h: not retval[h], files)
350 files = filter(lambda h: not retval[h], files)
351 ui.debug("%d largefiles need to be uploaded\n" % len(files))
351 ui.debug("%d largefiles need to be uploaded\n" % len(files))
352
352
353 for hash in files:
353 for hash in files:
354 ui.progress(_('uploading largefiles'), at, unit='largefile',
354 ui.progress(_('uploading largefiles'), at, unit='largefile',
355 total=len(files))
355 total=len(files))
356 source = lfutil.findfile(rsrc, hash)
356 source = lfutil.findfile(rsrc, hash)
357 if not source:
357 if not source:
358 raise error.Abort(_('largefile %s missing from store'
358 raise error.Abort(_('largefile %s missing from store'
359 ' (needs to be uploaded)') % hash)
359 ' (needs to be uploaded)') % hash)
360 # XXX check for errors here
360 # XXX check for errors here
361 store.put(source, hash)
361 store.put(source, hash)
362 at += 1
362 at += 1
363 ui.progress(_('uploading largefiles'), None)
363 ui.progress(_('uploading largefiles'), None)
364
364
365 def verifylfiles(ui, repo, all=False, contents=False):
365 def verifylfiles(ui, repo, all=False, contents=False):
366 '''Verify that every largefile revision in the current changeset
366 '''Verify that every largefile revision in the current changeset
367 exists in the central store. With --contents, also verify that
367 exists in the central store. With --contents, also verify that
368 the contents of each local largefile file revision are correct (SHA-1 hash
368 the contents of each local largefile file revision are correct (SHA-1 hash
369 matches the revision ID). With --all, check every changeset in
369 matches the revision ID). With --all, check every changeset in
370 this repository.'''
370 this repository.'''
371 if all:
371 if all:
372 revs = repo.revs('all()')
372 revs = repo.revs('all()')
373 else:
373 else:
374 revs = ['.']
374 revs = ['.']
375
375
376 store = basestore._openstore(repo)
376 store = basestore._openstore(repo)
377 return store.verify(revs, contents=contents)
377 return store.verify(revs, contents=contents)
378
378
379 def cachelfiles(ui, repo, node, filelist=None):
379 def cachelfiles(ui, repo, node, filelist=None):
380 '''cachelfiles ensures that all largefiles needed by the specified revision
380 '''cachelfiles ensures that all largefiles needed by the specified revision
381 are present in the repository's largefile cache.
381 are present in the repository's largefile cache.
382
382
383 returns a tuple (cached, missing). cached is the list of files downloaded
383 returns a tuple (cached, missing). cached is the list of files downloaded
384 by this operation; missing is the list of files that were needed but could
384 by this operation; missing is the list of files that were needed but could
385 not be found.'''
385 not be found.'''
386 lfiles = lfutil.listlfiles(repo, node)
386 lfiles = lfutil.listlfiles(repo, node)
387 if filelist:
387 if filelist:
388 lfiles = set(lfiles) & set(filelist)
388 lfiles = set(lfiles) & set(filelist)
389 toget = []
389 toget = []
390
390
391 for lfile in lfiles:
391 for lfile in lfiles:
392 try:
392 try:
393 expectedhash = repo[node][lfutil.standin(lfile)].data().strip()
393 expectedhash = repo[node][lfutil.standin(lfile)].data().strip()
394 except IOError as err:
394 except IOError as err:
395 if err.errno == errno.ENOENT:
395 if err.errno == errno.ENOENT:
396 continue # node must be None and standin wasn't found in wctx
396 continue # node must be None and standin wasn't found in wctx
397 raise
397 raise
398 if not lfutil.findfile(repo, expectedhash):
398 if not lfutil.findfile(repo, expectedhash):
399 toget.append((lfile, expectedhash))
399 toget.append((lfile, expectedhash))
400
400
401 if toget:
401 if toget:
402 store = basestore._openstore(repo)
402 store = basestore._openstore(repo)
403 ret = store.get(toget)
403 ret = store.get(toget)
404 return ret
404 return ret
405
405
406 return ([], [])
406 return ([], [])
407
407
408 def downloadlfiles(ui, repo, rev=None):
408 def downloadlfiles(ui, repo, rev=None):
409 matchfn = scmutil.match(repo[None],
409 matchfn = scmutil.match(repo[None],
410 [repo.wjoin(lfutil.shortname)], {})
410 [repo.wjoin(lfutil.shortname)], {})
411 def prepare(ctx, fns):
411 def prepare(ctx, fns):
412 pass
412 pass
413 totalsuccess = 0
413 totalsuccess = 0
414 totalmissing = 0
414 totalmissing = 0
415 if rev != []: # walkchangerevs on empty list would return all revs
415 if rev != []: # walkchangerevs on empty list would return all revs
416 for ctx in cmdutil.walkchangerevs(repo, matchfn, {'rev' : rev},
416 for ctx in cmdutil.walkchangerevs(repo, matchfn, {'rev' : rev},
417 prepare):
417 prepare):
418 success, missing = cachelfiles(ui, repo, ctx.node())
418 success, missing = cachelfiles(ui, repo, ctx.node())
419 totalsuccess += len(success)
419 totalsuccess += len(success)
420 totalmissing += len(missing)
420 totalmissing += len(missing)
421 ui.status(_("%d additional largefiles cached\n") % totalsuccess)
421 ui.status(_("%d additional largefiles cached\n") % totalsuccess)
422 if totalmissing > 0:
422 if totalmissing > 0:
423 ui.status(_("%d largefiles failed to download\n") % totalmissing)
423 ui.status(_("%d largefiles failed to download\n") % totalmissing)
424 return totalsuccess, totalmissing
424 return totalsuccess, totalmissing
425
425
426 def updatelfiles(ui, repo, filelist=None, printmessage=None,
426 def updatelfiles(ui, repo, filelist=None, printmessage=None,
427 normallookup=False):
427 normallookup=False):
428 '''Update largefiles according to standins in the working directory
428 '''Update largefiles according to standins in the working directory
429
429
430 If ``printmessage`` is other than ``None``, it means "print (or
430 If ``printmessage`` is other than ``None``, it means "print (or
431 ignore, for false) message forcibly".
431 ignore, for false) message forcibly".
432 '''
432 '''
433 statuswriter = lfutil.getstatuswriter(ui, repo, printmessage)
433 statuswriter = lfutil.getstatuswriter(ui, repo, printmessage)
434 wlock = repo.wlock()
434 wlock = repo.wlock()
435 try:
435 try:
436 lfdirstate = lfutil.openlfdirstate(ui, repo)
436 lfdirstate = lfutil.openlfdirstate(ui, repo)
437 lfiles = set(lfutil.listlfiles(repo)) | set(lfdirstate)
437 lfiles = set(lfutil.listlfiles(repo)) | set(lfdirstate)
438
438
439 if filelist is not None:
439 if filelist is not None:
440 filelist = set(filelist)
440 filelist = set(filelist)
441 lfiles = [f for f in lfiles if f in filelist]
441 lfiles = [f for f in lfiles if f in filelist]
442
442
443 update = {}
443 update = {}
444 updated, removed = 0, 0
444 updated, removed = 0, 0
445 for lfile in lfiles:
445 for lfile in lfiles:
446 abslfile = repo.wjoin(lfile)
446 abslfile = repo.wjoin(lfile)
447 abslfileorig = cmdutil.origpath(ui, repo, abslfile)
447 absstandin = repo.wjoin(lfutil.standin(lfile))
448 absstandin = repo.wjoin(lfutil.standin(lfile))
449 absstandinorig = cmdutil.origpath(ui, repo, absstandin)
448 if os.path.exists(absstandin):
450 if os.path.exists(absstandin):
449 if (os.path.exists(absstandin + '.orig') and
451 if (os.path.exists(absstandinorig) and
450 os.path.exists(abslfile)):
452 os.path.exists(abslfile)):
451 shutil.copyfile(abslfile, abslfile + '.orig')
453 shutil.copyfile(abslfile, abslfileorig)
452 util.unlinkpath(absstandin + '.orig')
454 util.unlinkpath(absstandinorig)
453 expecthash = lfutil.readstandin(repo, lfile)
455 expecthash = lfutil.readstandin(repo, lfile)
454 if expecthash != '':
456 if expecthash != '':
455 if lfile not in repo[None]: # not switched to normal file
457 if lfile not in repo[None]: # not switched to normal file
456 util.unlinkpath(abslfile, ignoremissing=True)
458 util.unlinkpath(abslfile, ignoremissing=True)
457 # use normallookup() to allocate an entry in largefiles
459 # use normallookup() to allocate an entry in largefiles
458 # dirstate to prevent lfilesrepo.status() from reporting
460 # dirstate to prevent lfilesrepo.status() from reporting
459 # missing files as removed.
461 # missing files as removed.
460 lfdirstate.normallookup(lfile)
462 lfdirstate.normallookup(lfile)
461 update[lfile] = expecthash
463 update[lfile] = expecthash
462 else:
464 else:
463 # Remove lfiles for which the standin is deleted, unless the
465 # Remove lfiles for which the standin is deleted, unless the
464 # lfile is added to the repository again. This happens when a
466 # lfile is added to the repository again. This happens when a
465 # largefile is converted back to a normal file: the standin
467 # largefile is converted back to a normal file: the standin
466 # disappears, but a new (normal) file appears as the lfile.
468 # disappears, but a new (normal) file appears as the lfile.
467 if (os.path.exists(abslfile) and
469 if (os.path.exists(abslfile) and
468 repo.dirstate.normalize(lfile) not in repo[None]):
470 repo.dirstate.normalize(lfile) not in repo[None]):
469 util.unlinkpath(abslfile)
471 util.unlinkpath(abslfile)
470 removed += 1
472 removed += 1
471
473
472 # largefile processing might be slow and be interrupted - be prepared
474 # largefile processing might be slow and be interrupted - be prepared
473 lfdirstate.write()
475 lfdirstate.write()
474
476
475 if lfiles:
477 if lfiles:
476 statuswriter(_('getting changed largefiles\n'))
478 statuswriter(_('getting changed largefiles\n'))
477 cachelfiles(ui, repo, None, lfiles)
479 cachelfiles(ui, repo, None, lfiles)
478
480
479 for lfile in lfiles:
481 for lfile in lfiles:
480 update1 = 0
482 update1 = 0
481
483
482 expecthash = update.get(lfile)
484 expecthash = update.get(lfile)
483 if expecthash:
485 if expecthash:
484 if not lfutil.copyfromcache(repo, expecthash, lfile):
486 if not lfutil.copyfromcache(repo, expecthash, lfile):
485 # failed ... but already removed and set to normallookup
487 # failed ... but already removed and set to normallookup
486 continue
488 continue
487 # Synchronize largefile dirstate to the last modified
489 # Synchronize largefile dirstate to the last modified
488 # time of the file
490 # time of the file
489 lfdirstate.normal(lfile)
491 lfdirstate.normal(lfile)
490 update1 = 1
492 update1 = 1
491
493
492 # copy the state of largefile standin from the repository's
494 # copy the state of largefile standin from the repository's
493 # dirstate to its state in the lfdirstate.
495 # dirstate to its state in the lfdirstate.
494 abslfile = repo.wjoin(lfile)
496 abslfile = repo.wjoin(lfile)
495 absstandin = repo.wjoin(lfutil.standin(lfile))
497 absstandin = repo.wjoin(lfutil.standin(lfile))
496 if os.path.exists(absstandin):
498 if os.path.exists(absstandin):
497 mode = os.stat(absstandin).st_mode
499 mode = os.stat(absstandin).st_mode
498 if mode != os.stat(abslfile).st_mode:
500 if mode != os.stat(abslfile).st_mode:
499 os.chmod(abslfile, mode)
501 os.chmod(abslfile, mode)
500 update1 = 1
502 update1 = 1
501
503
502 updated += update1
504 updated += update1
503
505
504 lfutil.synclfdirstate(repo, lfdirstate, lfile, normallookup)
506 lfutil.synclfdirstate(repo, lfdirstate, lfile, normallookup)
505
507
506 lfdirstate.write()
508 lfdirstate.write()
507 if lfiles:
509 if lfiles:
508 statuswriter(_('%d largefiles updated, %d removed\n') % (updated,
510 statuswriter(_('%d largefiles updated, %d removed\n') % (updated,
509 removed))
511 removed))
510 finally:
512 finally:
511 wlock.release()
513 wlock.release()
512
514
513 @command('lfpull',
515 @command('lfpull',
514 [('r', 'rev', [], _('pull largefiles for these revisions'))
516 [('r', 'rev', [], _('pull largefiles for these revisions'))
515 ] + commands.remoteopts,
517 ] + commands.remoteopts,
516 _('-r REV... [-e CMD] [--remotecmd CMD] [SOURCE]'))
518 _('-r REV... [-e CMD] [--remotecmd CMD] [SOURCE]'))
517 def lfpull(ui, repo, source="default", **opts):
519 def lfpull(ui, repo, source="default", **opts):
518 """pull largefiles for the specified revisions from the specified source
520 """pull largefiles for the specified revisions from the specified source
519
521
520 Pull largefiles that are referenced from local changesets but missing
522 Pull largefiles that are referenced from local changesets but missing
521 locally, pulling from a remote repository to the local cache.
523 locally, pulling from a remote repository to the local cache.
522
524
523 If SOURCE is omitted, the 'default' path will be used.
525 If SOURCE is omitted, the 'default' path will be used.
524 See :hg:`help urls` for more information.
526 See :hg:`help urls` for more information.
525
527
526 .. container:: verbose
528 .. container:: verbose
527
529
528 Some examples:
530 Some examples:
529
531
530 - pull largefiles for all branch heads::
532 - pull largefiles for all branch heads::
531
533
532 hg lfpull -r "head() and not closed()"
534 hg lfpull -r "head() and not closed()"
533
535
534 - pull largefiles on the default branch::
536 - pull largefiles on the default branch::
535
537
536 hg lfpull -r "branch(default)"
538 hg lfpull -r "branch(default)"
537 """
539 """
538 repo.lfpullsource = source
540 repo.lfpullsource = source
539
541
540 revs = opts.get('rev', [])
542 revs = opts.get('rev', [])
541 if not revs:
543 if not revs:
542 raise error.Abort(_('no revisions specified'))
544 raise error.Abort(_('no revisions specified'))
543 revs = scmutil.revrange(repo, revs)
545 revs = scmutil.revrange(repo, revs)
544
546
545 numcached = 0
547 numcached = 0
546 for rev in revs:
548 for rev in revs:
547 ui.note(_('pulling largefiles for revision %s\n') % rev)
549 ui.note(_('pulling largefiles for revision %s\n') % rev)
548 (cached, missing) = cachelfiles(ui, repo, rev)
550 (cached, missing) = cachelfiles(ui, repo, rev)
549 numcached += len(cached)
551 numcached += len(cached)
550 ui.status(_("%d largefiles cached\n") % numcached)
552 ui.status(_("%d largefiles cached\n") % numcached)
@@ -1,1089 +1,1101 b''
1 This file contains testcases that tend to be related to special cases or less
1 This file contains testcases that tend to be related to special cases or less
2 common commands affecting largefile.
2 common commands affecting largefile.
3
3
4 Each sections should be independent of each others.
4 Each sections should be independent of each others.
5
5
6 $ USERCACHE="$TESTTMP/cache"; export USERCACHE
6 $ USERCACHE="$TESTTMP/cache"; export USERCACHE
7 $ mkdir "${USERCACHE}"
7 $ mkdir "${USERCACHE}"
8 $ cat >> $HGRCPATH <<EOF
8 $ cat >> $HGRCPATH <<EOF
9 > [extensions]
9 > [extensions]
10 > largefiles=
10 > largefiles=
11 > purge=
11 > purge=
12 > rebase=
12 > rebase=
13 > transplant=
13 > transplant=
14 > [phases]
14 > [phases]
15 > publish=False
15 > publish=False
16 > [largefiles]
16 > [largefiles]
17 > minsize=2
17 > minsize=2
18 > patterns=glob:**.dat
18 > patterns=glob:**.dat
19 > usercache=${USERCACHE}
19 > usercache=${USERCACHE}
20 > [hooks]
20 > [hooks]
21 > precommit=sh -c "echo \\"Invoking status precommit hook\\"; hg status"
21 > precommit=sh -c "echo \\"Invoking status precommit hook\\"; hg status"
22 > EOF
22 > EOF
23
23
24
24
25
25
26 Test copies and moves from a directory other than root (issue3516)
26 Test copies and moves from a directory other than root (issue3516)
27 =========================================================================
27 =========================================================================
28
28
29 $ hg init lf_cpmv
29 $ hg init lf_cpmv
30 $ cd lf_cpmv
30 $ cd lf_cpmv
31 $ mkdir dira
31 $ mkdir dira
32 $ mkdir dira/dirb
32 $ mkdir dira/dirb
33 $ touch dira/dirb/largefile
33 $ touch dira/dirb/largefile
34 $ hg add --large dira/dirb/largefile
34 $ hg add --large dira/dirb/largefile
35 $ hg commit -m "added"
35 $ hg commit -m "added"
36 Invoking status precommit hook
36 Invoking status precommit hook
37 A dira/dirb/largefile
37 A dira/dirb/largefile
38 $ cd dira
38 $ cd dira
39 $ hg cp dirb/largefile foo/largefile
39 $ hg cp dirb/largefile foo/largefile
40
40
41 TODO: Ideally, this should mention the largefile, not the standin
41 TODO: Ideally, this should mention the largefile, not the standin
42 $ hg log -T '{rev}\n' --stat 'set:clean()'
42 $ hg log -T '{rev}\n' --stat 'set:clean()'
43 0
43 0
44 .hglf/dira/dirb/largefile | 1 +
44 .hglf/dira/dirb/largefile | 1 +
45 1 files changed, 1 insertions(+), 0 deletions(-)
45 1 files changed, 1 insertions(+), 0 deletions(-)
46
46
47 $ hg ci -m "deep copy"
47 $ hg ci -m "deep copy"
48 Invoking status precommit hook
48 Invoking status precommit hook
49 A dira/foo/largefile
49 A dira/foo/largefile
50 $ find . | sort
50 $ find . | sort
51 .
51 .
52 ./dirb
52 ./dirb
53 ./dirb/largefile
53 ./dirb/largefile
54 ./foo
54 ./foo
55 ./foo/largefile
55 ./foo/largefile
56 $ hg mv foo/largefile baz/largefile
56 $ hg mv foo/largefile baz/largefile
57 $ hg ci -m "moved"
57 $ hg ci -m "moved"
58 Invoking status precommit hook
58 Invoking status precommit hook
59 A dira/baz/largefile
59 A dira/baz/largefile
60 R dira/foo/largefile
60 R dira/foo/largefile
61 $ find . | sort
61 $ find . | sort
62 .
62 .
63 ./baz
63 ./baz
64 ./baz/largefile
64 ./baz/largefile
65 ./dirb
65 ./dirb
66 ./dirb/largefile
66 ./dirb/largefile
67 $ cd ..
67 $ cd ..
68 $ hg mv dira dirc
68 $ hg mv dira dirc
69 moving .hglf/dira/baz/largefile to .hglf/dirc/baz/largefile (glob)
69 moving .hglf/dira/baz/largefile to .hglf/dirc/baz/largefile (glob)
70 moving .hglf/dira/dirb/largefile to .hglf/dirc/dirb/largefile (glob)
70 moving .hglf/dira/dirb/largefile to .hglf/dirc/dirb/largefile (glob)
71 $ find * | sort
71 $ find * | sort
72 dirc
72 dirc
73 dirc/baz
73 dirc/baz
74 dirc/baz/largefile
74 dirc/baz/largefile
75 dirc/dirb
75 dirc/dirb
76 dirc/dirb/largefile
76 dirc/dirb/largefile
77
77
78 $ hg clone -q . ../fetch
78 $ hg clone -q . ../fetch
79 $ hg --config extensions.fetch= fetch ../fetch
79 $ hg --config extensions.fetch= fetch ../fetch
80 abort: uncommitted changes
80 abort: uncommitted changes
81 [255]
81 [255]
82 $ hg up -qC
82 $ hg up -qC
83 $ cd ..
83 $ cd ..
84
84
85 Clone a local repository owned by another user
85 Clone a local repository owned by another user
86 ===================================================
86 ===================================================
87
87
88 #if unix-permissions
88 #if unix-permissions
89
89
90 We have to simulate that here by setting $HOME and removing write permissions
90 We have to simulate that here by setting $HOME and removing write permissions
91 $ ORIGHOME="$HOME"
91 $ ORIGHOME="$HOME"
92 $ mkdir alice
92 $ mkdir alice
93 $ HOME="`pwd`/alice"
93 $ HOME="`pwd`/alice"
94 $ cd alice
94 $ cd alice
95 $ hg init pubrepo
95 $ hg init pubrepo
96 $ cd pubrepo
96 $ cd pubrepo
97 $ dd if=/dev/zero bs=1k count=11k > a-large-file 2> /dev/null
97 $ dd if=/dev/zero bs=1k count=11k > a-large-file 2> /dev/null
98 $ hg add --large a-large-file
98 $ hg add --large a-large-file
99 $ hg commit -m "Add a large file"
99 $ hg commit -m "Add a large file"
100 Invoking status precommit hook
100 Invoking status precommit hook
101 A a-large-file
101 A a-large-file
102 $ cd ..
102 $ cd ..
103 $ chmod -R a-w pubrepo
103 $ chmod -R a-w pubrepo
104 $ cd ..
104 $ cd ..
105 $ mkdir bob
105 $ mkdir bob
106 $ HOME="`pwd`/bob"
106 $ HOME="`pwd`/bob"
107 $ cd bob
107 $ cd bob
108 $ hg clone --pull ../alice/pubrepo pubrepo
108 $ hg clone --pull ../alice/pubrepo pubrepo
109 requesting all changes
109 requesting all changes
110 adding changesets
110 adding changesets
111 adding manifests
111 adding manifests
112 adding file changes
112 adding file changes
113 added 1 changesets with 1 changes to 1 files
113 added 1 changesets with 1 changes to 1 files
114 updating to branch default
114 updating to branch default
115 getting changed largefiles
115 getting changed largefiles
116 1 largefiles updated, 0 removed
116 1 largefiles updated, 0 removed
117 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
117 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
118 $ cd ..
118 $ cd ..
119 $ chmod -R u+w alice/pubrepo
119 $ chmod -R u+w alice/pubrepo
120 $ HOME="$ORIGHOME"
120 $ HOME="$ORIGHOME"
121
121
122 #endif
122 #endif
123
123
124
124
125 Symlink to a large largefile should behave the same as a symlink to a normal file
125 Symlink to a large largefile should behave the same as a symlink to a normal file
126 =====================================================================================
126 =====================================================================================
127
127
128 #if symlink
128 #if symlink
129
129
130 $ hg init largesymlink
130 $ hg init largesymlink
131 $ cd largesymlink
131 $ cd largesymlink
132 $ dd if=/dev/zero bs=1k count=10k of=largefile 2>/dev/null
132 $ dd if=/dev/zero bs=1k count=10k of=largefile 2>/dev/null
133 $ hg add --large largefile
133 $ hg add --large largefile
134 $ hg commit -m "commit a large file"
134 $ hg commit -m "commit a large file"
135 Invoking status precommit hook
135 Invoking status precommit hook
136 A largefile
136 A largefile
137 $ ln -s largefile largelink
137 $ ln -s largefile largelink
138 $ hg add largelink
138 $ hg add largelink
139 $ hg commit -m "commit a large symlink"
139 $ hg commit -m "commit a large symlink"
140 Invoking status precommit hook
140 Invoking status precommit hook
141 A largelink
141 A largelink
142 $ rm -f largelink
142 $ rm -f largelink
143 $ hg up >/dev/null
143 $ hg up >/dev/null
144 $ test -f largelink
144 $ test -f largelink
145 [1]
145 [1]
146 $ test -L largelink
146 $ test -L largelink
147 [1]
147 [1]
148 $ rm -f largelink # make next part of the test independent of the previous
148 $ rm -f largelink # make next part of the test independent of the previous
149 $ hg up -C >/dev/null
149 $ hg up -C >/dev/null
150 $ test -f largelink
150 $ test -f largelink
151 $ test -L largelink
151 $ test -L largelink
152 $ cd ..
152 $ cd ..
153
153
154 #endif
154 #endif
155
155
156
156
157 test for pattern matching on 'hg status':
157 test for pattern matching on 'hg status':
158 ==============================================
158 ==============================================
159
159
160
160
161 to boost performance, largefiles checks whether specified patterns are
161 to boost performance, largefiles checks whether specified patterns are
162 related to largefiles in working directory (NOT to STANDIN) or not.
162 related to largefiles in working directory (NOT to STANDIN) or not.
163
163
164 $ hg init statusmatch
164 $ hg init statusmatch
165 $ cd statusmatch
165 $ cd statusmatch
166
166
167 $ mkdir -p a/b/c/d
167 $ mkdir -p a/b/c/d
168 $ echo normal > a/b/c/d/e.normal.txt
168 $ echo normal > a/b/c/d/e.normal.txt
169 $ hg add a/b/c/d/e.normal.txt
169 $ hg add a/b/c/d/e.normal.txt
170 $ echo large > a/b/c/d/e.large.txt
170 $ echo large > a/b/c/d/e.large.txt
171 $ hg add --large a/b/c/d/e.large.txt
171 $ hg add --large a/b/c/d/e.large.txt
172 $ mkdir -p a/b/c/x
172 $ mkdir -p a/b/c/x
173 $ echo normal > a/b/c/x/y.normal.txt
173 $ echo normal > a/b/c/x/y.normal.txt
174 $ hg add a/b/c/x/y.normal.txt
174 $ hg add a/b/c/x/y.normal.txt
175 $ hg commit -m 'add files'
175 $ hg commit -m 'add files'
176 Invoking status precommit hook
176 Invoking status precommit hook
177 A a/b/c/d/e.large.txt
177 A a/b/c/d/e.large.txt
178 A a/b/c/d/e.normal.txt
178 A a/b/c/d/e.normal.txt
179 A a/b/c/x/y.normal.txt
179 A a/b/c/x/y.normal.txt
180
180
181 (1) no pattern: no performance boost
181 (1) no pattern: no performance boost
182 $ hg status -A
182 $ hg status -A
183 C a/b/c/d/e.large.txt
183 C a/b/c/d/e.large.txt
184 C a/b/c/d/e.normal.txt
184 C a/b/c/d/e.normal.txt
185 C a/b/c/x/y.normal.txt
185 C a/b/c/x/y.normal.txt
186
186
187 (2) pattern not related to largefiles: performance boost
187 (2) pattern not related to largefiles: performance boost
188 $ hg status -A a/b/c/x
188 $ hg status -A a/b/c/x
189 C a/b/c/x/y.normal.txt
189 C a/b/c/x/y.normal.txt
190
190
191 (3) pattern related to largefiles: no performance boost
191 (3) pattern related to largefiles: no performance boost
192 $ hg status -A a/b/c/d
192 $ hg status -A a/b/c/d
193 C a/b/c/d/e.large.txt
193 C a/b/c/d/e.large.txt
194 C a/b/c/d/e.normal.txt
194 C a/b/c/d/e.normal.txt
195
195
196 (4) pattern related to STANDIN (not to largefiles): performance boost
196 (4) pattern related to STANDIN (not to largefiles): performance boost
197 $ hg status -A .hglf/a
197 $ hg status -A .hglf/a
198 C .hglf/a/b/c/d/e.large.txt
198 C .hglf/a/b/c/d/e.large.txt
199
199
200 (5) mixed case: no performance boost
200 (5) mixed case: no performance boost
201 $ hg status -A a/b/c/x a/b/c/d
201 $ hg status -A a/b/c/x a/b/c/d
202 C a/b/c/d/e.large.txt
202 C a/b/c/d/e.large.txt
203 C a/b/c/d/e.normal.txt
203 C a/b/c/d/e.normal.txt
204 C a/b/c/x/y.normal.txt
204 C a/b/c/x/y.normal.txt
205
205
206 verify that largefiles doesn't break filesets
206 verify that largefiles doesn't break filesets
207
207
208 $ hg log --rev . --exclude "set:binary()"
208 $ hg log --rev . --exclude "set:binary()"
209 changeset: 0:41bd42f10efa
209 changeset: 0:41bd42f10efa
210 tag: tip
210 tag: tip
211 user: test
211 user: test
212 date: Thu Jan 01 00:00:00 1970 +0000
212 date: Thu Jan 01 00:00:00 1970 +0000
213 summary: add files
213 summary: add files
214
214
215 verify that large files in subrepos handled properly
215 verify that large files in subrepos handled properly
216 $ hg init subrepo
216 $ hg init subrepo
217 $ echo "subrepo = subrepo" > .hgsub
217 $ echo "subrepo = subrepo" > .hgsub
218 $ hg add .hgsub
218 $ hg add .hgsub
219 $ hg ci -m "add subrepo"
219 $ hg ci -m "add subrepo"
220 Invoking status precommit hook
220 Invoking status precommit hook
221 A .hgsub
221 A .hgsub
222 ? .hgsubstate
222 ? .hgsubstate
223 $ echo "rev 1" > subrepo/large.txt
223 $ echo "rev 1" > subrepo/large.txt
224 $ hg add --large subrepo/large.txt
224 $ hg add --large subrepo/large.txt
225 $ hg sum
225 $ hg sum
226 parent: 1:8ee150ea2e9c tip
226 parent: 1:8ee150ea2e9c tip
227 add subrepo
227 add subrepo
228 branch: default
228 branch: default
229 commit: 1 subrepos
229 commit: 1 subrepos
230 update: (current)
230 update: (current)
231 phases: 2 draft
231 phases: 2 draft
232 $ hg st
232 $ hg st
233 $ hg st -S
233 $ hg st -S
234 A subrepo/large.txt
234 A subrepo/large.txt
235 $ hg ci -S -m "commit top repo"
235 $ hg ci -S -m "commit top repo"
236 committing subrepository subrepo
236 committing subrepository subrepo
237 Invoking status precommit hook
237 Invoking status precommit hook
238 A large.txt
238 A large.txt
239 Invoking status precommit hook
239 Invoking status precommit hook
240 M .hgsubstate
240 M .hgsubstate
241 # No differences
241 # No differences
242 $ hg st -S
242 $ hg st -S
243 $ hg sum
243 $ hg sum
244 parent: 2:ce4cd0c527a6 tip
244 parent: 2:ce4cd0c527a6 tip
245 commit top repo
245 commit top repo
246 branch: default
246 branch: default
247 commit: (clean)
247 commit: (clean)
248 update: (current)
248 update: (current)
249 phases: 3 draft
249 phases: 3 draft
250 $ echo "rev 2" > subrepo/large.txt
250 $ echo "rev 2" > subrepo/large.txt
251 $ hg st -S
251 $ hg st -S
252 M subrepo/large.txt
252 M subrepo/large.txt
253 $ hg sum
253 $ hg sum
254 parent: 2:ce4cd0c527a6 tip
254 parent: 2:ce4cd0c527a6 tip
255 commit top repo
255 commit top repo
256 branch: default
256 branch: default
257 commit: 1 subrepos
257 commit: 1 subrepos
258 update: (current)
258 update: (current)
259 phases: 3 draft
259 phases: 3 draft
260 $ hg ci -m "this commit should fail without -S"
260 $ hg ci -m "this commit should fail without -S"
261 abort: uncommitted changes in subrepository 'subrepo'
261 abort: uncommitted changes in subrepository 'subrepo'
262 (use --subrepos for recursive commit)
262 (use --subrepos for recursive commit)
263 [255]
263 [255]
264
264
265 Add a normal file to the subrepo, then test archiving
265 Add a normal file to the subrepo, then test archiving
266
266
267 $ echo 'normal file' > subrepo/normal.txt
267 $ echo 'normal file' > subrepo/normal.txt
268 $ touch large.dat
268 $ touch large.dat
269 $ mv subrepo/large.txt subrepo/renamed-large.txt
269 $ mv subrepo/large.txt subrepo/renamed-large.txt
270 $ hg addremove -S --dry-run
270 $ hg addremove -S --dry-run
271 adding large.dat as a largefile
271 adding large.dat as a largefile
272 removing subrepo/large.txt
272 removing subrepo/large.txt
273 adding subrepo/normal.txt
273 adding subrepo/normal.txt
274 adding subrepo/renamed-large.txt
274 adding subrepo/renamed-large.txt
275 $ hg status -S
275 $ hg status -S
276 ! subrepo/large.txt
276 ! subrepo/large.txt
277 ? large.dat
277 ? large.dat
278 ? subrepo/normal.txt
278 ? subrepo/normal.txt
279 ? subrepo/renamed-large.txt
279 ? subrepo/renamed-large.txt
280
280
281 $ hg addremove --dry-run subrepo
281 $ hg addremove --dry-run subrepo
282 removing subrepo/large.txt (glob)
282 removing subrepo/large.txt (glob)
283 adding subrepo/normal.txt (glob)
283 adding subrepo/normal.txt (glob)
284 adding subrepo/renamed-large.txt (glob)
284 adding subrepo/renamed-large.txt (glob)
285 $ hg status -S
285 $ hg status -S
286 ! subrepo/large.txt
286 ! subrepo/large.txt
287 ? large.dat
287 ? large.dat
288 ? subrepo/normal.txt
288 ? subrepo/normal.txt
289 ? subrepo/renamed-large.txt
289 ? subrepo/renamed-large.txt
290 $ cd ..
290 $ cd ..
291
291
292 $ hg -R statusmatch addremove --dry-run statusmatch/subrepo
292 $ hg -R statusmatch addremove --dry-run statusmatch/subrepo
293 removing statusmatch/subrepo/large.txt (glob)
293 removing statusmatch/subrepo/large.txt (glob)
294 adding statusmatch/subrepo/normal.txt (glob)
294 adding statusmatch/subrepo/normal.txt (glob)
295 adding statusmatch/subrepo/renamed-large.txt (glob)
295 adding statusmatch/subrepo/renamed-large.txt (glob)
296 $ hg -R statusmatch status -S
296 $ hg -R statusmatch status -S
297 ! subrepo/large.txt
297 ! subrepo/large.txt
298 ? large.dat
298 ? large.dat
299 ? subrepo/normal.txt
299 ? subrepo/normal.txt
300 ? subrepo/renamed-large.txt
300 ? subrepo/renamed-large.txt
301
301
302 $ hg -R statusmatch addremove --dry-run -S
302 $ hg -R statusmatch addremove --dry-run -S
303 adding large.dat as a largefile
303 adding large.dat as a largefile
304 removing subrepo/large.txt
304 removing subrepo/large.txt
305 adding subrepo/normal.txt
305 adding subrepo/normal.txt
306 adding subrepo/renamed-large.txt
306 adding subrepo/renamed-large.txt
307 $ cd statusmatch
307 $ cd statusmatch
308
308
309 $ mv subrepo/renamed-large.txt subrepo/large.txt
309 $ mv subrepo/renamed-large.txt subrepo/large.txt
310 $ hg addremove subrepo
310 $ hg addremove subrepo
311 adding subrepo/normal.txt (glob)
311 adding subrepo/normal.txt (glob)
312 $ hg forget subrepo/normal.txt
312 $ hg forget subrepo/normal.txt
313
313
314 $ hg addremove -S
314 $ hg addremove -S
315 adding large.dat as a largefile
315 adding large.dat as a largefile
316 adding subrepo/normal.txt
316 adding subrepo/normal.txt
317 $ rm large.dat
317 $ rm large.dat
318
318
319 $ hg addremove subrepo
319 $ hg addremove subrepo
320 $ hg addremove -S
320 $ hg addremove -S
321 removing large.dat
321 removing large.dat
322
322
323 Lock in subrepo, otherwise the change isn't archived
323 Lock in subrepo, otherwise the change isn't archived
324
324
325 $ hg ci -S -m "add normal file to top level"
325 $ hg ci -S -m "add normal file to top level"
326 committing subrepository subrepo
326 committing subrepository subrepo
327 Invoking status precommit hook
327 Invoking status precommit hook
328 M large.txt
328 M large.txt
329 A normal.txt
329 A normal.txt
330 Invoking status precommit hook
330 Invoking status precommit hook
331 M .hgsubstate
331 M .hgsubstate
332 $ hg archive -S ../lf_subrepo_archive
332 $ hg archive -S ../lf_subrepo_archive
333 $ find ../lf_subrepo_archive | sort
333 $ find ../lf_subrepo_archive | sort
334 ../lf_subrepo_archive
334 ../lf_subrepo_archive
335 ../lf_subrepo_archive/.hg_archival.txt
335 ../lf_subrepo_archive/.hg_archival.txt
336 ../lf_subrepo_archive/.hgsub
336 ../lf_subrepo_archive/.hgsub
337 ../lf_subrepo_archive/.hgsubstate
337 ../lf_subrepo_archive/.hgsubstate
338 ../lf_subrepo_archive/a
338 ../lf_subrepo_archive/a
339 ../lf_subrepo_archive/a/b
339 ../lf_subrepo_archive/a/b
340 ../lf_subrepo_archive/a/b/c
340 ../lf_subrepo_archive/a/b/c
341 ../lf_subrepo_archive/a/b/c/d
341 ../lf_subrepo_archive/a/b/c/d
342 ../lf_subrepo_archive/a/b/c/d/e.large.txt
342 ../lf_subrepo_archive/a/b/c/d/e.large.txt
343 ../lf_subrepo_archive/a/b/c/d/e.normal.txt
343 ../lf_subrepo_archive/a/b/c/d/e.normal.txt
344 ../lf_subrepo_archive/a/b/c/x
344 ../lf_subrepo_archive/a/b/c/x
345 ../lf_subrepo_archive/a/b/c/x/y.normal.txt
345 ../lf_subrepo_archive/a/b/c/x/y.normal.txt
346 ../lf_subrepo_archive/subrepo
346 ../lf_subrepo_archive/subrepo
347 ../lf_subrepo_archive/subrepo/large.txt
347 ../lf_subrepo_archive/subrepo/large.txt
348 ../lf_subrepo_archive/subrepo/normal.txt
348 ../lf_subrepo_archive/subrepo/normal.txt
349 $ cat ../lf_subrepo_archive/.hg_archival.txt
349 $ cat ../lf_subrepo_archive/.hg_archival.txt
350 repo: 41bd42f10efa43698cc02052ea0977771cba506d
350 repo: 41bd42f10efa43698cc02052ea0977771cba506d
351 node: d56a95e6522858bc08a724c4fe2bdee066d1c30b
351 node: d56a95e6522858bc08a724c4fe2bdee066d1c30b
352 branch: default
352 branch: default
353 latesttag: null
353 latesttag: null
354 latesttagdistance: 4
354 latesttagdistance: 4
355 changessincelatesttag: 4
355 changessincelatesttag: 4
356
356
357 Test update with subrepos.
357 Test update with subrepos.
358
358
359 $ hg update 0
359 $ hg update 0
360 getting changed largefiles
360 getting changed largefiles
361 0 largefiles updated, 1 removed
361 0 largefiles updated, 1 removed
362 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
362 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
363 $ hg status -S
363 $ hg status -S
364 $ hg update tip
364 $ hg update tip
365 getting changed largefiles
365 getting changed largefiles
366 1 largefiles updated, 0 removed
366 1 largefiles updated, 0 removed
367 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
367 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
368 $ hg status -S
368 $ hg status -S
369 # modify a large file
369 # modify a large file
370 $ echo "modified" > subrepo/large.txt
370 $ echo "modified" > subrepo/large.txt
371 $ hg st -S
371 $ hg st -S
372 M subrepo/large.txt
372 M subrepo/large.txt
373 # update -C should revert the change.
373 # update -C should revert the change.
374 $ hg update -C
374 $ hg update -C
375 getting changed largefiles
375 getting changed largefiles
376 1 largefiles updated, 0 removed
376 1 largefiles updated, 0 removed
377 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
377 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
378 $ hg status -S
378 $ hg status -S
379
379
380 $ hg forget -v subrepo/large.txt
380 $ hg forget -v subrepo/large.txt
381 removing subrepo/large.txt (glob)
381 removing subrepo/large.txt (glob)
382
382
383 Test reverting a forgotten file
383 Test reverting a forgotten file
384 $ hg revert -R subrepo subrepo/large.txt
384 $ hg revert -R subrepo subrepo/large.txt
385 $ hg status -SA subrepo/large.txt
385 $ hg status -SA subrepo/large.txt
386 C subrepo/large.txt
386 C subrepo/large.txt
387
387
388 $ hg rm -v subrepo/large.txt
388 $ hg rm -v subrepo/large.txt
389 removing subrepo/large.txt (glob)
389 removing subrepo/large.txt (glob)
390 $ hg revert -R subrepo subrepo/large.txt
390 $ hg revert -R subrepo subrepo/large.txt
391 $ rm subrepo/large.txt
391 $ rm subrepo/large.txt
392 $ hg addremove -S
392 $ hg addremove -S
393 removing subrepo/large.txt
393 removing subrepo/large.txt
394 $ hg st -S
394 $ hg st -S
395 R subrepo/large.txt
395 R subrepo/large.txt
396
396
397 Test archiving a revision that references a subrepo that is not yet
397 Test archiving a revision that references a subrepo that is not yet
398 cloned (see test-subrepo-recursion.t):
398 cloned (see test-subrepo-recursion.t):
399
399
400 $ hg clone -U . ../empty
400 $ hg clone -U . ../empty
401 $ cd ../empty
401 $ cd ../empty
402 $ hg archive --subrepos -r tip ../archive.tar.gz
402 $ hg archive --subrepos -r tip ../archive.tar.gz
403 cloning subrepo subrepo from $TESTTMP/statusmatch/subrepo
403 cloning subrepo subrepo from $TESTTMP/statusmatch/subrepo
404 $ cd ..
404 $ cd ..
405
405
406
406
407
407
408
408
409
409
410
410
411 Test addremove, forget and others
411 Test addremove, forget and others
412 ==============================================
412 ==============================================
413
413
414 Test that addremove picks up largefiles prior to the initial commit (issue3541)
414 Test that addremove picks up largefiles prior to the initial commit (issue3541)
415
415
416 $ hg init addrm2
416 $ hg init addrm2
417 $ cd addrm2
417 $ cd addrm2
418 $ touch large.dat
418 $ touch large.dat
419 $ touch large2.dat
419 $ touch large2.dat
420 $ touch normal
420 $ touch normal
421 $ hg add --large large.dat
421 $ hg add --large large.dat
422 $ hg addremove -v
422 $ hg addremove -v
423 adding large2.dat as a largefile
423 adding large2.dat as a largefile
424 adding normal
424 adding normal
425
425
426 Test that forgetting all largefiles reverts to islfilesrepo() == False
426 Test that forgetting all largefiles reverts to islfilesrepo() == False
427 (addremove will add *.dat as normal files now)
427 (addremove will add *.dat as normal files now)
428 $ hg forget large.dat
428 $ hg forget large.dat
429 $ hg forget large2.dat
429 $ hg forget large2.dat
430 $ hg addremove -v
430 $ hg addremove -v
431 adding large.dat
431 adding large.dat
432 adding large2.dat
432 adding large2.dat
433
433
434 Test commit's addremove option prior to the first commit
434 Test commit's addremove option prior to the first commit
435 $ hg forget large.dat
435 $ hg forget large.dat
436 $ hg forget large2.dat
436 $ hg forget large2.dat
437 $ hg add --large large.dat
437 $ hg add --large large.dat
438 $ hg ci -Am "commit"
438 $ hg ci -Am "commit"
439 adding large2.dat as a largefile
439 adding large2.dat as a largefile
440 Invoking status precommit hook
440 Invoking status precommit hook
441 A large.dat
441 A large.dat
442 A large2.dat
442 A large2.dat
443 A normal
443 A normal
444 $ find .hglf | sort
444 $ find .hglf | sort
445 .hglf
445 .hglf
446 .hglf/large.dat
446 .hglf/large.dat
447 .hglf/large2.dat
447 .hglf/large2.dat
448
448
449 Test actions on largefiles using relative paths from subdir
449 Test actions on largefiles using relative paths from subdir
450
450
451 $ mkdir sub
451 $ mkdir sub
452 $ cd sub
452 $ cd sub
453 $ echo anotherlarge > anotherlarge
453 $ echo anotherlarge > anotherlarge
454 $ hg add --large anotherlarge
454 $ hg add --large anotherlarge
455 $ hg st
455 $ hg st
456 A sub/anotherlarge
456 A sub/anotherlarge
457 $ hg st anotherlarge
457 $ hg st anotherlarge
458 A anotherlarge
458 A anotherlarge
459 $ hg commit -m anotherlarge anotherlarge
459 $ hg commit -m anotherlarge anotherlarge
460 Invoking status precommit hook
460 Invoking status precommit hook
461 A sub/anotherlarge
461 A sub/anotherlarge
462 $ hg log anotherlarge
462 $ hg log anotherlarge
463 changeset: 1:9627a577c5e9
463 changeset: 1:9627a577c5e9
464 tag: tip
464 tag: tip
465 user: test
465 user: test
466 date: Thu Jan 01 00:00:00 1970 +0000
466 date: Thu Jan 01 00:00:00 1970 +0000
467 summary: anotherlarge
467 summary: anotherlarge
468
468
469 $ hg --debug log -T '{rev}: {desc}\n' ../sub/anotherlarge
469 $ hg --debug log -T '{rev}: {desc}\n' ../sub/anotherlarge
470 updated patterns: ['../.hglf/sub/../sub/anotherlarge', '../sub/anotherlarge']
470 updated patterns: ['../.hglf/sub/../sub/anotherlarge', '../sub/anotherlarge']
471 1: anotherlarge
471 1: anotherlarge
472
472
473 $ hg log -G anotherlarge
473 $ hg log -G anotherlarge
474 @ changeset: 1:9627a577c5e9
474 @ changeset: 1:9627a577c5e9
475 | tag: tip
475 | tag: tip
476 | user: test
476 | user: test
477 | date: Thu Jan 01 00:00:00 1970 +0000
477 | date: Thu Jan 01 00:00:00 1970 +0000
478 | summary: anotherlarge
478 | summary: anotherlarge
479 |
479 |
480
480
481 $ hg log glob:another*
481 $ hg log glob:another*
482 changeset: 1:9627a577c5e9
482 changeset: 1:9627a577c5e9
483 tag: tip
483 tag: tip
484 user: test
484 user: test
485 date: Thu Jan 01 00:00:00 1970 +0000
485 date: Thu Jan 01 00:00:00 1970 +0000
486 summary: anotherlarge
486 summary: anotherlarge
487
487
488 $ hg --debug log -T '{rev}: {desc}\n' -G glob:another*
488 $ hg --debug log -T '{rev}: {desc}\n' -G glob:another*
489 updated patterns: ['glob:../.hglf/sub/another*', 'glob:another*']
489 updated patterns: ['glob:../.hglf/sub/another*', 'glob:another*']
490 @ 1: anotherlarge
490 @ 1: anotherlarge
491 |
491 |
492
492
493 #if no-msys
493 #if no-msys
494 $ hg --debug log -T '{rev}: {desc}\n' 'glob:../.hglf/sub/another*' # no-msys
494 $ hg --debug log -T '{rev}: {desc}\n' 'glob:../.hglf/sub/another*' # no-msys
495 updated patterns: ['glob:../.hglf/sub/another*']
495 updated patterns: ['glob:../.hglf/sub/another*']
496 1: anotherlarge
496 1: anotherlarge
497
497
498 $ hg --debug log -G -T '{rev}: {desc}\n' 'glob:../.hglf/sub/another*' # no-msys
498 $ hg --debug log -G -T '{rev}: {desc}\n' 'glob:../.hglf/sub/another*' # no-msys
499 updated patterns: ['glob:../.hglf/sub/another*']
499 updated patterns: ['glob:../.hglf/sub/another*']
500 @ 1: anotherlarge
500 @ 1: anotherlarge
501 |
501 |
502 #endif
502 #endif
503
503
504 $ echo more >> anotherlarge
504 $ echo more >> anotherlarge
505 $ hg st .
505 $ hg st .
506 M anotherlarge
506 M anotherlarge
507 $ hg cat anotherlarge
507 $ hg cat anotherlarge
508 anotherlarge
508 anotherlarge
509 $ hg revert anotherlarge
509 $ hg revert anotherlarge
510 $ hg st
510 $ hg st
511 ? sub/anotherlarge.orig
511 ? sub/anotherlarge.orig
512
513 Test orig files go where we want them
514 $ echo moremore >> anotherlarge
515 $ hg revert anotherlarge -v --config 'ui.origbackuppath=.hg/origbackups'
516 creating directory: $TESTTMP/addrm2/.hg/origbackups/.hglf/sub
517 saving current version of ../.hglf/sub/anotherlarge as $TESTTMP/addrm2/.hg/origbackups/.hglf/sub/anotherlarge.orig
518 reverting ../.hglf/sub/anotherlarge (glob)
519 creating directory: $TESTTMP/addrm2/.hg/origbackups/sub
520 found 90c622cf65cebe75c5842f9136c459333faf392e in store
521 found 90c622cf65cebe75c5842f9136c459333faf392e in store
522 $ ls ../.hg/origbackups/sub
523 anotherlarge.orig
512 $ cd ..
524 $ cd ..
513
525
514 Test glob logging from the root dir
526 Test glob logging from the root dir
515 $ hg log glob:**another*
527 $ hg log glob:**another*
516 changeset: 1:9627a577c5e9
528 changeset: 1:9627a577c5e9
517 tag: tip
529 tag: tip
518 user: test
530 user: test
519 date: Thu Jan 01 00:00:00 1970 +0000
531 date: Thu Jan 01 00:00:00 1970 +0000
520 summary: anotherlarge
532 summary: anotherlarge
521
533
522 $ hg log -G glob:**another*
534 $ hg log -G glob:**another*
523 @ changeset: 1:9627a577c5e9
535 @ changeset: 1:9627a577c5e9
524 | tag: tip
536 | tag: tip
525 | user: test
537 | user: test
526 | date: Thu Jan 01 00:00:00 1970 +0000
538 | date: Thu Jan 01 00:00:00 1970 +0000
527 | summary: anotherlarge
539 | summary: anotherlarge
528 |
540 |
529
541
530 $ cd ..
542 $ cd ..
531
543
532 Log from outer space
544 Log from outer space
533 $ hg --debug log -R addrm2 -T '{rev}: {desc}\n' 'addrm2/sub/anotherlarge'
545 $ hg --debug log -R addrm2 -T '{rev}: {desc}\n' 'addrm2/sub/anotherlarge'
534 updated patterns: ['addrm2/.hglf/sub/anotherlarge', 'addrm2/sub/anotherlarge']
546 updated patterns: ['addrm2/.hglf/sub/anotherlarge', 'addrm2/sub/anotherlarge']
535 1: anotherlarge
547 1: anotherlarge
536 $ hg --debug log -R addrm2 -T '{rev}: {desc}\n' 'addrm2/.hglf/sub/anotherlarge'
548 $ hg --debug log -R addrm2 -T '{rev}: {desc}\n' 'addrm2/.hglf/sub/anotherlarge'
537 updated patterns: ['addrm2/.hglf/sub/anotherlarge']
549 updated patterns: ['addrm2/.hglf/sub/anotherlarge']
538 1: anotherlarge
550 1: anotherlarge
539
551
540
552
541 Check error message while exchange
553 Check error message while exchange
542 =========================================================
554 =========================================================
543
555
544 issue3651: summary/outgoing with largefiles shows "no remote repo"
556 issue3651: summary/outgoing with largefiles shows "no remote repo"
545 unexpectedly
557 unexpectedly
546
558
547 $ mkdir issue3651
559 $ mkdir issue3651
548 $ cd issue3651
560 $ cd issue3651
549
561
550 $ hg init src
562 $ hg init src
551 $ echo a > src/a
563 $ echo a > src/a
552 $ hg -R src add --large src/a
564 $ hg -R src add --large src/a
553 $ hg -R src commit -m '#0'
565 $ hg -R src commit -m '#0'
554 Invoking status precommit hook
566 Invoking status precommit hook
555 A a
567 A a
556
568
557 check messages when no remote repository is specified:
569 check messages when no remote repository is specified:
558 "no remote repo" route for "hg outgoing --large" is not tested here,
570 "no remote repo" route for "hg outgoing --large" is not tested here,
559 because it can't be reproduced easily.
571 because it can't be reproduced easily.
560
572
561 $ hg init clone1
573 $ hg init clone1
562 $ hg -R clone1 -q pull src
574 $ hg -R clone1 -q pull src
563 $ hg -R clone1 -q update
575 $ hg -R clone1 -q update
564 $ hg -R clone1 paths | grep default
576 $ hg -R clone1 paths | grep default
565 [1]
577 [1]
566
578
567 $ hg -R clone1 summary --large
579 $ hg -R clone1 summary --large
568 parent: 0:fc0bd45326d3 tip
580 parent: 0:fc0bd45326d3 tip
569 #0
581 #0
570 branch: default
582 branch: default
571 commit: (clean)
583 commit: (clean)
572 update: (current)
584 update: (current)
573 phases: 1 draft
585 phases: 1 draft
574 largefiles: (no remote repo)
586 largefiles: (no remote repo)
575
587
576 check messages when there is no files to upload:
588 check messages when there is no files to upload:
577
589
578 $ hg -q clone src clone2
590 $ hg -q clone src clone2
579 $ hg -R clone2 paths | grep default
591 $ hg -R clone2 paths | grep default
580 default = $TESTTMP/issue3651/src (glob)
592 default = $TESTTMP/issue3651/src (glob)
581
593
582 $ hg -R clone2 summary --large
594 $ hg -R clone2 summary --large
583 parent: 0:fc0bd45326d3 tip
595 parent: 0:fc0bd45326d3 tip
584 #0
596 #0
585 branch: default
597 branch: default
586 commit: (clean)
598 commit: (clean)
587 update: (current)
599 update: (current)
588 phases: 1 draft
600 phases: 1 draft
589 largefiles: (no files to upload)
601 largefiles: (no files to upload)
590 $ hg -R clone2 outgoing --large
602 $ hg -R clone2 outgoing --large
591 comparing with $TESTTMP/issue3651/src (glob)
603 comparing with $TESTTMP/issue3651/src (glob)
592 searching for changes
604 searching for changes
593 no changes found
605 no changes found
594 largefiles: no files to upload
606 largefiles: no files to upload
595 [1]
607 [1]
596
608
597 $ hg -R clone2 outgoing --large --graph --template "{rev}"
609 $ hg -R clone2 outgoing --large --graph --template "{rev}"
598 comparing with $TESTTMP/issue3651/src (glob)
610 comparing with $TESTTMP/issue3651/src (glob)
599 searching for changes
611 searching for changes
600 no changes found
612 no changes found
601 largefiles: no files to upload
613 largefiles: no files to upload
602
614
603 check messages when there are files to upload:
615 check messages when there are files to upload:
604
616
605 $ echo b > clone2/b
617 $ echo b > clone2/b
606 $ hg -R clone2 add --large clone2/b
618 $ hg -R clone2 add --large clone2/b
607 $ hg -R clone2 commit -m '#1'
619 $ hg -R clone2 commit -m '#1'
608 Invoking status precommit hook
620 Invoking status precommit hook
609 A b
621 A b
610 $ hg -R clone2 summary --large
622 $ hg -R clone2 summary --large
611 parent: 1:1acbe71ce432 tip
623 parent: 1:1acbe71ce432 tip
612 #1
624 #1
613 branch: default
625 branch: default
614 commit: (clean)
626 commit: (clean)
615 update: (current)
627 update: (current)
616 phases: 2 draft
628 phases: 2 draft
617 largefiles: 1 entities for 1 files to upload
629 largefiles: 1 entities for 1 files to upload
618 $ hg -R clone2 outgoing --large
630 $ hg -R clone2 outgoing --large
619 comparing with $TESTTMP/issue3651/src (glob)
631 comparing with $TESTTMP/issue3651/src (glob)
620 searching for changes
632 searching for changes
621 changeset: 1:1acbe71ce432
633 changeset: 1:1acbe71ce432
622 tag: tip
634 tag: tip
623 user: test
635 user: test
624 date: Thu Jan 01 00:00:00 1970 +0000
636 date: Thu Jan 01 00:00:00 1970 +0000
625 summary: #1
637 summary: #1
626
638
627 largefiles to upload (1 entities):
639 largefiles to upload (1 entities):
628 b
640 b
629
641
630 $ hg -R clone2 outgoing --large --graph --template "{rev}"
642 $ hg -R clone2 outgoing --large --graph --template "{rev}"
631 comparing with $TESTTMP/issue3651/src (glob)
643 comparing with $TESTTMP/issue3651/src (glob)
632 searching for changes
644 searching for changes
633 @ 1
645 @ 1
634
646
635 largefiles to upload (1 entities):
647 largefiles to upload (1 entities):
636 b
648 b
637
649
638
650
639 $ cp clone2/b clone2/b1
651 $ cp clone2/b clone2/b1
640 $ cp clone2/b clone2/b2
652 $ cp clone2/b clone2/b2
641 $ hg -R clone2 add --large clone2/b1 clone2/b2
653 $ hg -R clone2 add --large clone2/b1 clone2/b2
642 $ hg -R clone2 commit -m '#2: add largefiles referring same entity'
654 $ hg -R clone2 commit -m '#2: add largefiles referring same entity'
643 Invoking status precommit hook
655 Invoking status precommit hook
644 A b1
656 A b1
645 A b2
657 A b2
646 $ hg -R clone2 summary --large
658 $ hg -R clone2 summary --large
647 parent: 2:6095d0695d70 tip
659 parent: 2:6095d0695d70 tip
648 #2: add largefiles referring same entity
660 #2: add largefiles referring same entity
649 branch: default
661 branch: default
650 commit: (clean)
662 commit: (clean)
651 update: (current)
663 update: (current)
652 phases: 3 draft
664 phases: 3 draft
653 largefiles: 1 entities for 3 files to upload
665 largefiles: 1 entities for 3 files to upload
654 $ hg -R clone2 outgoing --large -T "{rev}:{node|short}\n"
666 $ hg -R clone2 outgoing --large -T "{rev}:{node|short}\n"
655 comparing with $TESTTMP/issue3651/src (glob)
667 comparing with $TESTTMP/issue3651/src (glob)
656 searching for changes
668 searching for changes
657 1:1acbe71ce432
669 1:1acbe71ce432
658 2:6095d0695d70
670 2:6095d0695d70
659 largefiles to upload (1 entities):
671 largefiles to upload (1 entities):
660 b
672 b
661 b1
673 b1
662 b2
674 b2
663
675
664 $ hg -R clone2 cat -r 1 clone2/.hglf/b
676 $ hg -R clone2 cat -r 1 clone2/.hglf/b
665 89e6c98d92887913cadf06b2adb97f26cde4849b
677 89e6c98d92887913cadf06b2adb97f26cde4849b
666 $ hg -R clone2 outgoing --large -T "{rev}:{node|short}\n" --debug --config progress.debug=true
678 $ hg -R clone2 outgoing --large -T "{rev}:{node|short}\n" --debug --config progress.debug=true
667 comparing with $TESTTMP/issue3651/src (glob)
679 comparing with $TESTTMP/issue3651/src (glob)
668 query 1; heads
680 query 1; heads
669 searching for changes
681 searching for changes
670 all remote heads known locally
682 all remote heads known locally
671 1:1acbe71ce432
683 1:1acbe71ce432
672 2:6095d0695d70
684 2:6095d0695d70
673 finding outgoing largefiles: 0/2 revision (0.00%)
685 finding outgoing largefiles: 0/2 revision (0.00%)
674 finding outgoing largefiles: 1/2 revision (50.00%)
686 finding outgoing largefiles: 1/2 revision (50.00%)
675 largefiles to upload (1 entities):
687 largefiles to upload (1 entities):
676 b
688 b
677 89e6c98d92887913cadf06b2adb97f26cde4849b
689 89e6c98d92887913cadf06b2adb97f26cde4849b
678 b1
690 b1
679 89e6c98d92887913cadf06b2adb97f26cde4849b
691 89e6c98d92887913cadf06b2adb97f26cde4849b
680 b2
692 b2
681 89e6c98d92887913cadf06b2adb97f26cde4849b
693 89e6c98d92887913cadf06b2adb97f26cde4849b
682
694
683
695
684 $ echo bbb > clone2/b
696 $ echo bbb > clone2/b
685 $ hg -R clone2 commit -m '#3: add new largefile entity as existing file'
697 $ hg -R clone2 commit -m '#3: add new largefile entity as existing file'
686 Invoking status precommit hook
698 Invoking status precommit hook
687 M b
699 M b
688 $ echo bbbb > clone2/b
700 $ echo bbbb > clone2/b
689 $ hg -R clone2 commit -m '#4: add new largefile entity as existing file'
701 $ hg -R clone2 commit -m '#4: add new largefile entity as existing file'
690 Invoking status precommit hook
702 Invoking status precommit hook
691 M b
703 M b
692 $ cp clone2/b1 clone2/b
704 $ cp clone2/b1 clone2/b
693 $ hg -R clone2 commit -m '#5: refer existing largefile entity again'
705 $ hg -R clone2 commit -m '#5: refer existing largefile entity again'
694 Invoking status precommit hook
706 Invoking status precommit hook
695 M b
707 M b
696 $ hg -R clone2 summary --large
708 $ hg -R clone2 summary --large
697 parent: 5:036794ea641c tip
709 parent: 5:036794ea641c tip
698 #5: refer existing largefile entity again
710 #5: refer existing largefile entity again
699 branch: default
711 branch: default
700 commit: (clean)
712 commit: (clean)
701 update: (current)
713 update: (current)
702 phases: 6 draft
714 phases: 6 draft
703 largefiles: 3 entities for 3 files to upload
715 largefiles: 3 entities for 3 files to upload
704 $ hg -R clone2 outgoing --large -T "{rev}:{node|short}\n"
716 $ hg -R clone2 outgoing --large -T "{rev}:{node|short}\n"
705 comparing with $TESTTMP/issue3651/src (glob)
717 comparing with $TESTTMP/issue3651/src (glob)
706 searching for changes
718 searching for changes
707 1:1acbe71ce432
719 1:1acbe71ce432
708 2:6095d0695d70
720 2:6095d0695d70
709 3:7983dce246cc
721 3:7983dce246cc
710 4:233f12ada4ae
722 4:233f12ada4ae
711 5:036794ea641c
723 5:036794ea641c
712 largefiles to upload (3 entities):
724 largefiles to upload (3 entities):
713 b
725 b
714 b1
726 b1
715 b2
727 b2
716
728
717 $ hg -R clone2 cat -r 3 clone2/.hglf/b
729 $ hg -R clone2 cat -r 3 clone2/.hglf/b
718 c801c9cfe94400963fcb683246217d5db77f9a9a
730 c801c9cfe94400963fcb683246217d5db77f9a9a
719 $ hg -R clone2 cat -r 4 clone2/.hglf/b
731 $ hg -R clone2 cat -r 4 clone2/.hglf/b
720 13f9ed0898e315bf59dc2973fec52037b6f441a2
732 13f9ed0898e315bf59dc2973fec52037b6f441a2
721 $ hg -R clone2 outgoing --large -T "{rev}:{node|short}\n" --debug --config progress.debug=true
733 $ hg -R clone2 outgoing --large -T "{rev}:{node|short}\n" --debug --config progress.debug=true
722 comparing with $TESTTMP/issue3651/src (glob)
734 comparing with $TESTTMP/issue3651/src (glob)
723 query 1; heads
735 query 1; heads
724 searching for changes
736 searching for changes
725 all remote heads known locally
737 all remote heads known locally
726 1:1acbe71ce432
738 1:1acbe71ce432
727 2:6095d0695d70
739 2:6095d0695d70
728 3:7983dce246cc
740 3:7983dce246cc
729 4:233f12ada4ae
741 4:233f12ada4ae
730 5:036794ea641c
742 5:036794ea641c
731 finding outgoing largefiles: 0/5 revision (0.00%)
743 finding outgoing largefiles: 0/5 revision (0.00%)
732 finding outgoing largefiles: 1/5 revision (20.00%)
744 finding outgoing largefiles: 1/5 revision (20.00%)
733 finding outgoing largefiles: 2/5 revision (40.00%)
745 finding outgoing largefiles: 2/5 revision (40.00%)
734 finding outgoing largefiles: 3/5 revision (60.00%)
746 finding outgoing largefiles: 3/5 revision (60.00%)
735 finding outgoing largefiles: 4/5 revision (80.00%)
747 finding outgoing largefiles: 4/5 revision (80.00%)
736 largefiles to upload (3 entities):
748 largefiles to upload (3 entities):
737 b
749 b
738 13f9ed0898e315bf59dc2973fec52037b6f441a2
750 13f9ed0898e315bf59dc2973fec52037b6f441a2
739 89e6c98d92887913cadf06b2adb97f26cde4849b
751 89e6c98d92887913cadf06b2adb97f26cde4849b
740 c801c9cfe94400963fcb683246217d5db77f9a9a
752 c801c9cfe94400963fcb683246217d5db77f9a9a
741 b1
753 b1
742 89e6c98d92887913cadf06b2adb97f26cde4849b
754 89e6c98d92887913cadf06b2adb97f26cde4849b
743 b2
755 b2
744 89e6c98d92887913cadf06b2adb97f26cde4849b
756 89e6c98d92887913cadf06b2adb97f26cde4849b
745
757
746
758
747 Pushing revision #1 causes uploading entity 89e6c98d9288, which is
759 Pushing revision #1 causes uploading entity 89e6c98d9288, which is
748 shared also by largefiles b1, b2 in revision #2 and b in revision #5.
760 shared also by largefiles b1, b2 in revision #2 and b in revision #5.
749
761
750 Then, entity 89e6c98d9288 is not treated as "outgoing entity" at "hg
762 Then, entity 89e6c98d9288 is not treated as "outgoing entity" at "hg
751 summary" and "hg outgoing", even though files in outgoing revision #2
763 summary" and "hg outgoing", even though files in outgoing revision #2
752 and #5 refer it.
764 and #5 refer it.
753
765
754 $ hg -R clone2 push -r 1 -q
766 $ hg -R clone2 push -r 1 -q
755 $ hg -R clone2 summary --large
767 $ hg -R clone2 summary --large
756 parent: 5:036794ea641c tip
768 parent: 5:036794ea641c tip
757 #5: refer existing largefile entity again
769 #5: refer existing largefile entity again
758 branch: default
770 branch: default
759 commit: (clean)
771 commit: (clean)
760 update: (current)
772 update: (current)
761 phases: 6 draft
773 phases: 6 draft
762 largefiles: 2 entities for 1 files to upload
774 largefiles: 2 entities for 1 files to upload
763 $ hg -R clone2 outgoing --large -T "{rev}:{node|short}\n"
775 $ hg -R clone2 outgoing --large -T "{rev}:{node|short}\n"
764 comparing with $TESTTMP/issue3651/src (glob)
776 comparing with $TESTTMP/issue3651/src (glob)
765 searching for changes
777 searching for changes
766 2:6095d0695d70
778 2:6095d0695d70
767 3:7983dce246cc
779 3:7983dce246cc
768 4:233f12ada4ae
780 4:233f12ada4ae
769 5:036794ea641c
781 5:036794ea641c
770 largefiles to upload (2 entities):
782 largefiles to upload (2 entities):
771 b
783 b
772
784
773 $ hg -R clone2 outgoing --large -T "{rev}:{node|short}\n" --debug --config progress.debug=true
785 $ hg -R clone2 outgoing --large -T "{rev}:{node|short}\n" --debug --config progress.debug=true
774 comparing with $TESTTMP/issue3651/src (glob)
786 comparing with $TESTTMP/issue3651/src (glob)
775 query 1; heads
787 query 1; heads
776 searching for changes
788 searching for changes
777 all remote heads known locally
789 all remote heads known locally
778 2:6095d0695d70
790 2:6095d0695d70
779 3:7983dce246cc
791 3:7983dce246cc
780 4:233f12ada4ae
792 4:233f12ada4ae
781 5:036794ea641c
793 5:036794ea641c
782 finding outgoing largefiles: 0/4 revision (0.00%)
794 finding outgoing largefiles: 0/4 revision (0.00%)
783 finding outgoing largefiles: 1/4 revision (25.00%)
795 finding outgoing largefiles: 1/4 revision (25.00%)
784 finding outgoing largefiles: 2/4 revision (50.00%)
796 finding outgoing largefiles: 2/4 revision (50.00%)
785 finding outgoing largefiles: 3/4 revision (75.00%)
797 finding outgoing largefiles: 3/4 revision (75.00%)
786 largefiles to upload (2 entities):
798 largefiles to upload (2 entities):
787 b
799 b
788 13f9ed0898e315bf59dc2973fec52037b6f441a2
800 13f9ed0898e315bf59dc2973fec52037b6f441a2
789 c801c9cfe94400963fcb683246217d5db77f9a9a
801 c801c9cfe94400963fcb683246217d5db77f9a9a
790
802
791
803
792 $ cd ..
804 $ cd ..
793
805
794 merge action 'd' for 'local renamed directory to d2/g' which has no filename
806 merge action 'd' for 'local renamed directory to d2/g' which has no filename
795 ==================================================================================
807 ==================================================================================
796
808
797 $ hg init merge-action
809 $ hg init merge-action
798 $ cd merge-action
810 $ cd merge-action
799 $ touch l
811 $ touch l
800 $ hg add --large l
812 $ hg add --large l
801 $ mkdir d1
813 $ mkdir d1
802 $ touch d1/f
814 $ touch d1/f
803 $ hg ci -Aqm0
815 $ hg ci -Aqm0
804 Invoking status precommit hook
816 Invoking status precommit hook
805 A d1/f
817 A d1/f
806 A l
818 A l
807 $ echo > d1/f
819 $ echo > d1/f
808 $ touch d1/g
820 $ touch d1/g
809 $ hg ci -Aqm1
821 $ hg ci -Aqm1
810 Invoking status precommit hook
822 Invoking status precommit hook
811 M d1/f
823 M d1/f
812 A d1/g
824 A d1/g
813 $ hg up -qr0
825 $ hg up -qr0
814 $ hg mv d1 d2
826 $ hg mv d1 d2
815 moving d1/f to d2/f (glob)
827 moving d1/f to d2/f (glob)
816 $ hg ci -qm2
828 $ hg ci -qm2
817 Invoking status precommit hook
829 Invoking status precommit hook
818 A d2/f
830 A d2/f
819 R d1/f
831 R d1/f
820 $ hg merge
832 $ hg merge
821 merging d2/f and d1/f to d2/f
833 merging d2/f and d1/f to d2/f
822 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
834 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
823 (branch merge, don't forget to commit)
835 (branch merge, don't forget to commit)
824 $ cd ..
836 $ cd ..
825
837
826
838
827 Merge conflicts:
839 Merge conflicts:
828 =====================
840 =====================
829
841
830 $ hg init merge
842 $ hg init merge
831 $ cd merge
843 $ cd merge
832 $ echo 0 > f-different
844 $ echo 0 > f-different
833 $ echo 0 > f-same
845 $ echo 0 > f-same
834 $ echo 0 > f-unchanged-1
846 $ echo 0 > f-unchanged-1
835 $ echo 0 > f-unchanged-2
847 $ echo 0 > f-unchanged-2
836 $ hg add --large *
848 $ hg add --large *
837 $ hg ci -m0
849 $ hg ci -m0
838 Invoking status precommit hook
850 Invoking status precommit hook
839 A f-different
851 A f-different
840 A f-same
852 A f-same
841 A f-unchanged-1
853 A f-unchanged-1
842 A f-unchanged-2
854 A f-unchanged-2
843 $ echo tmp1 > f-unchanged-1
855 $ echo tmp1 > f-unchanged-1
844 $ echo tmp1 > f-unchanged-2
856 $ echo tmp1 > f-unchanged-2
845 $ echo tmp1 > f-same
857 $ echo tmp1 > f-same
846 $ hg ci -m1
858 $ hg ci -m1
847 Invoking status precommit hook
859 Invoking status precommit hook
848 M f-same
860 M f-same
849 M f-unchanged-1
861 M f-unchanged-1
850 M f-unchanged-2
862 M f-unchanged-2
851 $ echo 2 > f-different
863 $ echo 2 > f-different
852 $ echo 0 > f-unchanged-1
864 $ echo 0 > f-unchanged-1
853 $ echo 1 > f-unchanged-2
865 $ echo 1 > f-unchanged-2
854 $ echo 1 > f-same
866 $ echo 1 > f-same
855 $ hg ci -m2
867 $ hg ci -m2
856 Invoking status precommit hook
868 Invoking status precommit hook
857 M f-different
869 M f-different
858 M f-same
870 M f-same
859 M f-unchanged-1
871 M f-unchanged-1
860 M f-unchanged-2
872 M f-unchanged-2
861 $ hg up -qr0
873 $ hg up -qr0
862 $ echo tmp2 > f-unchanged-1
874 $ echo tmp2 > f-unchanged-1
863 $ echo tmp2 > f-unchanged-2
875 $ echo tmp2 > f-unchanged-2
864 $ echo tmp2 > f-same
876 $ echo tmp2 > f-same
865 $ hg ci -m3
877 $ hg ci -m3
866 Invoking status precommit hook
878 Invoking status precommit hook
867 M f-same
879 M f-same
868 M f-unchanged-1
880 M f-unchanged-1
869 M f-unchanged-2
881 M f-unchanged-2
870 created new head
882 created new head
871 $ echo 1 > f-different
883 $ echo 1 > f-different
872 $ echo 1 > f-unchanged-1
884 $ echo 1 > f-unchanged-1
873 $ echo 0 > f-unchanged-2
885 $ echo 0 > f-unchanged-2
874 $ echo 1 > f-same
886 $ echo 1 > f-same
875 $ hg ci -m4
887 $ hg ci -m4
876 Invoking status precommit hook
888 Invoking status precommit hook
877 M f-different
889 M f-different
878 M f-same
890 M f-same
879 M f-unchanged-1
891 M f-unchanged-1
880 M f-unchanged-2
892 M f-unchanged-2
881 $ hg merge
893 $ hg merge
882 largefile f-different has a merge conflict
894 largefile f-different has a merge conflict
883 ancestor was 09d2af8dd22201dd8d48e5dcfcaed281ff9422c7
895 ancestor was 09d2af8dd22201dd8d48e5dcfcaed281ff9422c7
884 keep (l)ocal e5fa44f2b31c1fb553b6021e7360d07d5d91ff5e or
896 keep (l)ocal e5fa44f2b31c1fb553b6021e7360d07d5d91ff5e or
885 take (o)ther 7448d8798a4380162d4b56f9b452e2f6f9e24e7a? l
897 take (o)ther 7448d8798a4380162d4b56f9b452e2f6f9e24e7a? l
886 getting changed largefiles
898 getting changed largefiles
887 1 largefiles updated, 0 removed
899 1 largefiles updated, 0 removed
888 0 files updated, 4 files merged, 0 files removed, 0 files unresolved
900 0 files updated, 4 files merged, 0 files removed, 0 files unresolved
889 (branch merge, don't forget to commit)
901 (branch merge, don't forget to commit)
890 $ cat f-different
902 $ cat f-different
891 1
903 1
892 $ cat f-same
904 $ cat f-same
893 1
905 1
894 $ cat f-unchanged-1
906 $ cat f-unchanged-1
895 1
907 1
896 $ cat f-unchanged-2
908 $ cat f-unchanged-2
897 1
909 1
898 $ cd ..
910 $ cd ..
899
911
900 Test largefile insulation (do not enabled a side effect
912 Test largefile insulation (do not enabled a side effect
901 ========================================================
913 ========================================================
902
914
903 Check whether "largefiles" feature is supported only in repositories
915 Check whether "largefiles" feature is supported only in repositories
904 enabling largefiles extension.
916 enabling largefiles extension.
905
917
906 $ mkdir individualenabling
918 $ mkdir individualenabling
907 $ cd individualenabling
919 $ cd individualenabling
908
920
909 $ hg init enabledlocally
921 $ hg init enabledlocally
910 $ echo large > enabledlocally/large
922 $ echo large > enabledlocally/large
911 $ hg -R enabledlocally add --large enabledlocally/large
923 $ hg -R enabledlocally add --large enabledlocally/large
912 $ hg -R enabledlocally commit -m '#0'
924 $ hg -R enabledlocally commit -m '#0'
913 Invoking status precommit hook
925 Invoking status precommit hook
914 A large
926 A large
915
927
916 $ hg init notenabledlocally
928 $ hg init notenabledlocally
917 $ echo large > notenabledlocally/large
929 $ echo large > notenabledlocally/large
918 $ hg -R notenabledlocally add --large notenabledlocally/large
930 $ hg -R notenabledlocally add --large notenabledlocally/large
919 $ hg -R notenabledlocally commit -m '#0'
931 $ hg -R notenabledlocally commit -m '#0'
920 Invoking status precommit hook
932 Invoking status precommit hook
921 A large
933 A large
922
934
923 $ cat >> $HGRCPATH <<EOF
935 $ cat >> $HGRCPATH <<EOF
924 > [extensions]
936 > [extensions]
925 > # disable globally
937 > # disable globally
926 > largefiles=!
938 > largefiles=!
927 > EOF
939 > EOF
928 $ cat >> enabledlocally/.hg/hgrc <<EOF
940 $ cat >> enabledlocally/.hg/hgrc <<EOF
929 > [extensions]
941 > [extensions]
930 > # enable locally
942 > # enable locally
931 > largefiles=
943 > largefiles=
932 > EOF
944 > EOF
933 $ hg -R enabledlocally root
945 $ hg -R enabledlocally root
934 $TESTTMP/individualenabling/enabledlocally (glob)
946 $TESTTMP/individualenabling/enabledlocally (glob)
935 $ hg -R notenabledlocally root
947 $ hg -R notenabledlocally root
936 abort: repository requires features unknown to this Mercurial: largefiles!
948 abort: repository requires features unknown to this Mercurial: largefiles!
937 (see https://mercurial-scm.org/wiki/MissingRequirement for more information)
949 (see https://mercurial-scm.org/wiki/MissingRequirement for more information)
938 [255]
950 [255]
939
951
940 $ hg init push-dst
952 $ hg init push-dst
941 $ hg -R enabledlocally push push-dst
953 $ hg -R enabledlocally push push-dst
942 pushing to push-dst
954 pushing to push-dst
943 abort: required features are not supported in the destination: largefiles
955 abort: required features are not supported in the destination: largefiles
944 [255]
956 [255]
945
957
946 $ hg init pull-src
958 $ hg init pull-src
947 $ hg -R pull-src pull enabledlocally
959 $ hg -R pull-src pull enabledlocally
948 pulling from enabledlocally
960 pulling from enabledlocally
949 abort: required features are not supported in the destination: largefiles
961 abort: required features are not supported in the destination: largefiles
950 [255]
962 [255]
951
963
952 $ hg clone enabledlocally clone-dst
964 $ hg clone enabledlocally clone-dst
953 abort: repository requires features unknown to this Mercurial: largefiles!
965 abort: repository requires features unknown to this Mercurial: largefiles!
954 (see https://mercurial-scm.org/wiki/MissingRequirement for more information)
966 (see https://mercurial-scm.org/wiki/MissingRequirement for more information)
955 [255]
967 [255]
956 $ test -d clone-dst
968 $ test -d clone-dst
957 [1]
969 [1]
958 $ hg clone --pull enabledlocally clone-pull-dst
970 $ hg clone --pull enabledlocally clone-pull-dst
959 abort: required features are not supported in the destination: largefiles
971 abort: required features are not supported in the destination: largefiles
960 [255]
972 [255]
961 $ test -d clone-pull-dst
973 $ test -d clone-pull-dst
962 [1]
974 [1]
963
975
964 #if serve
976 #if serve
965
977
966 Test largefiles specific peer setup, when largefiles is enabled
978 Test largefiles specific peer setup, when largefiles is enabled
967 locally (issue4109)
979 locally (issue4109)
968
980
969 $ hg showconfig extensions | grep largefiles
981 $ hg showconfig extensions | grep largefiles
970 extensions.largefiles=!
982 extensions.largefiles=!
971 $ mkdir -p $TESTTMP/individualenabling/usercache
983 $ mkdir -p $TESTTMP/individualenabling/usercache
972
984
973 $ hg serve -R enabledlocally -d -p $HGPORT --pid-file hg.pid
985 $ hg serve -R enabledlocally -d -p $HGPORT --pid-file hg.pid
974 $ cat hg.pid >> $DAEMON_PIDS
986 $ cat hg.pid >> $DAEMON_PIDS
975
987
976 $ hg init pull-dst
988 $ hg init pull-dst
977 $ cat > pull-dst/.hg/hgrc <<EOF
989 $ cat > pull-dst/.hg/hgrc <<EOF
978 > [extensions]
990 > [extensions]
979 > # enable locally
991 > # enable locally
980 > largefiles=
992 > largefiles=
981 > [largefiles]
993 > [largefiles]
982 > # ignore system cache to force largefiles specific wire proto access
994 > # ignore system cache to force largefiles specific wire proto access
983 > usercache=$TESTTMP/individualenabling/usercache
995 > usercache=$TESTTMP/individualenabling/usercache
984 > EOF
996 > EOF
985 $ hg -R pull-dst -q pull -u http://localhost:$HGPORT
997 $ hg -R pull-dst -q pull -u http://localhost:$HGPORT
986
998
987 $ killdaemons.py
999 $ killdaemons.py
988 #endif
1000 #endif
989
1001
990 Test overridden functions work correctly even for repos disabling
1002 Test overridden functions work correctly even for repos disabling
991 largefiles (issue4547)
1003 largefiles (issue4547)
992
1004
993 $ hg showconfig extensions | grep largefiles
1005 $ hg showconfig extensions | grep largefiles
994 extensions.largefiles=!
1006 extensions.largefiles=!
995
1007
996 (test updating implied by clone)
1008 (test updating implied by clone)
997
1009
998 $ hg init enabled-but-no-largefiles
1010 $ hg init enabled-but-no-largefiles
999 $ echo normal1 > enabled-but-no-largefiles/normal1
1011 $ echo normal1 > enabled-but-no-largefiles/normal1
1000 $ hg -R enabled-but-no-largefiles add enabled-but-no-largefiles/normal1
1012 $ hg -R enabled-but-no-largefiles add enabled-but-no-largefiles/normal1
1001 $ hg -R enabled-but-no-largefiles commit -m '#0@enabled-but-no-largefiles'
1013 $ hg -R enabled-but-no-largefiles commit -m '#0@enabled-but-no-largefiles'
1002 Invoking status precommit hook
1014 Invoking status precommit hook
1003 A normal1
1015 A normal1
1004 $ cat >> enabled-but-no-largefiles/.hg/hgrc <<EOF
1016 $ cat >> enabled-but-no-largefiles/.hg/hgrc <<EOF
1005 > [extensions]
1017 > [extensions]
1006 > # enable locally
1018 > # enable locally
1007 > largefiles=
1019 > largefiles=
1008 > EOF
1020 > EOF
1009 $ hg clone -q enabled-but-no-largefiles no-largefiles
1021 $ hg clone -q enabled-but-no-largefiles no-largefiles
1010
1022
1011 $ echo normal2 > enabled-but-no-largefiles/normal2
1023 $ echo normal2 > enabled-but-no-largefiles/normal2
1012 $ hg -R enabled-but-no-largefiles add enabled-but-no-largefiles/normal2
1024 $ hg -R enabled-but-no-largefiles add enabled-but-no-largefiles/normal2
1013 $ hg -R enabled-but-no-largefiles commit -m '#1@enabled-but-no-largefiles'
1025 $ hg -R enabled-but-no-largefiles commit -m '#1@enabled-but-no-largefiles'
1014 Invoking status precommit hook
1026 Invoking status precommit hook
1015 A normal2
1027 A normal2
1016
1028
1017 $ echo normal3 > no-largefiles/normal3
1029 $ echo normal3 > no-largefiles/normal3
1018 $ hg -R no-largefiles add no-largefiles/normal3
1030 $ hg -R no-largefiles add no-largefiles/normal3
1019 $ hg -R no-largefiles commit -m '#1@no-largefiles'
1031 $ hg -R no-largefiles commit -m '#1@no-largefiles'
1020 Invoking status precommit hook
1032 Invoking status precommit hook
1021 A normal3
1033 A normal3
1022
1034
1023 $ hg -R no-largefiles -q pull --rebase
1035 $ hg -R no-largefiles -q pull --rebase
1024 Invoking status precommit hook
1036 Invoking status precommit hook
1025 A normal3
1037 A normal3
1026
1038
1027 (test reverting)
1039 (test reverting)
1028
1040
1029 $ hg init subrepo-root
1041 $ hg init subrepo-root
1030 $ cat >> subrepo-root/.hg/hgrc <<EOF
1042 $ cat >> subrepo-root/.hg/hgrc <<EOF
1031 > [extensions]
1043 > [extensions]
1032 > # enable locally
1044 > # enable locally
1033 > largefiles=
1045 > largefiles=
1034 > EOF
1046 > EOF
1035 $ echo large > subrepo-root/large
1047 $ echo large > subrepo-root/large
1036 $ hg -R subrepo-root add --large subrepo-root/large
1048 $ hg -R subrepo-root add --large subrepo-root/large
1037 $ hg clone -q no-largefiles subrepo-root/no-largefiles
1049 $ hg clone -q no-largefiles subrepo-root/no-largefiles
1038 $ cat > subrepo-root/.hgsub <<EOF
1050 $ cat > subrepo-root/.hgsub <<EOF
1039 > no-largefiles = no-largefiles
1051 > no-largefiles = no-largefiles
1040 > EOF
1052 > EOF
1041 $ hg -R subrepo-root add subrepo-root/.hgsub
1053 $ hg -R subrepo-root add subrepo-root/.hgsub
1042 $ hg -R subrepo-root commit -m '#0'
1054 $ hg -R subrepo-root commit -m '#0'
1043 Invoking status precommit hook
1055 Invoking status precommit hook
1044 A .hgsub
1056 A .hgsub
1045 A large
1057 A large
1046 ? .hgsubstate
1058 ? .hgsubstate
1047 $ echo dirty >> subrepo-root/large
1059 $ echo dirty >> subrepo-root/large
1048 $ echo dirty >> subrepo-root/no-largefiles/normal1
1060 $ echo dirty >> subrepo-root/no-largefiles/normal1
1049 $ hg -R subrepo-root status -S
1061 $ hg -R subrepo-root status -S
1050 M large
1062 M large
1051 M no-largefiles/normal1
1063 M no-largefiles/normal1
1052 $ hg -R subrepo-root revert --all
1064 $ hg -R subrepo-root revert --all
1053 reverting subrepo-root/.hglf/large (glob)
1065 reverting subrepo-root/.hglf/large (glob)
1054 reverting subrepo no-largefiles
1066 reverting subrepo no-largefiles
1055 reverting subrepo-root/no-largefiles/normal1 (glob)
1067 reverting subrepo-root/no-largefiles/normal1 (glob)
1056
1068
1057 $ cd ..
1069 $ cd ..
1058
1070
1059
1071
1060 Test "pull --rebase" when rebase is enabled before largefiles (issue3861)
1072 Test "pull --rebase" when rebase is enabled before largefiles (issue3861)
1061 =========================================================================
1073 =========================================================================
1062
1074
1063 $ hg showconfig extensions | grep largefiles
1075 $ hg showconfig extensions | grep largefiles
1064 extensions.largefiles=!
1076 extensions.largefiles=!
1065
1077
1066 $ mkdir issue3861
1078 $ mkdir issue3861
1067 $ cd issue3861
1079 $ cd issue3861
1068 $ hg init src
1080 $ hg init src
1069 $ hg clone -q src dst
1081 $ hg clone -q src dst
1070 $ echo a > src/a
1082 $ echo a > src/a
1071 $ hg -R src commit -Aqm "#0"
1083 $ hg -R src commit -Aqm "#0"
1072 Invoking status precommit hook
1084 Invoking status precommit hook
1073 A a
1085 A a
1074
1086
1075 $ cat >> dst/.hg/hgrc <<EOF
1087 $ cat >> dst/.hg/hgrc <<EOF
1076 > [extensions]
1088 > [extensions]
1077 > largefiles=
1089 > largefiles=
1078 > EOF
1090 > EOF
1079 $ hg -R dst pull --rebase
1091 $ hg -R dst pull --rebase
1080 pulling from $TESTTMP/issue3861/src (glob)
1092 pulling from $TESTTMP/issue3861/src (glob)
1081 requesting all changes
1093 requesting all changes
1082 adding changesets
1094 adding changesets
1083 adding manifests
1095 adding manifests
1084 adding file changes
1096 adding file changes
1085 added 1 changesets with 1 changes to 1 files
1097 added 1 changesets with 1 changes to 1 files
1086 nothing to rebase - working directory parent is already an ancestor of destination bf5e395ced2c
1098 nothing to rebase - working directory parent is already an ancestor of destination bf5e395ced2c
1087 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1099 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1088
1100
1089 $ cd ..
1101 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now