##// END OF EJS Templates
largefiles: fix largefiles+subrepo update (issue3752)...
Benoit Boissinot -
r18459:c9db897d stable
parent child Browse files
Show More
@@ -1,1163 +1,1163 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 '''Overridden Mercurial commands and functions for the largefiles extension'''
9 '''Overridden Mercurial commands and functions for the largefiles extension'''
10
10
11 import os
11 import os
12 import copy
12 import copy
13
13
14 from mercurial import hg, commands, util, cmdutil, scmutil, match as match_, \
14 from mercurial import hg, commands, util, cmdutil, scmutil, match as match_, \
15 node, archival, error, merge, discovery
15 node, archival, error, merge, discovery
16 from mercurial.i18n import _
16 from mercurial.i18n import _
17 from mercurial.node import hex
17 from mercurial.node import hex
18 from hgext import rebase
18 from hgext import rebase
19
19
20 import lfutil
20 import lfutil
21 import lfcommands
21 import lfcommands
22
22
23 # -- Utility functions: commonly/repeatedly needed functionality ---------------
23 # -- Utility functions: commonly/repeatedly needed functionality ---------------
24
24
25 def installnormalfilesmatchfn(manifest):
25 def installnormalfilesmatchfn(manifest):
26 '''overrides scmutil.match so that the matcher it returns will ignore all
26 '''overrides scmutil.match so that the matcher it returns will ignore all
27 largefiles'''
27 largefiles'''
28 oldmatch = None # for the closure
28 oldmatch = None # for the closure
29 def overridematch(ctx, pats=[], opts={}, globbed=False,
29 def overridematch(ctx, pats=[], opts={}, globbed=False,
30 default='relpath'):
30 default='relpath'):
31 match = oldmatch(ctx, pats, opts, globbed, default)
31 match = oldmatch(ctx, pats, opts, globbed, default)
32 m = copy.copy(match)
32 m = copy.copy(match)
33 notlfile = lambda f: not (lfutil.isstandin(f) or lfutil.standin(f) in
33 notlfile = lambda f: not (lfutil.isstandin(f) or lfutil.standin(f) in
34 manifest)
34 manifest)
35 m._files = filter(notlfile, m._files)
35 m._files = filter(notlfile, m._files)
36 m._fmap = set(m._files)
36 m._fmap = set(m._files)
37 origmatchfn = m.matchfn
37 origmatchfn = m.matchfn
38 m.matchfn = lambda f: notlfile(f) and origmatchfn(f) or None
38 m.matchfn = lambda f: notlfile(f) and origmatchfn(f) or None
39 return m
39 return m
40 oldmatch = installmatchfn(overridematch)
40 oldmatch = installmatchfn(overridematch)
41
41
42 def installmatchfn(f):
42 def installmatchfn(f):
43 oldmatch = scmutil.match
43 oldmatch = scmutil.match
44 setattr(f, 'oldmatch', oldmatch)
44 setattr(f, 'oldmatch', oldmatch)
45 scmutil.match = f
45 scmutil.match = f
46 return oldmatch
46 return oldmatch
47
47
48 def restorematchfn():
48 def restorematchfn():
49 '''restores scmutil.match to what it was before installnormalfilesmatchfn
49 '''restores scmutil.match to what it was before installnormalfilesmatchfn
50 was called. no-op if scmutil.match is its original function.
50 was called. no-op if scmutil.match is its original function.
51
51
52 Note that n calls to installnormalfilesmatchfn will require n calls to
52 Note that n calls to installnormalfilesmatchfn will require n calls to
53 restore matchfn to reverse'''
53 restore matchfn to reverse'''
54 scmutil.match = getattr(scmutil.match, 'oldmatch', scmutil.match)
54 scmutil.match = getattr(scmutil.match, 'oldmatch', scmutil.match)
55
55
56 def addlargefiles(ui, repo, *pats, **opts):
56 def addlargefiles(ui, repo, *pats, **opts):
57 large = opts.pop('large', None)
57 large = opts.pop('large', None)
58 lfsize = lfutil.getminsize(
58 lfsize = lfutil.getminsize(
59 ui, lfutil.islfilesrepo(repo), opts.pop('lfsize', None))
59 ui, lfutil.islfilesrepo(repo), opts.pop('lfsize', None))
60
60
61 lfmatcher = None
61 lfmatcher = None
62 if lfutil.islfilesrepo(repo):
62 if lfutil.islfilesrepo(repo):
63 lfpats = ui.configlist(lfutil.longname, 'patterns', default=[])
63 lfpats = ui.configlist(lfutil.longname, 'patterns', default=[])
64 if lfpats:
64 if lfpats:
65 lfmatcher = match_.match(repo.root, '', list(lfpats))
65 lfmatcher = match_.match(repo.root, '', list(lfpats))
66
66
67 lfnames = []
67 lfnames = []
68 m = scmutil.match(repo[None], pats, opts)
68 m = scmutil.match(repo[None], pats, opts)
69 m.bad = lambda x, y: None
69 m.bad = lambda x, y: None
70 wctx = repo[None]
70 wctx = repo[None]
71 for f in repo.walk(m):
71 for f in repo.walk(m):
72 exact = m.exact(f)
72 exact = m.exact(f)
73 lfile = lfutil.standin(f) in wctx
73 lfile = lfutil.standin(f) in wctx
74 nfile = f in wctx
74 nfile = f in wctx
75 exists = lfile or nfile
75 exists = lfile or nfile
76
76
77 # Don't warn the user when they attempt to add a normal tracked file.
77 # Don't warn the user when they attempt to add a normal tracked file.
78 # The normal add code will do that for us.
78 # The normal add code will do that for us.
79 if exact and exists:
79 if exact and exists:
80 if lfile:
80 if lfile:
81 ui.warn(_('%s already a largefile\n') % f)
81 ui.warn(_('%s already a largefile\n') % f)
82 continue
82 continue
83
83
84 if (exact or not exists) and not lfutil.isstandin(f):
84 if (exact or not exists) and not lfutil.isstandin(f):
85 wfile = repo.wjoin(f)
85 wfile = repo.wjoin(f)
86
86
87 # In case the file was removed previously, but not committed
87 # In case the file was removed previously, but not committed
88 # (issue3507)
88 # (issue3507)
89 if not os.path.exists(wfile):
89 if not os.path.exists(wfile):
90 continue
90 continue
91
91
92 abovemin = (lfsize and
92 abovemin = (lfsize and
93 os.lstat(wfile).st_size >= lfsize * 1024 * 1024)
93 os.lstat(wfile).st_size >= lfsize * 1024 * 1024)
94 if large or abovemin or (lfmatcher and lfmatcher(f)):
94 if large or abovemin or (lfmatcher and lfmatcher(f)):
95 lfnames.append(f)
95 lfnames.append(f)
96 if ui.verbose or not exact:
96 if ui.verbose or not exact:
97 ui.status(_('adding %s as a largefile\n') % m.rel(f))
97 ui.status(_('adding %s as a largefile\n') % m.rel(f))
98
98
99 bad = []
99 bad = []
100 standins = []
100 standins = []
101
101
102 # Need to lock, otherwise there could be a race condition between
102 # Need to lock, otherwise there could be a race condition between
103 # when standins are created and added to the repo.
103 # when standins are created and added to the repo.
104 wlock = repo.wlock()
104 wlock = repo.wlock()
105 try:
105 try:
106 if not opts.get('dry_run'):
106 if not opts.get('dry_run'):
107 lfdirstate = lfutil.openlfdirstate(ui, repo)
107 lfdirstate = lfutil.openlfdirstate(ui, repo)
108 for f in lfnames:
108 for f in lfnames:
109 standinname = lfutil.standin(f)
109 standinname = lfutil.standin(f)
110 lfutil.writestandin(repo, standinname, hash='',
110 lfutil.writestandin(repo, standinname, hash='',
111 executable=lfutil.getexecutable(repo.wjoin(f)))
111 executable=lfutil.getexecutable(repo.wjoin(f)))
112 standins.append(standinname)
112 standins.append(standinname)
113 if lfdirstate[f] == 'r':
113 if lfdirstate[f] == 'r':
114 lfdirstate.normallookup(f)
114 lfdirstate.normallookup(f)
115 else:
115 else:
116 lfdirstate.add(f)
116 lfdirstate.add(f)
117 lfdirstate.write()
117 lfdirstate.write()
118 bad += [lfutil.splitstandin(f)
118 bad += [lfutil.splitstandin(f)
119 for f in repo[None].add(standins)
119 for f in repo[None].add(standins)
120 if f in m.files()]
120 if f in m.files()]
121 finally:
121 finally:
122 wlock.release()
122 wlock.release()
123 return bad
123 return bad
124
124
125 def removelargefiles(ui, repo, *pats, **opts):
125 def removelargefiles(ui, repo, *pats, **opts):
126 after = opts.get('after')
126 after = opts.get('after')
127 if not pats and not after:
127 if not pats and not after:
128 raise util.Abort(_('no files specified'))
128 raise util.Abort(_('no files specified'))
129 m = scmutil.match(repo[None], pats, opts)
129 m = scmutil.match(repo[None], pats, opts)
130 try:
130 try:
131 repo.lfstatus = True
131 repo.lfstatus = True
132 s = repo.status(match=m, clean=True)
132 s = repo.status(match=m, clean=True)
133 finally:
133 finally:
134 repo.lfstatus = False
134 repo.lfstatus = False
135 manifest = repo[None].manifest()
135 manifest = repo[None].manifest()
136 modified, added, deleted, clean = [[f for f in list
136 modified, added, deleted, clean = [[f for f in list
137 if lfutil.standin(f) in manifest]
137 if lfutil.standin(f) in manifest]
138 for list in [s[0], s[1], s[3], s[6]]]
138 for list in [s[0], s[1], s[3], s[6]]]
139
139
140 def warn(files, msg):
140 def warn(files, msg):
141 for f in files:
141 for f in files:
142 ui.warn(msg % m.rel(f))
142 ui.warn(msg % m.rel(f))
143 return int(len(files) > 0)
143 return int(len(files) > 0)
144
144
145 result = 0
145 result = 0
146
146
147 if after:
147 if after:
148 remove, forget = deleted, []
148 remove, forget = deleted, []
149 result = warn(modified + added + clean,
149 result = warn(modified + added + clean,
150 _('not removing %s: file still exists\n'))
150 _('not removing %s: file still exists\n'))
151 else:
151 else:
152 remove, forget = deleted + clean, []
152 remove, forget = deleted + clean, []
153 result = warn(modified, _('not removing %s: file is modified (use -f'
153 result = warn(modified, _('not removing %s: file is modified (use -f'
154 ' to force removal)\n'))
154 ' to force removal)\n'))
155 result = warn(added, _('not removing %s: file has been marked for add'
155 result = warn(added, _('not removing %s: file has been marked for add'
156 ' (use forget to undo)\n')) or result
156 ' (use forget to undo)\n')) or result
157
157
158 for f in sorted(remove + forget):
158 for f in sorted(remove + forget):
159 if ui.verbose or not m.exact(f):
159 if ui.verbose or not m.exact(f):
160 ui.status(_('removing %s\n') % m.rel(f))
160 ui.status(_('removing %s\n') % m.rel(f))
161
161
162 # Need to lock because standin files are deleted then removed from the
162 # Need to lock because standin files are deleted then removed from the
163 # repository and we could race in-between.
163 # repository and we could race in-between.
164 wlock = repo.wlock()
164 wlock = repo.wlock()
165 try:
165 try:
166 lfdirstate = lfutil.openlfdirstate(ui, repo)
166 lfdirstate = lfutil.openlfdirstate(ui, repo)
167 for f in remove:
167 for f in remove:
168 if not after:
168 if not after:
169 # If this is being called by addremove, notify the user that we
169 # If this is being called by addremove, notify the user that we
170 # are removing the file.
170 # are removing the file.
171 if getattr(repo, "_isaddremove", False):
171 if getattr(repo, "_isaddremove", False):
172 ui.status(_('removing %s\n') % f)
172 ui.status(_('removing %s\n') % f)
173 util.unlinkpath(repo.wjoin(f), ignoremissing=True)
173 util.unlinkpath(repo.wjoin(f), ignoremissing=True)
174 lfdirstate.remove(f)
174 lfdirstate.remove(f)
175 lfdirstate.write()
175 lfdirstate.write()
176 forget = [lfutil.standin(f) for f in forget]
176 forget = [lfutil.standin(f) for f in forget]
177 remove = [lfutil.standin(f) for f in remove]
177 remove = [lfutil.standin(f) for f in remove]
178 repo[None].forget(forget)
178 repo[None].forget(forget)
179 # If this is being called by addremove, let the original addremove
179 # If this is being called by addremove, let the original addremove
180 # function handle this.
180 # function handle this.
181 if not getattr(repo, "_isaddremove", False):
181 if not getattr(repo, "_isaddremove", False):
182 for f in remove:
182 for f in remove:
183 util.unlinkpath(repo.wjoin(f), ignoremissing=True)
183 util.unlinkpath(repo.wjoin(f), ignoremissing=True)
184 repo[None].forget(remove)
184 repo[None].forget(remove)
185 finally:
185 finally:
186 wlock.release()
186 wlock.release()
187
187
188 return result
188 return result
189
189
190 # For overriding mercurial.hgweb.webcommands so that largefiles will
190 # For overriding mercurial.hgweb.webcommands so that largefiles will
191 # appear at their right place in the manifests.
191 # appear at their right place in the manifests.
192 def decodepath(orig, path):
192 def decodepath(orig, path):
193 return lfutil.splitstandin(path) or path
193 return lfutil.splitstandin(path) or path
194
194
195 # -- Wrappers: modify existing commands --------------------------------
195 # -- Wrappers: modify existing commands --------------------------------
196
196
197 # Add works by going through the files that the user wanted to add and
197 # Add works by going through the files that the user wanted to add and
198 # checking if they should be added as largefiles. Then it makes a new
198 # checking if they should be added as largefiles. Then it makes a new
199 # matcher which matches only the normal files and runs the original
199 # matcher which matches only the normal files and runs the original
200 # version of add.
200 # version of add.
201 def overrideadd(orig, ui, repo, *pats, **opts):
201 def overrideadd(orig, ui, repo, *pats, **opts):
202 normal = opts.pop('normal')
202 normal = opts.pop('normal')
203 if normal:
203 if normal:
204 if opts.get('large'):
204 if opts.get('large'):
205 raise util.Abort(_('--normal cannot be used with --large'))
205 raise util.Abort(_('--normal cannot be used with --large'))
206 return orig(ui, repo, *pats, **opts)
206 return orig(ui, repo, *pats, **opts)
207 bad = addlargefiles(ui, repo, *pats, **opts)
207 bad = addlargefiles(ui, repo, *pats, **opts)
208 installnormalfilesmatchfn(repo[None].manifest())
208 installnormalfilesmatchfn(repo[None].manifest())
209 result = orig(ui, repo, *pats, **opts)
209 result = orig(ui, repo, *pats, **opts)
210 restorematchfn()
210 restorematchfn()
211
211
212 return (result == 1 or bad) and 1 or 0
212 return (result == 1 or bad) and 1 or 0
213
213
214 def overrideremove(orig, ui, repo, *pats, **opts):
214 def overrideremove(orig, ui, repo, *pats, **opts):
215 installnormalfilesmatchfn(repo[None].manifest())
215 installnormalfilesmatchfn(repo[None].manifest())
216 result = orig(ui, repo, *pats, **opts)
216 result = orig(ui, repo, *pats, **opts)
217 restorematchfn()
217 restorematchfn()
218 return removelargefiles(ui, repo, *pats, **opts) or result
218 return removelargefiles(ui, repo, *pats, **opts) or result
219
219
220 def overridestatusfn(orig, repo, rev2, **opts):
220 def overridestatusfn(orig, repo, rev2, **opts):
221 try:
221 try:
222 repo._repo.lfstatus = True
222 repo._repo.lfstatus = True
223 return orig(repo, rev2, **opts)
223 return orig(repo, rev2, **opts)
224 finally:
224 finally:
225 repo._repo.lfstatus = False
225 repo._repo.lfstatus = False
226
226
227 def overridestatus(orig, ui, repo, *pats, **opts):
227 def overridestatus(orig, ui, repo, *pats, **opts):
228 try:
228 try:
229 repo.lfstatus = True
229 repo.lfstatus = True
230 return orig(ui, repo, *pats, **opts)
230 return orig(ui, repo, *pats, **opts)
231 finally:
231 finally:
232 repo.lfstatus = False
232 repo.lfstatus = False
233
233
234 def overridedirty(orig, repo, ignoreupdate=False):
234 def overridedirty(orig, repo, ignoreupdate=False):
235 try:
235 try:
236 repo._repo.lfstatus = True
236 repo._repo.lfstatus = True
237 return orig(repo, ignoreupdate)
237 return orig(repo, ignoreupdate)
238 finally:
238 finally:
239 repo._repo.lfstatus = False
239 repo._repo.lfstatus = False
240
240
241 def overridelog(orig, ui, repo, *pats, **opts):
241 def overridelog(orig, ui, repo, *pats, **opts):
242 def overridematch(ctx, pats=[], opts={}, globbed=False,
242 def overridematch(ctx, pats=[], opts={}, globbed=False,
243 default='relpath'):
243 default='relpath'):
244 """Matcher that merges root directory with .hglf, suitable for log.
244 """Matcher that merges root directory with .hglf, suitable for log.
245 It is still possible to match .hglf directly.
245 It is still possible to match .hglf directly.
246 For any listed files run log on the standin too.
246 For any listed files run log on the standin too.
247 matchfn tries both the given filename and with .hglf stripped.
247 matchfn tries both the given filename and with .hglf stripped.
248 """
248 """
249 match = oldmatch(ctx, pats, opts, globbed, default)
249 match = oldmatch(ctx, pats, opts, globbed, default)
250 m = copy.copy(match)
250 m = copy.copy(match)
251 standins = [lfutil.standin(f) for f in m._files]
251 standins = [lfutil.standin(f) for f in m._files]
252 m._files.extend(standins)
252 m._files.extend(standins)
253 m._fmap = set(m._files)
253 m._fmap = set(m._files)
254 origmatchfn = m.matchfn
254 origmatchfn = m.matchfn
255 def lfmatchfn(f):
255 def lfmatchfn(f):
256 lf = lfutil.splitstandin(f)
256 lf = lfutil.splitstandin(f)
257 if lf is not None and origmatchfn(lf):
257 if lf is not None and origmatchfn(lf):
258 return True
258 return True
259 r = origmatchfn(f)
259 r = origmatchfn(f)
260 return r
260 return r
261 m.matchfn = lfmatchfn
261 m.matchfn = lfmatchfn
262 return m
262 return m
263 oldmatch = installmatchfn(overridematch)
263 oldmatch = installmatchfn(overridematch)
264 try:
264 try:
265 repo.lfstatus = True
265 repo.lfstatus = True
266 return orig(ui, repo, *pats, **opts)
266 return orig(ui, repo, *pats, **opts)
267 finally:
267 finally:
268 repo.lfstatus = False
268 repo.lfstatus = False
269 restorematchfn()
269 restorematchfn()
270
270
271 def overrideverify(orig, ui, repo, *pats, **opts):
271 def overrideverify(orig, ui, repo, *pats, **opts):
272 large = opts.pop('large', False)
272 large = opts.pop('large', False)
273 all = opts.pop('lfa', False)
273 all = opts.pop('lfa', False)
274 contents = opts.pop('lfc', False)
274 contents = opts.pop('lfc', False)
275
275
276 result = orig(ui, repo, *pats, **opts)
276 result = orig(ui, repo, *pats, **opts)
277 if large:
277 if large:
278 result = result or lfcommands.verifylfiles(ui, repo, all, contents)
278 result = result or lfcommands.verifylfiles(ui, repo, all, contents)
279 return result
279 return result
280
280
281 def overridedebugstate(orig, ui, repo, *pats, **opts):
281 def overridedebugstate(orig, ui, repo, *pats, **opts):
282 large = opts.pop('large', False)
282 large = opts.pop('large', False)
283 if large:
283 if large:
284 lfcommands.debugdirstate(ui, repo)
284 lfcommands.debugdirstate(ui, repo)
285 else:
285 else:
286 orig(ui, repo, *pats, **opts)
286 orig(ui, repo, *pats, **opts)
287
287
288 # Override needs to refresh standins so that update's normal merge
288 # Override needs to refresh standins so that update's normal merge
289 # will go through properly. Then the other update hook (overriding repo.update)
289 # will go through properly. Then the other update hook (overriding repo.update)
290 # will get the new files. Filemerge is also overridden so that the merge
290 # will get the new files. Filemerge is also overridden so that the merge
291 # will merge standins correctly.
291 # will merge standins correctly.
292 def overrideupdate(orig, ui, repo, *pats, **opts):
292 def overrideupdate(orig, ui, repo, *pats, **opts):
293 lfdirstate = lfutil.openlfdirstate(ui, repo)
293 lfdirstate = lfutil.openlfdirstate(ui, repo)
294 s = lfdirstate.status(match_.always(repo.root, repo.getcwd()), [], False,
294 s = lfdirstate.status(match_.always(repo.root, repo.getcwd()), [], False,
295 False, False)
295 False, False)
296 (unsure, modified, added, removed, missing, unknown, ignored, clean) = s
296 (unsure, modified, added, removed, missing, unknown, ignored, clean) = s
297
297
298 # Need to lock between the standins getting updated and their
298 # Need to lock between the standins getting updated and their
299 # largefiles getting updated
299 # largefiles getting updated
300 wlock = repo.wlock()
300 wlock = repo.wlock()
301 try:
301 try:
302 if opts['check']:
302 if opts['check']:
303 mod = len(modified) > 0
303 mod = len(modified) > 0
304 for lfile in unsure:
304 for lfile in unsure:
305 standin = lfutil.standin(lfile)
305 standin = lfutil.standin(lfile)
306 if repo['.'][standin].data().strip() != \
306 if repo['.'][standin].data().strip() != \
307 lfutil.hashfile(repo.wjoin(lfile)):
307 lfutil.hashfile(repo.wjoin(lfile)):
308 mod = True
308 mod = True
309 else:
309 else:
310 lfdirstate.normal(lfile)
310 lfdirstate.normal(lfile)
311 lfdirstate.write()
311 lfdirstate.write()
312 if mod:
312 if mod:
313 raise util.Abort(_('uncommitted local changes'))
313 raise util.Abort(_('uncommitted local changes'))
314 # XXX handle removed differently
314 # XXX handle removed differently
315 if not opts['clean']:
315 if not opts['clean']:
316 for lfile in unsure + modified + added:
316 for lfile in unsure + modified + added:
317 lfutil.updatestandin(repo, lfutil.standin(lfile))
317 lfutil.updatestandin(repo, lfutil.standin(lfile))
318 finally:
318 finally:
319 wlock.release()
319 wlock.release()
320 return orig(ui, repo, *pats, **opts)
320 return orig(ui, repo, *pats, **opts)
321
321
322 # Before starting the manifest merge, merge.updates will call
322 # Before starting the manifest merge, merge.updates will call
323 # _checkunknown to check if there are any files in the merged-in
323 # _checkunknown to check if there are any files in the merged-in
324 # changeset that collide with unknown files in the working copy.
324 # changeset that collide with unknown files in the working copy.
325 #
325 #
326 # The largefiles are seen as unknown, so this prevents us from merging
326 # The largefiles are seen as unknown, so this prevents us from merging
327 # in a file 'foo' if we already have a largefile with the same name.
327 # in a file 'foo' if we already have a largefile with the same name.
328 #
328 #
329 # The overridden function filters the unknown files by removing any
329 # The overridden function filters the unknown files by removing any
330 # largefiles. This makes the merge proceed and we can then handle this
330 # largefiles. This makes the merge proceed and we can then handle this
331 # case further in the overridden manifestmerge function below.
331 # case further in the overridden manifestmerge function below.
332 def overridecheckunknownfile(origfn, repo, wctx, mctx, f):
332 def overridecheckunknownfile(origfn, repo, wctx, mctx, f):
333 if lfutil.standin(f) in wctx:
333 if lfutil.standin(f) in wctx:
334 return False
334 return False
335 return origfn(repo, wctx, mctx, f)
335 return origfn(repo, wctx, mctx, f)
336
336
337 # The manifest merge handles conflicts on the manifest level. We want
337 # The manifest merge handles conflicts on the manifest level. We want
338 # to handle changes in largefile-ness of files at this level too.
338 # to handle changes in largefile-ness of files at this level too.
339 #
339 #
340 # The strategy is to run the original manifestmerge and then process
340 # The strategy is to run the original manifestmerge and then process
341 # the action list it outputs. There are two cases we need to deal with:
341 # the action list it outputs. There are two cases we need to deal with:
342 #
342 #
343 # 1. Normal file in p1, largefile in p2. Here the largefile is
343 # 1. Normal file in p1, largefile in p2. Here the largefile is
344 # detected via its standin file, which will enter the working copy
344 # detected via its standin file, which will enter the working copy
345 # with a "get" action. It is not "merge" since the standin is all
345 # with a "get" action. It is not "merge" since the standin is all
346 # Mercurial is concerned with at this level -- the link to the
346 # Mercurial is concerned with at this level -- the link to the
347 # existing normal file is not relevant here.
347 # existing normal file is not relevant here.
348 #
348 #
349 # 2. Largefile in p1, normal file in p2. Here we get a "merge" action
349 # 2. Largefile in p1, normal file in p2. Here we get a "merge" action
350 # since the largefile will be present in the working copy and
350 # since the largefile will be present in the working copy and
351 # different from the normal file in p2. Mercurial therefore
351 # different from the normal file in p2. Mercurial therefore
352 # triggers a merge action.
352 # triggers a merge action.
353 #
353 #
354 # In both cases, we prompt the user and emit new actions to either
354 # In both cases, we prompt the user and emit new actions to either
355 # remove the standin (if the normal file was kept) or to remove the
355 # remove the standin (if the normal file was kept) or to remove the
356 # normal file and get the standin (if the largefile was kept). The
356 # normal file and get the standin (if the largefile was kept). The
357 # default prompt answer is to use the largefile version since it was
357 # default prompt answer is to use the largefile version since it was
358 # presumably changed on purpose.
358 # presumably changed on purpose.
359 #
359 #
360 # Finally, the merge.applyupdates function will then take care of
360 # Finally, the merge.applyupdates function will then take care of
361 # writing the files into the working copy and lfcommands.updatelfiles
361 # writing the files into the working copy and lfcommands.updatelfiles
362 # will update the largefiles.
362 # will update the largefiles.
363 def overridemanifestmerge(origfn, repo, p1, p2, pa, overwrite, partial):
363 def overridemanifestmerge(origfn, repo, p1, p2, pa, overwrite, partial):
364 actions = origfn(repo, p1, p2, pa, overwrite, partial)
364 actions = origfn(repo, p1, p2, pa, overwrite, partial)
365 processed = []
365 processed = []
366
366
367 for action in actions:
367 for action in actions:
368 if overwrite:
368 if overwrite:
369 processed.append(action)
369 processed.append(action)
370 continue
370 continue
371 f, m = action[:2]
371 f, m = action[:2]
372
372
373 choices = (_('&Largefile'), _('&Normal file'))
373 choices = (_('&Largefile'), _('&Normal file'))
374 if m == "g" and lfutil.splitstandin(f) in p1 and f in p2:
374 if m == "g" and lfutil.splitstandin(f) in p1 and f in p2:
375 # Case 1: normal file in the working copy, largefile in
375 # Case 1: normal file in the working copy, largefile in
376 # the second parent
376 # the second parent
377 lfile = lfutil.splitstandin(f)
377 lfile = lfutil.splitstandin(f)
378 standin = f
378 standin = f
379 msg = _('%s has been turned into a largefile\n'
379 msg = _('%s has been turned into a largefile\n'
380 'use (l)argefile or keep as (n)ormal file?') % lfile
380 'use (l)argefile or keep as (n)ormal file?') % lfile
381 if repo.ui.promptchoice(msg, choices, 0) == 0:
381 if repo.ui.promptchoice(msg, choices, 0) == 0:
382 processed.append((lfile, "r"))
382 processed.append((lfile, "r"))
383 processed.append((standin, "g", p2.flags(standin)))
383 processed.append((standin, "g", p2.flags(standin)))
384 else:
384 else:
385 processed.append((standin, "r"))
385 processed.append((standin, "r"))
386 elif m == "g" and lfutil.standin(f) in p1 and f in p2:
386 elif m == "g" and lfutil.standin(f) in p1 and f in p2:
387 # Case 2: largefile in the working copy, normal file in
387 # Case 2: largefile in the working copy, normal file in
388 # the second parent
388 # the second parent
389 standin = lfutil.standin(f)
389 standin = lfutil.standin(f)
390 lfile = f
390 lfile = f
391 msg = _('%s has been turned into a normal file\n'
391 msg = _('%s has been turned into a normal file\n'
392 'keep as (l)argefile or use (n)ormal file?') % lfile
392 'keep as (l)argefile or use (n)ormal file?') % lfile
393 if repo.ui.promptchoice(msg, choices, 0) == 0:
393 if repo.ui.promptchoice(msg, choices, 0) == 0:
394 processed.append((lfile, "r"))
394 processed.append((lfile, "r"))
395 else:
395 else:
396 processed.append((standin, "r"))
396 processed.append((standin, "r"))
397 processed.append((lfile, "g", p2.flags(lfile)))
397 processed.append((lfile, "g", p2.flags(lfile)))
398 else:
398 else:
399 processed.append(action)
399 processed.append(action)
400
400
401 return processed
401 return processed
402
402
403 # Override filemerge to prompt the user about how they wish to merge
403 # Override filemerge to prompt the user about how they wish to merge
404 # largefiles. This will handle identical edits, and copy/rename +
404 # largefiles. This will handle identical edits, and copy/rename +
405 # edit without prompting the user.
405 # edit without prompting the user.
406 def overridefilemerge(origfn, repo, mynode, orig, fcd, fco, fca):
406 def overridefilemerge(origfn, repo, mynode, orig, fcd, fco, fca):
407 # Use better variable names here. Because this is a wrapper we cannot
407 # Use better variable names here. Because this is a wrapper we cannot
408 # change the variable names in the function declaration.
408 # change the variable names in the function declaration.
409 fcdest, fcother, fcancestor = fcd, fco, fca
409 fcdest, fcother, fcancestor = fcd, fco, fca
410 if not lfutil.isstandin(orig):
410 if not lfutil.isstandin(orig):
411 return origfn(repo, mynode, orig, fcdest, fcother, fcancestor)
411 return origfn(repo, mynode, orig, fcdest, fcother, fcancestor)
412 else:
412 else:
413 if not fcother.cmp(fcdest): # files identical?
413 if not fcother.cmp(fcdest): # files identical?
414 return None
414 return None
415
415
416 # backwards, use working dir parent as ancestor
416 # backwards, use working dir parent as ancestor
417 if fcancestor == fcother:
417 if fcancestor == fcother:
418 fcancestor = fcdest.parents()[0]
418 fcancestor = fcdest.parents()[0]
419
419
420 if orig != fcother.path():
420 if orig != fcother.path():
421 repo.ui.status(_('merging %s and %s to %s\n')
421 repo.ui.status(_('merging %s and %s to %s\n')
422 % (lfutil.splitstandin(orig),
422 % (lfutil.splitstandin(orig),
423 lfutil.splitstandin(fcother.path()),
423 lfutil.splitstandin(fcother.path()),
424 lfutil.splitstandin(fcdest.path())))
424 lfutil.splitstandin(fcdest.path())))
425 else:
425 else:
426 repo.ui.status(_('merging %s\n')
426 repo.ui.status(_('merging %s\n')
427 % lfutil.splitstandin(fcdest.path()))
427 % lfutil.splitstandin(fcdest.path()))
428
428
429 if fcancestor.path() != fcother.path() and fcother.data() == \
429 if fcancestor.path() != fcother.path() and fcother.data() == \
430 fcancestor.data():
430 fcancestor.data():
431 return 0
431 return 0
432 if fcancestor.path() != fcdest.path() and fcdest.data() == \
432 if fcancestor.path() != fcdest.path() and fcdest.data() == \
433 fcancestor.data():
433 fcancestor.data():
434 repo.wwrite(fcdest.path(), fcother.data(), fcother.flags())
434 repo.wwrite(fcdest.path(), fcother.data(), fcother.flags())
435 return 0
435 return 0
436
436
437 if repo.ui.promptchoice(_('largefile %s has a merge conflict\n'
437 if repo.ui.promptchoice(_('largefile %s has a merge conflict\n'
438 'keep (l)ocal or take (o)ther?') %
438 'keep (l)ocal or take (o)ther?') %
439 lfutil.splitstandin(orig),
439 lfutil.splitstandin(orig),
440 (_('&Local'), _('&Other')), 0) == 0:
440 (_('&Local'), _('&Other')), 0) == 0:
441 return 0
441 return 0
442 else:
442 else:
443 repo.wwrite(fcdest.path(), fcother.data(), fcother.flags())
443 repo.wwrite(fcdest.path(), fcother.data(), fcother.flags())
444 return 0
444 return 0
445
445
446 # Copy first changes the matchers to match standins instead of
446 # Copy first changes the matchers to match standins instead of
447 # largefiles. Then it overrides util.copyfile in that function it
447 # largefiles. Then it overrides util.copyfile in that function it
448 # checks if the destination largefile already exists. It also keeps a
448 # checks if the destination largefile already exists. It also keeps a
449 # list of copied files so that the largefiles can be copied and the
449 # list of copied files so that the largefiles can be copied and the
450 # dirstate updated.
450 # dirstate updated.
451 def overridecopy(orig, ui, repo, pats, opts, rename=False):
451 def overridecopy(orig, ui, repo, pats, opts, rename=False):
452 # doesn't remove largefile on rename
452 # doesn't remove largefile on rename
453 if len(pats) < 2:
453 if len(pats) < 2:
454 # this isn't legal, let the original function deal with it
454 # this isn't legal, let the original function deal with it
455 return orig(ui, repo, pats, opts, rename)
455 return orig(ui, repo, pats, opts, rename)
456
456
457 def makestandin(relpath):
457 def makestandin(relpath):
458 path = scmutil.canonpath(repo.root, repo.getcwd(), relpath)
458 path = scmutil.canonpath(repo.root, repo.getcwd(), relpath)
459 return os.path.join(repo.wjoin(lfutil.standin(path)))
459 return os.path.join(repo.wjoin(lfutil.standin(path)))
460
460
461 fullpats = scmutil.expandpats(pats)
461 fullpats = scmutil.expandpats(pats)
462 dest = fullpats[-1]
462 dest = fullpats[-1]
463
463
464 if os.path.isdir(dest):
464 if os.path.isdir(dest):
465 if not os.path.isdir(makestandin(dest)):
465 if not os.path.isdir(makestandin(dest)):
466 os.makedirs(makestandin(dest))
466 os.makedirs(makestandin(dest))
467 # This could copy both lfiles and normal files in one command,
467 # This could copy both lfiles and normal files in one command,
468 # but we don't want to do that. First replace their matcher to
468 # but we don't want to do that. First replace their matcher to
469 # only match normal files and run it, then replace it to just
469 # only match normal files and run it, then replace it to just
470 # match largefiles and run it again.
470 # match largefiles and run it again.
471 nonormalfiles = False
471 nonormalfiles = False
472 nolfiles = False
472 nolfiles = False
473 try:
473 try:
474 try:
474 try:
475 installnormalfilesmatchfn(repo[None].manifest())
475 installnormalfilesmatchfn(repo[None].manifest())
476 result = orig(ui, repo, pats, opts, rename)
476 result = orig(ui, repo, pats, opts, rename)
477 except util.Abort, e:
477 except util.Abort, e:
478 if str(e) != _('no files to copy'):
478 if str(e) != _('no files to copy'):
479 raise e
479 raise e
480 else:
480 else:
481 nonormalfiles = True
481 nonormalfiles = True
482 result = 0
482 result = 0
483 finally:
483 finally:
484 restorematchfn()
484 restorematchfn()
485
485
486 # The first rename can cause our current working directory to be removed.
486 # The first rename can cause our current working directory to be removed.
487 # In that case there is nothing left to copy/rename so just quit.
487 # In that case there is nothing left to copy/rename so just quit.
488 try:
488 try:
489 repo.getcwd()
489 repo.getcwd()
490 except OSError:
490 except OSError:
491 return result
491 return result
492
492
493 try:
493 try:
494 try:
494 try:
495 # When we call orig below it creates the standins but we don't add
495 # When we call orig below it creates the standins but we don't add
496 # them to the dir state until later so lock during that time.
496 # them to the dir state until later so lock during that time.
497 wlock = repo.wlock()
497 wlock = repo.wlock()
498
498
499 manifest = repo[None].manifest()
499 manifest = repo[None].manifest()
500 oldmatch = None # for the closure
500 oldmatch = None # for the closure
501 def overridematch(ctx, pats=[], opts={}, globbed=False,
501 def overridematch(ctx, pats=[], opts={}, globbed=False,
502 default='relpath'):
502 default='relpath'):
503 newpats = []
503 newpats = []
504 # The patterns were previously mangled to add the standin
504 # The patterns were previously mangled to add the standin
505 # directory; we need to remove that now
505 # directory; we need to remove that now
506 for pat in pats:
506 for pat in pats:
507 if match_.patkind(pat) is None and lfutil.shortname in pat:
507 if match_.patkind(pat) is None and lfutil.shortname in pat:
508 newpats.append(pat.replace(lfutil.shortname, ''))
508 newpats.append(pat.replace(lfutil.shortname, ''))
509 else:
509 else:
510 newpats.append(pat)
510 newpats.append(pat)
511 match = oldmatch(ctx, newpats, opts, globbed, default)
511 match = oldmatch(ctx, newpats, opts, globbed, default)
512 m = copy.copy(match)
512 m = copy.copy(match)
513 lfile = lambda f: lfutil.standin(f) in manifest
513 lfile = lambda f: lfutil.standin(f) in manifest
514 m._files = [lfutil.standin(f) for f in m._files if lfile(f)]
514 m._files = [lfutil.standin(f) for f in m._files if lfile(f)]
515 m._fmap = set(m._files)
515 m._fmap = set(m._files)
516 origmatchfn = m.matchfn
516 origmatchfn = m.matchfn
517 m.matchfn = lambda f: (lfutil.isstandin(f) and
517 m.matchfn = lambda f: (lfutil.isstandin(f) and
518 (f in manifest) and
518 (f in manifest) and
519 origmatchfn(lfutil.splitstandin(f)) or
519 origmatchfn(lfutil.splitstandin(f)) or
520 None)
520 None)
521 return m
521 return m
522 oldmatch = installmatchfn(overridematch)
522 oldmatch = installmatchfn(overridematch)
523 listpats = []
523 listpats = []
524 for pat in pats:
524 for pat in pats:
525 if match_.patkind(pat) is not None:
525 if match_.patkind(pat) is not None:
526 listpats.append(pat)
526 listpats.append(pat)
527 else:
527 else:
528 listpats.append(makestandin(pat))
528 listpats.append(makestandin(pat))
529
529
530 try:
530 try:
531 origcopyfile = util.copyfile
531 origcopyfile = util.copyfile
532 copiedfiles = []
532 copiedfiles = []
533 def overridecopyfile(src, dest):
533 def overridecopyfile(src, dest):
534 if (lfutil.shortname in src and
534 if (lfutil.shortname in src and
535 dest.startswith(repo.wjoin(lfutil.shortname))):
535 dest.startswith(repo.wjoin(lfutil.shortname))):
536 destlfile = dest.replace(lfutil.shortname, '')
536 destlfile = dest.replace(lfutil.shortname, '')
537 if not opts['force'] and os.path.exists(destlfile):
537 if not opts['force'] and os.path.exists(destlfile):
538 raise IOError('',
538 raise IOError('',
539 _('destination largefile already exists'))
539 _('destination largefile already exists'))
540 copiedfiles.append((src, dest))
540 copiedfiles.append((src, dest))
541 origcopyfile(src, dest)
541 origcopyfile(src, dest)
542
542
543 util.copyfile = overridecopyfile
543 util.copyfile = overridecopyfile
544 result += orig(ui, repo, listpats, opts, rename)
544 result += orig(ui, repo, listpats, opts, rename)
545 finally:
545 finally:
546 util.copyfile = origcopyfile
546 util.copyfile = origcopyfile
547
547
548 lfdirstate = lfutil.openlfdirstate(ui, repo)
548 lfdirstate = lfutil.openlfdirstate(ui, repo)
549 for (src, dest) in copiedfiles:
549 for (src, dest) in copiedfiles:
550 if (lfutil.shortname in src and
550 if (lfutil.shortname in src and
551 dest.startswith(repo.wjoin(lfutil.shortname))):
551 dest.startswith(repo.wjoin(lfutil.shortname))):
552 srclfile = src.replace(repo.wjoin(lfutil.standin('')), '')
552 srclfile = src.replace(repo.wjoin(lfutil.standin('')), '')
553 destlfile = dest.replace(repo.wjoin(lfutil.standin('')), '')
553 destlfile = dest.replace(repo.wjoin(lfutil.standin('')), '')
554 destlfiledir = os.path.dirname(repo.wjoin(destlfile)) or '.'
554 destlfiledir = os.path.dirname(repo.wjoin(destlfile)) or '.'
555 if not os.path.isdir(destlfiledir):
555 if not os.path.isdir(destlfiledir):
556 os.makedirs(destlfiledir)
556 os.makedirs(destlfiledir)
557 if rename:
557 if rename:
558 os.rename(repo.wjoin(srclfile), repo.wjoin(destlfile))
558 os.rename(repo.wjoin(srclfile), repo.wjoin(destlfile))
559 lfdirstate.remove(srclfile)
559 lfdirstate.remove(srclfile)
560 else:
560 else:
561 util.copyfile(repo.wjoin(srclfile),
561 util.copyfile(repo.wjoin(srclfile),
562 repo.wjoin(destlfile))
562 repo.wjoin(destlfile))
563
563
564 lfdirstate.add(destlfile)
564 lfdirstate.add(destlfile)
565 lfdirstate.write()
565 lfdirstate.write()
566 except util.Abort, e:
566 except util.Abort, e:
567 if str(e) != _('no files to copy'):
567 if str(e) != _('no files to copy'):
568 raise e
568 raise e
569 else:
569 else:
570 nolfiles = True
570 nolfiles = True
571 finally:
571 finally:
572 restorematchfn()
572 restorematchfn()
573 wlock.release()
573 wlock.release()
574
574
575 if nolfiles and nonormalfiles:
575 if nolfiles and nonormalfiles:
576 raise util.Abort(_('no files to copy'))
576 raise util.Abort(_('no files to copy'))
577
577
578 return result
578 return result
579
579
580 # When the user calls revert, we have to be careful to not revert any
580 # When the user calls revert, we have to be careful to not revert any
581 # changes to other largefiles accidentally. This means we have to keep
581 # changes to other largefiles accidentally. This means we have to keep
582 # track of the largefiles that are being reverted so we only pull down
582 # track of the largefiles that are being reverted so we only pull down
583 # the necessary largefiles.
583 # the necessary largefiles.
584 #
584 #
585 # Standins are only updated (to match the hash of largefiles) before
585 # Standins are only updated (to match the hash of largefiles) before
586 # commits. Update the standins then run the original revert, changing
586 # commits. Update the standins then run the original revert, changing
587 # the matcher to hit standins instead of largefiles. Based on the
587 # the matcher to hit standins instead of largefiles. Based on the
588 # resulting standins update the largefiles. Then return the standins
588 # resulting standins update the largefiles. Then return the standins
589 # to their proper state
589 # to their proper state
590 def overriderevert(orig, ui, repo, *pats, **opts):
590 def overriderevert(orig, ui, repo, *pats, **opts):
591 # Because we put the standins in a bad state (by updating them)
591 # Because we put the standins in a bad state (by updating them)
592 # and then return them to a correct state we need to lock to
592 # and then return them to a correct state we need to lock to
593 # prevent others from changing them in their incorrect state.
593 # prevent others from changing them in their incorrect state.
594 wlock = repo.wlock()
594 wlock = repo.wlock()
595 try:
595 try:
596 lfdirstate = lfutil.openlfdirstate(ui, repo)
596 lfdirstate = lfutil.openlfdirstate(ui, repo)
597 (modified, added, removed, missing, unknown, ignored, clean) = \
597 (modified, added, removed, missing, unknown, ignored, clean) = \
598 lfutil.lfdirstatestatus(lfdirstate, repo, repo['.'].rev())
598 lfutil.lfdirstatestatus(lfdirstate, repo, repo['.'].rev())
599 lfdirstate.write()
599 lfdirstate.write()
600 for lfile in modified:
600 for lfile in modified:
601 lfutil.updatestandin(repo, lfutil.standin(lfile))
601 lfutil.updatestandin(repo, lfutil.standin(lfile))
602 for lfile in missing:
602 for lfile in missing:
603 if (os.path.exists(repo.wjoin(lfutil.standin(lfile)))):
603 if (os.path.exists(repo.wjoin(lfutil.standin(lfile)))):
604 os.unlink(repo.wjoin(lfutil.standin(lfile)))
604 os.unlink(repo.wjoin(lfutil.standin(lfile)))
605
605
606 try:
606 try:
607 ctx = scmutil.revsingle(repo, opts.get('rev'))
607 ctx = scmutil.revsingle(repo, opts.get('rev'))
608 oldmatch = None # for the closure
608 oldmatch = None # for the closure
609 def overridematch(ctx, pats=[], opts={}, globbed=False,
609 def overridematch(ctx, pats=[], opts={}, globbed=False,
610 default='relpath'):
610 default='relpath'):
611 match = oldmatch(ctx, pats, opts, globbed, default)
611 match = oldmatch(ctx, pats, opts, globbed, default)
612 m = copy.copy(match)
612 m = copy.copy(match)
613 def tostandin(f):
613 def tostandin(f):
614 if lfutil.standin(f) in ctx:
614 if lfutil.standin(f) in ctx:
615 return lfutil.standin(f)
615 return lfutil.standin(f)
616 elif lfutil.standin(f) in repo[None]:
616 elif lfutil.standin(f) in repo[None]:
617 return None
617 return None
618 return f
618 return f
619 m._files = [tostandin(f) for f in m._files]
619 m._files = [tostandin(f) for f in m._files]
620 m._files = [f for f in m._files if f is not None]
620 m._files = [f for f in m._files if f is not None]
621 m._fmap = set(m._files)
621 m._fmap = set(m._files)
622 origmatchfn = m.matchfn
622 origmatchfn = m.matchfn
623 def matchfn(f):
623 def matchfn(f):
624 if lfutil.isstandin(f):
624 if lfutil.isstandin(f):
625 # We need to keep track of what largefiles are being
625 # We need to keep track of what largefiles are being
626 # matched so we know which ones to update later --
626 # matched so we know which ones to update later --
627 # otherwise we accidentally revert changes to other
627 # otherwise we accidentally revert changes to other
628 # largefiles. This is repo-specific, so duckpunch the
628 # largefiles. This is repo-specific, so duckpunch the
629 # repo object to keep the list of largefiles for us
629 # repo object to keep the list of largefiles for us
630 # later.
630 # later.
631 if origmatchfn(lfutil.splitstandin(f)) and \
631 if origmatchfn(lfutil.splitstandin(f)) and \
632 (f in repo[None] or f in ctx):
632 (f in repo[None] or f in ctx):
633 lfileslist = getattr(repo, '_lfilestoupdate', [])
633 lfileslist = getattr(repo, '_lfilestoupdate', [])
634 lfileslist.append(lfutil.splitstandin(f))
634 lfileslist.append(lfutil.splitstandin(f))
635 repo._lfilestoupdate = lfileslist
635 repo._lfilestoupdate = lfileslist
636 return True
636 return True
637 else:
637 else:
638 return False
638 return False
639 return origmatchfn(f)
639 return origmatchfn(f)
640 m.matchfn = matchfn
640 m.matchfn = matchfn
641 return m
641 return m
642 oldmatch = installmatchfn(overridematch)
642 oldmatch = installmatchfn(overridematch)
643 scmutil.match
643 scmutil.match
644 matches = overridematch(repo[None], pats, opts)
644 matches = overridematch(repo[None], pats, opts)
645 orig(ui, repo, *pats, **opts)
645 orig(ui, repo, *pats, **opts)
646 finally:
646 finally:
647 restorematchfn()
647 restorematchfn()
648 lfileslist = getattr(repo, '_lfilestoupdate', [])
648 lfileslist = getattr(repo, '_lfilestoupdate', [])
649 lfcommands.updatelfiles(ui, repo, filelist=lfileslist,
649 lfcommands.updatelfiles(ui, repo, filelist=lfileslist,
650 printmessage=False)
650 printmessage=False)
651
651
652 # empty out the largefiles list so we start fresh next time
652 # empty out the largefiles list so we start fresh next time
653 repo._lfilestoupdate = []
653 repo._lfilestoupdate = []
654 for lfile in modified:
654 for lfile in modified:
655 if lfile in lfileslist:
655 if lfile in lfileslist:
656 if os.path.exists(repo.wjoin(lfutil.standin(lfile))) and lfile\
656 if os.path.exists(repo.wjoin(lfutil.standin(lfile))) and lfile\
657 in repo['.']:
657 in repo['.']:
658 lfutil.writestandin(repo, lfutil.standin(lfile),
658 lfutil.writestandin(repo, lfutil.standin(lfile),
659 repo['.'][lfile].data().strip(),
659 repo['.'][lfile].data().strip(),
660 'x' in repo['.'][lfile].flags())
660 'x' in repo['.'][lfile].flags())
661 lfdirstate = lfutil.openlfdirstate(ui, repo)
661 lfdirstate = lfutil.openlfdirstate(ui, repo)
662 for lfile in added:
662 for lfile in added:
663 standin = lfutil.standin(lfile)
663 standin = lfutil.standin(lfile)
664 if standin not in ctx and (standin in matches or opts.get('all')):
664 if standin not in ctx and (standin in matches or opts.get('all')):
665 if lfile in lfdirstate:
665 if lfile in lfdirstate:
666 lfdirstate.drop(lfile)
666 lfdirstate.drop(lfile)
667 util.unlinkpath(repo.wjoin(standin))
667 util.unlinkpath(repo.wjoin(standin))
668 lfdirstate.write()
668 lfdirstate.write()
669 finally:
669 finally:
670 wlock.release()
670 wlock.release()
671
671
672 def hgupdate(orig, repo, node):
672 def hgupdaterepo(orig, repo, node, overwrite):
673 # Only call updatelfiles the standins that have changed to save time
673 if not overwrite:
674 oldstandins = lfutil.getstandinsstate(repo)
674 # Only call updatelfiles on the standins that have changed to save time
675 result = orig(repo, node)
675 oldstandins = lfutil.getstandinsstate(repo)
676 newstandins = lfutil.getstandinsstate(repo)
677 filelist = lfutil.getlfilestoupdate(oldstandins, newstandins)
678 lfcommands.updatelfiles(repo.ui, repo, filelist=filelist, printmessage=True)
679 return result
680
676
681 def hgclean(orig, repo, node, show_stats=True):
677 result = orig(repo, node, overwrite)
682 result = orig(repo, node, show_stats)
678
683 lfcommands.updatelfiles(repo.ui, repo)
679 filelist = None
680 if not overwrite:
681 newstandins = lfutil.getstandinsstate(repo)
682 filelist = lfutil.getlfilestoupdate(oldstandins, newstandins)
683 lfcommands.updatelfiles(repo.ui, repo, filelist=filelist)
684 return result
684 return result
685
685
686 def hgmerge(orig, repo, node, force=None, remind=True):
686 def hgmerge(orig, repo, node, force=None, remind=True):
687 # Mark the repo as being in the middle of a merge, so that
687 # Mark the repo as being in the middle of a merge, so that
688 # updatelfiles() will know that it needs to trust the standins in
688 # updatelfiles() will know that it needs to trust the standins in
689 # the working copy, not in the standins in the current node
689 # the working copy, not in the standins in the current node
690 repo._ismerging = True
690 repo._ismerging = True
691 try:
691 try:
692 result = orig(repo, node, force, remind)
692 result = orig(repo, node, force, remind)
693 lfcommands.updatelfiles(repo.ui, repo)
693 lfcommands.updatelfiles(repo.ui, repo)
694 finally:
694 finally:
695 repo._ismerging = False
695 repo._ismerging = False
696 return result
696 return result
697
697
698 # When we rebase a repository with remotely changed largefiles, we need to
698 # When we rebase a repository with remotely changed largefiles, we need to
699 # take some extra care so that the largefiles are correctly updated in the
699 # take some extra care so that the largefiles are correctly updated in the
700 # working copy
700 # working copy
701 def overridepull(orig, ui, repo, source=None, **opts):
701 def overridepull(orig, ui, repo, source=None, **opts):
702 revsprepull = len(repo)
702 revsprepull = len(repo)
703 if opts.get('rebase', False):
703 if opts.get('rebase', False):
704 repo._isrebasing = True
704 repo._isrebasing = True
705 try:
705 try:
706 if opts.get('update'):
706 if opts.get('update'):
707 del opts['update']
707 del opts['update']
708 ui.debug('--update and --rebase are not compatible, ignoring '
708 ui.debug('--update and --rebase are not compatible, ignoring '
709 'the update flag\n')
709 'the update flag\n')
710 del opts['rebase']
710 del opts['rebase']
711 cmdutil.bailifchanged(repo)
711 cmdutil.bailifchanged(repo)
712 origpostincoming = commands.postincoming
712 origpostincoming = commands.postincoming
713 def _dummy(*args, **kwargs):
713 def _dummy(*args, **kwargs):
714 pass
714 pass
715 commands.postincoming = _dummy
715 commands.postincoming = _dummy
716 if not source:
716 if not source:
717 source = 'default'
717 source = 'default'
718 repo.lfpullsource = source
718 repo.lfpullsource = source
719 try:
719 try:
720 result = commands.pull(ui, repo, source, **opts)
720 result = commands.pull(ui, repo, source, **opts)
721 finally:
721 finally:
722 commands.postincoming = origpostincoming
722 commands.postincoming = origpostincoming
723 revspostpull = len(repo)
723 revspostpull = len(repo)
724 if revspostpull > revsprepull:
724 if revspostpull > revsprepull:
725 result = result or rebase.rebase(ui, repo)
725 result = result or rebase.rebase(ui, repo)
726 finally:
726 finally:
727 repo._isrebasing = False
727 repo._isrebasing = False
728 else:
728 else:
729 if not source:
729 if not source:
730 source = 'default'
730 source = 'default'
731 repo.lfpullsource = source
731 repo.lfpullsource = source
732 oldheads = lfutil.getcurrentheads(repo)
732 oldheads = lfutil.getcurrentheads(repo)
733 result = orig(ui, repo, source, **opts)
733 result = orig(ui, repo, source, **opts)
734 # If we do not have the new largefiles for any new heads we pulled, we
734 # If we do not have the new largefiles for any new heads we pulled, we
735 # will run into a problem later if we try to merge or rebase with one of
735 # will run into a problem later if we try to merge or rebase with one of
736 # these heads, so cache the largefiles now directly into the system
736 # these heads, so cache the largefiles now directly into the system
737 # cache.
737 # cache.
738 ui.status(_("caching new largefiles\n"))
738 ui.status(_("caching new largefiles\n"))
739 numcached = 0
739 numcached = 0
740 heads = lfutil.getcurrentheads(repo)
740 heads = lfutil.getcurrentheads(repo)
741 newheads = set(heads).difference(set(oldheads))
741 newheads = set(heads).difference(set(oldheads))
742 for head in newheads:
742 for head in newheads:
743 (cached, missing) = lfcommands.cachelfiles(ui, repo, head)
743 (cached, missing) = lfcommands.cachelfiles(ui, repo, head)
744 numcached += len(cached)
744 numcached += len(cached)
745 ui.status(_("%d largefiles cached\n") % numcached)
745 ui.status(_("%d largefiles cached\n") % numcached)
746 if opts.get('all_largefiles'):
746 if opts.get('all_largefiles'):
747 revspostpull = len(repo)
747 revspostpull = len(repo)
748 revs = []
748 revs = []
749 for rev in xrange(revsprepull + 1, revspostpull):
749 for rev in xrange(revsprepull + 1, revspostpull):
750 revs.append(repo[rev].rev())
750 revs.append(repo[rev].rev())
751 lfcommands.downloadlfiles(ui, repo, revs)
751 lfcommands.downloadlfiles(ui, repo, revs)
752 return result
752 return result
753
753
754 def overrideclone(orig, ui, source, dest=None, **opts):
754 def overrideclone(orig, ui, source, dest=None, **opts):
755 d = dest
755 d = dest
756 if d is None:
756 if d is None:
757 d = hg.defaultdest(source)
757 d = hg.defaultdest(source)
758 if opts.get('all_largefiles') and not hg.islocal(d):
758 if opts.get('all_largefiles') and not hg.islocal(d):
759 raise util.Abort(_(
759 raise util.Abort(_(
760 '--all-largefiles is incompatible with non-local destination %s' %
760 '--all-largefiles is incompatible with non-local destination %s' %
761 d))
761 d))
762
762
763 return orig(ui, source, dest, **opts)
763 return orig(ui, source, dest, **opts)
764
764
765 def hgclone(orig, ui, opts, *args, **kwargs):
765 def hgclone(orig, ui, opts, *args, **kwargs):
766 result = orig(ui, opts, *args, **kwargs)
766 result = orig(ui, opts, *args, **kwargs)
767
767
768 if result is not None:
768 if result is not None:
769 sourcerepo, destrepo = result
769 sourcerepo, destrepo = result
770 repo = destrepo.local()
770 repo = destrepo.local()
771
771
772 # The .hglf directory must exist for the standin matcher to match
772 # The .hglf directory must exist for the standin matcher to match
773 # anything (which listlfiles uses for each rev), and .hg/largefiles is
773 # anything (which listlfiles uses for each rev), and .hg/largefiles is
774 # assumed to exist by the code that caches the downloaded file. These
774 # assumed to exist by the code that caches the downloaded file. These
775 # directories exist if clone updated to any rev. (If the repo does not
775 # directories exist if clone updated to any rev. (If the repo does not
776 # have largefiles, download never gets to the point of needing
776 # have largefiles, download never gets to the point of needing
777 # .hg/largefiles, and the standin matcher won't match anything anyway.)
777 # .hg/largefiles, and the standin matcher won't match anything anyway.)
778 if 'largefiles' in repo.requirements:
778 if 'largefiles' in repo.requirements:
779 if opts.get('noupdate'):
779 if opts.get('noupdate'):
780 util.makedirs(repo.wjoin(lfutil.shortname))
780 util.makedirs(repo.wjoin(lfutil.shortname))
781 util.makedirs(repo.join(lfutil.longname))
781 util.makedirs(repo.join(lfutil.longname))
782
782
783 # Caching is implicitly limited to 'rev' option, since the dest repo was
783 # Caching is implicitly limited to 'rev' option, since the dest repo was
784 # truncated at that point. The user may expect a download count with
784 # truncated at that point. The user may expect a download count with
785 # this option, so attempt whether or not this is a largefile repo.
785 # this option, so attempt whether or not this is a largefile repo.
786 if opts.get('all_largefiles'):
786 if opts.get('all_largefiles'):
787 success, missing = lfcommands.downloadlfiles(ui, repo, None)
787 success, missing = lfcommands.downloadlfiles(ui, repo, None)
788
788
789 if missing != 0:
789 if missing != 0:
790 return None
790 return None
791
791
792 return result
792 return result
793
793
794 def overriderebase(orig, ui, repo, **opts):
794 def overriderebase(orig, ui, repo, **opts):
795 repo._isrebasing = True
795 repo._isrebasing = True
796 try:
796 try:
797 return orig(ui, repo, **opts)
797 return orig(ui, repo, **opts)
798 finally:
798 finally:
799 repo._isrebasing = False
799 repo._isrebasing = False
800
800
801 def overridearchive(orig, repo, dest, node, kind, decode=True, matchfn=None,
801 def overridearchive(orig, repo, dest, node, kind, decode=True, matchfn=None,
802 prefix=None, mtime=None, subrepos=None):
802 prefix=None, mtime=None, subrepos=None):
803 # No need to lock because we are only reading history and
803 # No need to lock because we are only reading history and
804 # largefile caches, neither of which are modified.
804 # largefile caches, neither of which are modified.
805 lfcommands.cachelfiles(repo.ui, repo, node)
805 lfcommands.cachelfiles(repo.ui, repo, node)
806
806
807 if kind not in archival.archivers:
807 if kind not in archival.archivers:
808 raise util.Abort(_("unknown archive type '%s'") % kind)
808 raise util.Abort(_("unknown archive type '%s'") % kind)
809
809
810 ctx = repo[node]
810 ctx = repo[node]
811
811
812 if kind == 'files':
812 if kind == 'files':
813 if prefix:
813 if prefix:
814 raise util.Abort(
814 raise util.Abort(
815 _('cannot give prefix when archiving to files'))
815 _('cannot give prefix when archiving to files'))
816 else:
816 else:
817 prefix = archival.tidyprefix(dest, kind, prefix)
817 prefix = archival.tidyprefix(dest, kind, prefix)
818
818
819 def write(name, mode, islink, getdata):
819 def write(name, mode, islink, getdata):
820 if matchfn and not matchfn(name):
820 if matchfn and not matchfn(name):
821 return
821 return
822 data = getdata()
822 data = getdata()
823 if decode:
823 if decode:
824 data = repo.wwritedata(name, data)
824 data = repo.wwritedata(name, data)
825 archiver.addfile(prefix + name, mode, islink, data)
825 archiver.addfile(prefix + name, mode, islink, data)
826
826
827 archiver = archival.archivers[kind](dest, mtime or ctx.date()[0])
827 archiver = archival.archivers[kind](dest, mtime or ctx.date()[0])
828
828
829 if repo.ui.configbool("ui", "archivemeta", True):
829 if repo.ui.configbool("ui", "archivemeta", True):
830 def metadata():
830 def metadata():
831 base = 'repo: %s\nnode: %s\nbranch: %s\n' % (
831 base = 'repo: %s\nnode: %s\nbranch: %s\n' % (
832 hex(repo.changelog.node(0)), hex(node), ctx.branch())
832 hex(repo.changelog.node(0)), hex(node), ctx.branch())
833
833
834 tags = ''.join('tag: %s\n' % t for t in ctx.tags()
834 tags = ''.join('tag: %s\n' % t for t in ctx.tags()
835 if repo.tagtype(t) == 'global')
835 if repo.tagtype(t) == 'global')
836 if not tags:
836 if not tags:
837 repo.ui.pushbuffer()
837 repo.ui.pushbuffer()
838 opts = {'template': '{latesttag}\n{latesttagdistance}',
838 opts = {'template': '{latesttag}\n{latesttagdistance}',
839 'style': '', 'patch': None, 'git': None}
839 'style': '', 'patch': None, 'git': None}
840 cmdutil.show_changeset(repo.ui, repo, opts).show(ctx)
840 cmdutil.show_changeset(repo.ui, repo, opts).show(ctx)
841 ltags, dist = repo.ui.popbuffer().split('\n')
841 ltags, dist = repo.ui.popbuffer().split('\n')
842 tags = ''.join('latesttag: %s\n' % t for t in ltags.split(':'))
842 tags = ''.join('latesttag: %s\n' % t for t in ltags.split(':'))
843 tags += 'latesttagdistance: %s\n' % dist
843 tags += 'latesttagdistance: %s\n' % dist
844
844
845 return base + tags
845 return base + tags
846
846
847 write('.hg_archival.txt', 0644, False, metadata)
847 write('.hg_archival.txt', 0644, False, metadata)
848
848
849 for f in ctx:
849 for f in ctx:
850 ff = ctx.flags(f)
850 ff = ctx.flags(f)
851 getdata = ctx[f].data
851 getdata = ctx[f].data
852 if lfutil.isstandin(f):
852 if lfutil.isstandin(f):
853 path = lfutil.findfile(repo, getdata().strip())
853 path = lfutil.findfile(repo, getdata().strip())
854 if path is None:
854 if path is None:
855 raise util.Abort(
855 raise util.Abort(
856 _('largefile %s not found in repo store or system cache')
856 _('largefile %s not found in repo store or system cache')
857 % lfutil.splitstandin(f))
857 % lfutil.splitstandin(f))
858 f = lfutil.splitstandin(f)
858 f = lfutil.splitstandin(f)
859
859
860 def getdatafn():
860 def getdatafn():
861 fd = None
861 fd = None
862 try:
862 try:
863 fd = open(path, 'rb')
863 fd = open(path, 'rb')
864 return fd.read()
864 return fd.read()
865 finally:
865 finally:
866 if fd:
866 if fd:
867 fd.close()
867 fd.close()
868
868
869 getdata = getdatafn
869 getdata = getdatafn
870 write(f, 'x' in ff and 0755 or 0644, 'l' in ff, getdata)
870 write(f, 'x' in ff and 0755 or 0644, 'l' in ff, getdata)
871
871
872 if subrepos:
872 if subrepos:
873 for subpath in sorted(ctx.substate):
873 for subpath in sorted(ctx.substate):
874 sub = ctx.sub(subpath)
874 sub = ctx.sub(subpath)
875 submatch = match_.narrowmatcher(subpath, matchfn)
875 submatch = match_.narrowmatcher(subpath, matchfn)
876 sub.archive(repo.ui, archiver, prefix, submatch)
876 sub.archive(repo.ui, archiver, prefix, submatch)
877
877
878 archiver.done()
878 archiver.done()
879
879
880 def hgsubrepoarchive(orig, repo, ui, archiver, prefix, match=None):
880 def hgsubrepoarchive(orig, repo, ui, archiver, prefix, match=None):
881 repo._get(repo._state + ('hg',))
881 repo._get(repo._state + ('hg',))
882 rev = repo._state[1]
882 rev = repo._state[1]
883 ctx = repo._repo[rev]
883 ctx = repo._repo[rev]
884
884
885 lfcommands.cachelfiles(ui, repo._repo, ctx.node())
885 lfcommands.cachelfiles(ui, repo._repo, ctx.node())
886
886
887 def write(name, mode, islink, getdata):
887 def write(name, mode, islink, getdata):
888 # At this point, the standin has been replaced with the largefile name,
888 # At this point, the standin has been replaced with the largefile name,
889 # so the normal matcher works here without the lfutil variants.
889 # so the normal matcher works here without the lfutil variants.
890 if match and not match(f):
890 if match and not match(f):
891 return
891 return
892 data = getdata()
892 data = getdata()
893
893
894 archiver.addfile(prefix + repo._path + '/' + name, mode, islink, data)
894 archiver.addfile(prefix + repo._path + '/' + name, mode, islink, data)
895
895
896 for f in ctx:
896 for f in ctx:
897 ff = ctx.flags(f)
897 ff = ctx.flags(f)
898 getdata = ctx[f].data
898 getdata = ctx[f].data
899 if lfutil.isstandin(f):
899 if lfutil.isstandin(f):
900 path = lfutil.findfile(repo._repo, getdata().strip())
900 path = lfutil.findfile(repo._repo, getdata().strip())
901 if path is None:
901 if path is None:
902 raise util.Abort(
902 raise util.Abort(
903 _('largefile %s not found in repo store or system cache')
903 _('largefile %s not found in repo store or system cache')
904 % lfutil.splitstandin(f))
904 % lfutil.splitstandin(f))
905 f = lfutil.splitstandin(f)
905 f = lfutil.splitstandin(f)
906
906
907 def getdatafn():
907 def getdatafn():
908 fd = None
908 fd = None
909 try:
909 try:
910 fd = open(os.path.join(prefix, path), 'rb')
910 fd = open(os.path.join(prefix, path), 'rb')
911 return fd.read()
911 return fd.read()
912 finally:
912 finally:
913 if fd:
913 if fd:
914 fd.close()
914 fd.close()
915
915
916 getdata = getdatafn
916 getdata = getdatafn
917
917
918 write(f, 'x' in ff and 0755 or 0644, 'l' in ff, getdata)
918 write(f, 'x' in ff and 0755 or 0644, 'l' in ff, getdata)
919
919
920 for subpath in sorted(ctx.substate):
920 for subpath in sorted(ctx.substate):
921 sub = ctx.sub(subpath)
921 sub = ctx.sub(subpath)
922 submatch = match_.narrowmatcher(subpath, match)
922 submatch = match_.narrowmatcher(subpath, match)
923 sub.archive(ui, archiver, os.path.join(prefix, repo._path) + '/',
923 sub.archive(ui, archiver, os.path.join(prefix, repo._path) + '/',
924 submatch)
924 submatch)
925
925
926 # If a largefile is modified, the change is not reflected in its
926 # If a largefile is modified, the change is not reflected in its
927 # standin until a commit. cmdutil.bailifchanged() raises an exception
927 # standin until a commit. cmdutil.bailifchanged() raises an exception
928 # if the repo has uncommitted changes. Wrap it to also check if
928 # if the repo has uncommitted changes. Wrap it to also check if
929 # largefiles were changed. This is used by bisect and backout.
929 # largefiles were changed. This is used by bisect and backout.
930 def overridebailifchanged(orig, repo):
930 def overridebailifchanged(orig, repo):
931 orig(repo)
931 orig(repo)
932 repo.lfstatus = True
932 repo.lfstatus = True
933 modified, added, removed, deleted = repo.status()[:4]
933 modified, added, removed, deleted = repo.status()[:4]
934 repo.lfstatus = False
934 repo.lfstatus = False
935 if modified or added or removed or deleted:
935 if modified or added or removed or deleted:
936 raise util.Abort(_('outstanding uncommitted changes'))
936 raise util.Abort(_('outstanding uncommitted changes'))
937
937
938 # Fetch doesn't use cmdutil.bailifchanged so override it to add the check
938 # Fetch doesn't use cmdutil.bailifchanged so override it to add the check
939 def overridefetch(orig, ui, repo, *pats, **opts):
939 def overridefetch(orig, ui, repo, *pats, **opts):
940 repo.lfstatus = True
940 repo.lfstatus = True
941 modified, added, removed, deleted = repo.status()[:4]
941 modified, added, removed, deleted = repo.status()[:4]
942 repo.lfstatus = False
942 repo.lfstatus = False
943 if modified or added or removed or deleted:
943 if modified or added or removed or deleted:
944 raise util.Abort(_('outstanding uncommitted changes'))
944 raise util.Abort(_('outstanding uncommitted changes'))
945 return orig(ui, repo, *pats, **opts)
945 return orig(ui, repo, *pats, **opts)
946
946
947 def overrideforget(orig, ui, repo, *pats, **opts):
947 def overrideforget(orig, ui, repo, *pats, **opts):
948 installnormalfilesmatchfn(repo[None].manifest())
948 installnormalfilesmatchfn(repo[None].manifest())
949 result = orig(ui, repo, *pats, **opts)
949 result = orig(ui, repo, *pats, **opts)
950 restorematchfn()
950 restorematchfn()
951 m = scmutil.match(repo[None], pats, opts)
951 m = scmutil.match(repo[None], pats, opts)
952
952
953 try:
953 try:
954 repo.lfstatus = True
954 repo.lfstatus = True
955 s = repo.status(match=m, clean=True)
955 s = repo.status(match=m, clean=True)
956 finally:
956 finally:
957 repo.lfstatus = False
957 repo.lfstatus = False
958 forget = sorted(s[0] + s[1] + s[3] + s[6])
958 forget = sorted(s[0] + s[1] + s[3] + s[6])
959 forget = [f for f in forget if lfutil.standin(f) in repo[None].manifest()]
959 forget = [f for f in forget if lfutil.standin(f) in repo[None].manifest()]
960
960
961 for f in forget:
961 for f in forget:
962 if lfutil.standin(f) not in repo.dirstate and not \
962 if lfutil.standin(f) not in repo.dirstate and not \
963 os.path.isdir(m.rel(lfutil.standin(f))):
963 os.path.isdir(m.rel(lfutil.standin(f))):
964 ui.warn(_('not removing %s: file is already untracked\n')
964 ui.warn(_('not removing %s: file is already untracked\n')
965 % m.rel(f))
965 % m.rel(f))
966 result = 1
966 result = 1
967
967
968 for f in forget:
968 for f in forget:
969 if ui.verbose or not m.exact(f):
969 if ui.verbose or not m.exact(f):
970 ui.status(_('removing %s\n') % m.rel(f))
970 ui.status(_('removing %s\n') % m.rel(f))
971
971
972 # Need to lock because standin files are deleted then removed from the
972 # Need to lock because standin files are deleted then removed from the
973 # repository and we could race in-between.
973 # repository and we could race in-between.
974 wlock = repo.wlock()
974 wlock = repo.wlock()
975 try:
975 try:
976 lfdirstate = lfutil.openlfdirstate(ui, repo)
976 lfdirstate = lfutil.openlfdirstate(ui, repo)
977 for f in forget:
977 for f in forget:
978 if lfdirstate[f] == 'a':
978 if lfdirstate[f] == 'a':
979 lfdirstate.drop(f)
979 lfdirstate.drop(f)
980 else:
980 else:
981 lfdirstate.remove(f)
981 lfdirstate.remove(f)
982 lfdirstate.write()
982 lfdirstate.write()
983 standins = [lfutil.standin(f) for f in forget]
983 standins = [lfutil.standin(f) for f in forget]
984 for f in standins:
984 for f in standins:
985 util.unlinkpath(repo.wjoin(f), ignoremissing=True)
985 util.unlinkpath(repo.wjoin(f), ignoremissing=True)
986 repo[None].forget(standins)
986 repo[None].forget(standins)
987 finally:
987 finally:
988 wlock.release()
988 wlock.release()
989
989
990 return result
990 return result
991
991
992 def getoutgoinglfiles(ui, repo, dest=None, **opts):
992 def getoutgoinglfiles(ui, repo, dest=None, **opts):
993 dest = ui.expandpath(dest or 'default-push', dest or 'default')
993 dest = ui.expandpath(dest or 'default-push', dest or 'default')
994 dest, branches = hg.parseurl(dest, opts.get('branch'))
994 dest, branches = hg.parseurl(dest, opts.get('branch'))
995 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
995 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
996 if revs:
996 if revs:
997 revs = [repo.lookup(rev) for rev in scmutil.revrange(repo, revs)]
997 revs = [repo.lookup(rev) for rev in scmutil.revrange(repo, revs)]
998
998
999 try:
999 try:
1000 remote = hg.peer(repo, opts, dest)
1000 remote = hg.peer(repo, opts, dest)
1001 except error.RepoError:
1001 except error.RepoError:
1002 return None
1002 return None
1003 outgoing = discovery.findcommonoutgoing(repo, remote.peer(), force=False)
1003 outgoing = discovery.findcommonoutgoing(repo, remote.peer(), force=False)
1004 if not outgoing.missing:
1004 if not outgoing.missing:
1005 return outgoing.missing
1005 return outgoing.missing
1006 o = repo.changelog.nodesbetween(outgoing.missing, revs)[0]
1006 o = repo.changelog.nodesbetween(outgoing.missing, revs)[0]
1007 if opts.get('newest_first'):
1007 if opts.get('newest_first'):
1008 o.reverse()
1008 o.reverse()
1009
1009
1010 toupload = set()
1010 toupload = set()
1011 for n in o:
1011 for n in o:
1012 parents = [p for p in repo.changelog.parents(n) if p != node.nullid]
1012 parents = [p for p in repo.changelog.parents(n) if p != node.nullid]
1013 ctx = repo[n]
1013 ctx = repo[n]
1014 files = set(ctx.files())
1014 files = set(ctx.files())
1015 if len(parents) == 2:
1015 if len(parents) == 2:
1016 mc = ctx.manifest()
1016 mc = ctx.manifest()
1017 mp1 = ctx.parents()[0].manifest()
1017 mp1 = ctx.parents()[0].manifest()
1018 mp2 = ctx.parents()[1].manifest()
1018 mp2 = ctx.parents()[1].manifest()
1019 for f in mp1:
1019 for f in mp1:
1020 if f not in mc:
1020 if f not in mc:
1021 files.add(f)
1021 files.add(f)
1022 for f in mp2:
1022 for f in mp2:
1023 if f not in mc:
1023 if f not in mc:
1024 files.add(f)
1024 files.add(f)
1025 for f in mc:
1025 for f in mc:
1026 if mc[f] != mp1.get(f, None) or mc[f] != mp2.get(f, None):
1026 if mc[f] != mp1.get(f, None) or mc[f] != mp2.get(f, None):
1027 files.add(f)
1027 files.add(f)
1028 toupload = toupload.union(
1028 toupload = toupload.union(
1029 set([f for f in files if lfutil.isstandin(f) and f in ctx]))
1029 set([f for f in files if lfutil.isstandin(f) and f in ctx]))
1030 return sorted(toupload)
1030 return sorted(toupload)
1031
1031
1032 def overrideoutgoing(orig, ui, repo, dest=None, **opts):
1032 def overrideoutgoing(orig, ui, repo, dest=None, **opts):
1033 result = orig(ui, repo, dest, **opts)
1033 result = orig(ui, repo, dest, **opts)
1034
1034
1035 if opts.pop('large', None):
1035 if opts.pop('large', None):
1036 toupload = getoutgoinglfiles(ui, repo, dest, **opts)
1036 toupload = getoutgoinglfiles(ui, repo, dest, **opts)
1037 if toupload is None:
1037 if toupload is None:
1038 ui.status(_('largefiles: No remote repo\n'))
1038 ui.status(_('largefiles: No remote repo\n'))
1039 elif not toupload:
1039 elif not toupload:
1040 ui.status(_('largefiles: no files to upload\n'))
1040 ui.status(_('largefiles: no files to upload\n'))
1041 else:
1041 else:
1042 ui.status(_('largefiles to upload:\n'))
1042 ui.status(_('largefiles to upload:\n'))
1043 for file in toupload:
1043 for file in toupload:
1044 ui.status(lfutil.splitstandin(file) + '\n')
1044 ui.status(lfutil.splitstandin(file) + '\n')
1045 ui.status('\n')
1045 ui.status('\n')
1046
1046
1047 return result
1047 return result
1048
1048
1049 def overridesummary(orig, ui, repo, *pats, **opts):
1049 def overridesummary(orig, ui, repo, *pats, **opts):
1050 try:
1050 try:
1051 repo.lfstatus = True
1051 repo.lfstatus = True
1052 orig(ui, repo, *pats, **opts)
1052 orig(ui, repo, *pats, **opts)
1053 finally:
1053 finally:
1054 repo.lfstatus = False
1054 repo.lfstatus = False
1055
1055
1056 if opts.pop('large', None):
1056 if opts.pop('large', None):
1057 toupload = getoutgoinglfiles(ui, repo, None, **opts)
1057 toupload = getoutgoinglfiles(ui, repo, None, **opts)
1058 if toupload is None:
1058 if toupload is None:
1059 # i18n: column positioning for "hg summary"
1059 # i18n: column positioning for "hg summary"
1060 ui.status(_('largefiles: (no remote repo)\n'))
1060 ui.status(_('largefiles: (no remote repo)\n'))
1061 elif not toupload:
1061 elif not toupload:
1062 # i18n: column positioning for "hg summary"
1062 # i18n: column positioning for "hg summary"
1063 ui.status(_('largefiles: (no files to upload)\n'))
1063 ui.status(_('largefiles: (no files to upload)\n'))
1064 else:
1064 else:
1065 # i18n: column positioning for "hg summary"
1065 # i18n: column positioning for "hg summary"
1066 ui.status(_('largefiles: %d to upload\n') % len(toupload))
1066 ui.status(_('largefiles: %d to upload\n') % len(toupload))
1067
1067
1068 def scmutiladdremove(orig, repo, pats=[], opts={}, dry_run=None,
1068 def scmutiladdremove(orig, repo, pats=[], opts={}, dry_run=None,
1069 similarity=None):
1069 similarity=None):
1070 if not lfutil.islfilesrepo(repo):
1070 if not lfutil.islfilesrepo(repo):
1071 return orig(repo, pats, opts, dry_run, similarity)
1071 return orig(repo, pats, opts, dry_run, similarity)
1072 # Get the list of missing largefiles so we can remove them
1072 # Get the list of missing largefiles so we can remove them
1073 lfdirstate = lfutil.openlfdirstate(repo.ui, repo)
1073 lfdirstate = lfutil.openlfdirstate(repo.ui, repo)
1074 s = lfdirstate.status(match_.always(repo.root, repo.getcwd()), [], False,
1074 s = lfdirstate.status(match_.always(repo.root, repo.getcwd()), [], False,
1075 False, False)
1075 False, False)
1076 (unsure, modified, added, removed, missing, unknown, ignored, clean) = s
1076 (unsure, modified, added, removed, missing, unknown, ignored, clean) = s
1077
1077
1078 # Call into the normal remove code, but the removing of the standin, we want
1078 # Call into the normal remove code, but the removing of the standin, we want
1079 # to have handled by original addremove. Monkey patching here makes sure
1079 # to have handled by original addremove. Monkey patching here makes sure
1080 # we don't remove the standin in the largefiles code, preventing a very
1080 # we don't remove the standin in the largefiles code, preventing a very
1081 # confused state later.
1081 # confused state later.
1082 if missing:
1082 if missing:
1083 m = [repo.wjoin(f) for f in missing]
1083 m = [repo.wjoin(f) for f in missing]
1084 repo._isaddremove = True
1084 repo._isaddremove = True
1085 removelargefiles(repo.ui, repo, *m, **opts)
1085 removelargefiles(repo.ui, repo, *m, **opts)
1086 repo._isaddremove = False
1086 repo._isaddremove = False
1087 # Call into the normal add code, and any files that *should* be added as
1087 # Call into the normal add code, and any files that *should* be added as
1088 # largefiles will be
1088 # largefiles will be
1089 addlargefiles(repo.ui, repo, *pats, **opts)
1089 addlargefiles(repo.ui, repo, *pats, **opts)
1090 # Now that we've handled largefiles, hand off to the original addremove
1090 # Now that we've handled largefiles, hand off to the original addremove
1091 # function to take care of the rest. Make sure it doesn't do anything with
1091 # function to take care of the rest. Make sure it doesn't do anything with
1092 # largefiles by installing a matcher that will ignore them.
1092 # largefiles by installing a matcher that will ignore them.
1093 installnormalfilesmatchfn(repo[None].manifest())
1093 installnormalfilesmatchfn(repo[None].manifest())
1094 result = orig(repo, pats, opts, dry_run, similarity)
1094 result = orig(repo, pats, opts, dry_run, similarity)
1095 restorematchfn()
1095 restorematchfn()
1096 return result
1096 return result
1097
1097
1098 # Calling purge with --all will cause the largefiles to be deleted.
1098 # Calling purge with --all will cause the largefiles to be deleted.
1099 # Override repo.status to prevent this from happening.
1099 # Override repo.status to prevent this from happening.
1100 def overridepurge(orig, ui, repo, *dirs, **opts):
1100 def overridepurge(orig, ui, repo, *dirs, **opts):
1101 # XXX large file status is buggy when used on repo proxy.
1101 # XXX large file status is buggy when used on repo proxy.
1102 # XXX this needs to be investigate.
1102 # XXX this needs to be investigate.
1103 repo = repo.unfiltered()
1103 repo = repo.unfiltered()
1104 oldstatus = repo.status
1104 oldstatus = repo.status
1105 def overridestatus(node1='.', node2=None, match=None, ignored=False,
1105 def overridestatus(node1='.', node2=None, match=None, ignored=False,
1106 clean=False, unknown=False, listsubrepos=False):
1106 clean=False, unknown=False, listsubrepos=False):
1107 r = oldstatus(node1, node2, match, ignored, clean, unknown,
1107 r = oldstatus(node1, node2, match, ignored, clean, unknown,
1108 listsubrepos)
1108 listsubrepos)
1109 lfdirstate = lfutil.openlfdirstate(ui, repo)
1109 lfdirstate = lfutil.openlfdirstate(ui, repo)
1110 modified, added, removed, deleted, unknown, ignored, clean = r
1110 modified, added, removed, deleted, unknown, ignored, clean = r
1111 unknown = [f for f in unknown if lfdirstate[f] == '?']
1111 unknown = [f for f in unknown if lfdirstate[f] == '?']
1112 ignored = [f for f in ignored if lfdirstate[f] == '?']
1112 ignored = [f for f in ignored if lfdirstate[f] == '?']
1113 return modified, added, removed, deleted, unknown, ignored, clean
1113 return modified, added, removed, deleted, unknown, ignored, clean
1114 repo.status = overridestatus
1114 repo.status = overridestatus
1115 orig(ui, repo, *dirs, **opts)
1115 orig(ui, repo, *dirs, **opts)
1116 repo.status = oldstatus
1116 repo.status = oldstatus
1117
1117
1118 def overriderollback(orig, ui, repo, **opts):
1118 def overriderollback(orig, ui, repo, **opts):
1119 result = orig(ui, repo, **opts)
1119 result = orig(ui, repo, **opts)
1120 merge.update(repo, node=None, branchmerge=False, force=True,
1120 merge.update(repo, node=None, branchmerge=False, force=True,
1121 partial=lfutil.isstandin)
1121 partial=lfutil.isstandin)
1122 wlock = repo.wlock()
1122 wlock = repo.wlock()
1123 try:
1123 try:
1124 lfdirstate = lfutil.openlfdirstate(ui, repo)
1124 lfdirstate = lfutil.openlfdirstate(ui, repo)
1125 lfiles = lfutil.listlfiles(repo)
1125 lfiles = lfutil.listlfiles(repo)
1126 oldlfiles = lfutil.listlfiles(repo, repo[None].parents()[0].rev())
1126 oldlfiles = lfutil.listlfiles(repo, repo[None].parents()[0].rev())
1127 for file in lfiles:
1127 for file in lfiles:
1128 if file in oldlfiles:
1128 if file in oldlfiles:
1129 lfdirstate.normallookup(file)
1129 lfdirstate.normallookup(file)
1130 else:
1130 else:
1131 lfdirstate.add(file)
1131 lfdirstate.add(file)
1132 lfdirstate.write()
1132 lfdirstate.write()
1133 finally:
1133 finally:
1134 wlock.release()
1134 wlock.release()
1135 return result
1135 return result
1136
1136
1137 def overridetransplant(orig, ui, repo, *revs, **opts):
1137 def overridetransplant(orig, ui, repo, *revs, **opts):
1138 try:
1138 try:
1139 oldstandins = lfutil.getstandinsstate(repo)
1139 oldstandins = lfutil.getstandinsstate(repo)
1140 repo._istransplanting = True
1140 repo._istransplanting = True
1141 result = orig(ui, repo, *revs, **opts)
1141 result = orig(ui, repo, *revs, **opts)
1142 newstandins = lfutil.getstandinsstate(repo)
1142 newstandins = lfutil.getstandinsstate(repo)
1143 filelist = lfutil.getlfilestoupdate(oldstandins, newstandins)
1143 filelist = lfutil.getlfilestoupdate(oldstandins, newstandins)
1144 lfcommands.updatelfiles(repo.ui, repo, filelist=filelist,
1144 lfcommands.updatelfiles(repo.ui, repo, filelist=filelist,
1145 printmessage=True)
1145 printmessage=True)
1146 finally:
1146 finally:
1147 repo._istransplanting = False
1147 repo._istransplanting = False
1148 return result
1148 return result
1149
1149
1150 def overridecat(orig, ui, repo, file1, *pats, **opts):
1150 def overridecat(orig, ui, repo, file1, *pats, **opts):
1151 ctx = scmutil.revsingle(repo, opts.get('rev'))
1151 ctx = scmutil.revsingle(repo, opts.get('rev'))
1152 if not lfutil.standin(file1) in ctx:
1152 if not lfutil.standin(file1) in ctx:
1153 result = orig(ui, repo, file1, *pats, **opts)
1153 result = orig(ui, repo, file1, *pats, **opts)
1154 return result
1154 return result
1155 return lfcommands.catlfile(repo, file1, ctx.rev(), opts.get('output'))
1155 return lfcommands.catlfile(repo, file1, ctx.rev(), opts.get('output'))
1156
1156
1157 def mercurialsinkbefore(orig, sink):
1157 def mercurialsinkbefore(orig, sink):
1158 sink.repo._isconverting = True
1158 sink.repo._isconverting = True
1159 orig(sink)
1159 orig(sink)
1160
1160
1161 def mercurialsinkafter(orig, sink):
1161 def mercurialsinkafter(orig, sink):
1162 sink.repo._isconverting = False
1162 sink.repo._isconverting = False
1163 orig(sink)
1163 orig(sink)
@@ -1,177 +1,173 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 '''setup for largefiles extension: uisetup'''
9 '''setup for largefiles extension: uisetup'''
10
10
11 from mercurial import archival, cmdutil, commands, extensions, filemerge, hg, \
11 from mercurial import archival, cmdutil, commands, extensions, filemerge, hg, \
12 httppeer, localrepo, merge, scmutil, sshpeer, wireproto
12 httppeer, localrepo, merge, scmutil, sshpeer, wireproto
13 from mercurial.i18n import _
13 from mercurial.i18n import _
14 from mercurial.hgweb import hgweb_mod, webcommands
14 from mercurial.hgweb import hgweb_mod, webcommands
15 from mercurial.subrepo import hgsubrepo
15 from mercurial.subrepo import hgsubrepo
16
16
17 import overrides
17 import overrides
18 import proto
18 import proto
19
19
20 def uisetup(ui):
20 def uisetup(ui):
21 # Disable auto-status for some commands which assume that all
21 # Disable auto-status for some commands which assume that all
22 # files in the result are under Mercurial's control
22 # files in the result are under Mercurial's control
23
23
24 entry = extensions.wrapcommand(commands.table, 'add',
24 entry = extensions.wrapcommand(commands.table, 'add',
25 overrides.overrideadd)
25 overrides.overrideadd)
26 addopt = [('', 'large', None, _('add as largefile')),
26 addopt = [('', 'large', None, _('add as largefile')),
27 ('', 'normal', None, _('add as normal file')),
27 ('', 'normal', None, _('add as normal file')),
28 ('', 'lfsize', '', _('add all files above this size '
28 ('', 'lfsize', '', _('add all files above this size '
29 '(in megabytes) as largefiles '
29 '(in megabytes) as largefiles '
30 '(default: 10)'))]
30 '(default: 10)'))]
31 entry[1].extend(addopt)
31 entry[1].extend(addopt)
32
32
33 # The scmutil function is called both by the (trivial) addremove command,
33 # The scmutil function is called both by the (trivial) addremove command,
34 # and in the process of handling commit -A (issue3542)
34 # and in the process of handling commit -A (issue3542)
35 entry = extensions.wrapfunction(scmutil, 'addremove',
35 entry = extensions.wrapfunction(scmutil, 'addremove',
36 overrides.scmutiladdremove)
36 overrides.scmutiladdremove)
37 entry = extensions.wrapcommand(commands.table, 'remove',
37 entry = extensions.wrapcommand(commands.table, 'remove',
38 overrides.overrideremove)
38 overrides.overrideremove)
39 entry = extensions.wrapcommand(commands.table, 'forget',
39 entry = extensions.wrapcommand(commands.table, 'forget',
40 overrides.overrideforget)
40 overrides.overrideforget)
41
41
42 # Subrepos call status function
42 # Subrepos call status function
43 entry = extensions.wrapcommand(commands.table, 'status',
43 entry = extensions.wrapcommand(commands.table, 'status',
44 overrides.overridestatus)
44 overrides.overridestatus)
45 entry = extensions.wrapfunction(hgsubrepo, 'status',
45 entry = extensions.wrapfunction(hgsubrepo, 'status',
46 overrides.overridestatusfn)
46 overrides.overridestatusfn)
47
47
48 entry = extensions.wrapcommand(commands.table, 'log',
48 entry = extensions.wrapcommand(commands.table, 'log',
49 overrides.overridelog)
49 overrides.overridelog)
50 entry = extensions.wrapcommand(commands.table, 'rollback',
50 entry = extensions.wrapcommand(commands.table, 'rollback',
51 overrides.overriderollback)
51 overrides.overriderollback)
52 entry = extensions.wrapcommand(commands.table, 'verify',
52 entry = extensions.wrapcommand(commands.table, 'verify',
53 overrides.overrideverify)
53 overrides.overrideverify)
54
54
55 verifyopt = [('', 'large', None, _('verify largefiles')),
55 verifyopt = [('', 'large', None, _('verify largefiles')),
56 ('', 'lfa', None,
56 ('', 'lfa', None,
57 _('verify all revisions of largefiles not just current')),
57 _('verify all revisions of largefiles not just current')),
58 ('', 'lfc', None,
58 ('', 'lfc', None,
59 _('verify largefile contents not just existence'))]
59 _('verify largefile contents not just existence'))]
60 entry[1].extend(verifyopt)
60 entry[1].extend(verifyopt)
61
61
62 entry = extensions.wrapcommand(commands.table, 'debugstate',
62 entry = extensions.wrapcommand(commands.table, 'debugstate',
63 overrides.overridedebugstate)
63 overrides.overridedebugstate)
64 debugstateopt = [('', 'large', None, _('display largefiles dirstate'))]
64 debugstateopt = [('', 'large', None, _('display largefiles dirstate'))]
65 entry[1].extend(debugstateopt)
65 entry[1].extend(debugstateopt)
66
66
67 entry = extensions.wrapcommand(commands.table, 'outgoing',
67 entry = extensions.wrapcommand(commands.table, 'outgoing',
68 overrides.overrideoutgoing)
68 overrides.overrideoutgoing)
69 outgoingopt = [('', 'large', None, _('display outgoing largefiles'))]
69 outgoingopt = [('', 'large', None, _('display outgoing largefiles'))]
70 entry[1].extend(outgoingopt)
70 entry[1].extend(outgoingopt)
71 entry = extensions.wrapcommand(commands.table, 'summary',
71 entry = extensions.wrapcommand(commands.table, 'summary',
72 overrides.overridesummary)
72 overrides.overridesummary)
73 summaryopt = [('', 'large', None, _('display outgoing largefiles'))]
73 summaryopt = [('', 'large', None, _('display outgoing largefiles'))]
74 entry[1].extend(summaryopt)
74 entry[1].extend(summaryopt)
75
75
76 entry = extensions.wrapcommand(commands.table, 'update',
76 entry = extensions.wrapcommand(commands.table, 'update',
77 overrides.overrideupdate)
77 overrides.overrideupdate)
78 entry = extensions.wrapcommand(commands.table, 'pull',
78 entry = extensions.wrapcommand(commands.table, 'pull',
79 overrides.overridepull)
79 overrides.overridepull)
80 pullopt = [('', 'all-largefiles', None,
80 pullopt = [('', 'all-largefiles', None,
81 _('download all pulled versions of largefiles'))]
81 _('download all pulled versions of largefiles'))]
82 entry[1].extend(pullopt)
82 entry[1].extend(pullopt)
83 entry = extensions.wrapcommand(commands.table, 'clone',
83 entry = extensions.wrapcommand(commands.table, 'clone',
84 overrides.overrideclone)
84 overrides.overrideclone)
85 cloneopt = [('', 'all-largefiles', None,
85 cloneopt = [('', 'all-largefiles', None,
86 _('download all versions of all largefiles'))]
86 _('download all versions of all largefiles'))]
87 entry[1].extend(cloneopt)
87 entry[1].extend(cloneopt)
88 entry = extensions.wrapfunction(hg, 'clone', overrides.hgclone)
88 entry = extensions.wrapfunction(hg, 'clone', overrides.hgclone)
89
89
90 entry = extensions.wrapcommand(commands.table, 'cat',
90 entry = extensions.wrapcommand(commands.table, 'cat',
91 overrides.overridecat)
91 overrides.overridecat)
92 entry = extensions.wrapfunction(merge, '_checkunknownfile',
92 entry = extensions.wrapfunction(merge, '_checkunknownfile',
93 overrides.overridecheckunknownfile)
93 overrides.overridecheckunknownfile)
94 entry = extensions.wrapfunction(merge, 'manifestmerge',
94 entry = extensions.wrapfunction(merge, 'manifestmerge',
95 overrides.overridemanifestmerge)
95 overrides.overridemanifestmerge)
96 entry = extensions.wrapfunction(filemerge, 'filemerge',
96 entry = extensions.wrapfunction(filemerge, 'filemerge',
97 overrides.overridefilemerge)
97 overrides.overridefilemerge)
98 entry = extensions.wrapfunction(cmdutil, 'copy',
98 entry = extensions.wrapfunction(cmdutil, 'copy',
99 overrides.overridecopy)
99 overrides.overridecopy)
100
100
101 # Summary calls dirty on the subrepos
101 # Summary calls dirty on the subrepos
102 entry = extensions.wrapfunction(hgsubrepo, 'dirty',
102 entry = extensions.wrapfunction(hgsubrepo, 'dirty',
103 overrides.overridedirty)
103 overrides.overridedirty)
104
104
105 # Backout calls revert so we need to override both the command and the
105 # Backout calls revert so we need to override both the command and the
106 # function
106 # function
107 entry = extensions.wrapcommand(commands.table, 'revert',
107 entry = extensions.wrapcommand(commands.table, 'revert',
108 overrides.overriderevert)
108 overrides.overriderevert)
109 entry = extensions.wrapfunction(commands, 'revert',
109 entry = extensions.wrapfunction(commands, 'revert',
110 overrides.overriderevert)
110 overrides.overriderevert)
111
111
112 # clone uses hg._update instead of hg.update even though they are the
112 extensions.wrapfunction(hg, 'updaterepo', overrides.hgupdaterepo)
113 # same function... so wrap both of them)
114 extensions.wrapfunction(hg, 'update', overrides.hgupdate)
115 extensions.wrapfunction(hg, '_update', overrides.hgupdate)
116 extensions.wrapfunction(hg, 'clean', overrides.hgclean)
117 extensions.wrapfunction(hg, 'merge', overrides.hgmerge)
113 extensions.wrapfunction(hg, 'merge', overrides.hgmerge)
118
114
119 extensions.wrapfunction(archival, 'archive', overrides.overridearchive)
115 extensions.wrapfunction(archival, 'archive', overrides.overridearchive)
120 extensions.wrapfunction(hgsubrepo, 'archive', overrides.hgsubrepoarchive)
116 extensions.wrapfunction(hgsubrepo, 'archive', overrides.hgsubrepoarchive)
121 extensions.wrapfunction(cmdutil, 'bailifchanged',
117 extensions.wrapfunction(cmdutil, 'bailifchanged',
122 overrides.overridebailifchanged)
118 overrides.overridebailifchanged)
123
119
124 # create the new wireproto commands ...
120 # create the new wireproto commands ...
125 wireproto.commands['putlfile'] = (proto.putlfile, 'sha')
121 wireproto.commands['putlfile'] = (proto.putlfile, 'sha')
126 wireproto.commands['getlfile'] = (proto.getlfile, 'sha')
122 wireproto.commands['getlfile'] = (proto.getlfile, 'sha')
127 wireproto.commands['statlfile'] = (proto.statlfile, 'sha')
123 wireproto.commands['statlfile'] = (proto.statlfile, 'sha')
128
124
129 # ... and wrap some existing ones
125 # ... and wrap some existing ones
130 wireproto.commands['capabilities'] = (proto.capabilities, '')
126 wireproto.commands['capabilities'] = (proto.capabilities, '')
131 wireproto.commands['heads'] = (proto.heads, '')
127 wireproto.commands['heads'] = (proto.heads, '')
132 wireproto.commands['lheads'] = (wireproto.heads, '')
128 wireproto.commands['lheads'] = (wireproto.heads, '')
133
129
134 # make putlfile behave the same as push and {get,stat}lfile behave
130 # make putlfile behave the same as push and {get,stat}lfile behave
135 # the same as pull w.r.t. permissions checks
131 # the same as pull w.r.t. permissions checks
136 hgweb_mod.perms['putlfile'] = 'push'
132 hgweb_mod.perms['putlfile'] = 'push'
137 hgweb_mod.perms['getlfile'] = 'pull'
133 hgweb_mod.perms['getlfile'] = 'pull'
138 hgweb_mod.perms['statlfile'] = 'pull'
134 hgweb_mod.perms['statlfile'] = 'pull'
139
135
140 extensions.wrapfunction(webcommands, 'decodepath', overrides.decodepath)
136 extensions.wrapfunction(webcommands, 'decodepath', overrides.decodepath)
141
137
142 # the hello wireproto command uses wireproto.capabilities, so it won't see
138 # the hello wireproto command uses wireproto.capabilities, so it won't see
143 # our largefiles capability unless we replace the actual function as well.
139 # our largefiles capability unless we replace the actual function as well.
144 proto.capabilitiesorig = wireproto.capabilities
140 proto.capabilitiesorig = wireproto.capabilities
145 wireproto.capabilities = proto.capabilities
141 wireproto.capabilities = proto.capabilities
146
142
147 # can't do this in reposetup because it needs to have happened before
143 # can't do this in reposetup because it needs to have happened before
148 # wirerepo.__init__ is called
144 # wirerepo.__init__ is called
149 proto.ssholdcallstream = sshpeer.sshpeer._callstream
145 proto.ssholdcallstream = sshpeer.sshpeer._callstream
150 proto.httpoldcallstream = httppeer.httppeer._callstream
146 proto.httpoldcallstream = httppeer.httppeer._callstream
151 sshpeer.sshpeer._callstream = proto.sshrepocallstream
147 sshpeer.sshpeer._callstream = proto.sshrepocallstream
152 httppeer.httppeer._callstream = proto.httprepocallstream
148 httppeer.httppeer._callstream = proto.httprepocallstream
153
149
154 # don't die on seeing a repo with the largefiles requirement
150 # don't die on seeing a repo with the largefiles requirement
155 localrepo.localrepository.supported |= set(['largefiles'])
151 localrepo.localrepository.supported |= set(['largefiles'])
156
152
157 # override some extensions' stuff as well
153 # override some extensions' stuff as well
158 for name, module in extensions.extensions():
154 for name, module in extensions.extensions():
159 if name == 'fetch':
155 if name == 'fetch':
160 extensions.wrapcommand(getattr(module, 'cmdtable'), 'fetch',
156 extensions.wrapcommand(getattr(module, 'cmdtable'), 'fetch',
161 overrides.overridefetch)
157 overrides.overridefetch)
162 if name == 'purge':
158 if name == 'purge':
163 extensions.wrapcommand(getattr(module, 'cmdtable'), 'purge',
159 extensions.wrapcommand(getattr(module, 'cmdtable'), 'purge',
164 overrides.overridepurge)
160 overrides.overridepurge)
165 if name == 'rebase':
161 if name == 'rebase':
166 extensions.wrapcommand(getattr(module, 'cmdtable'), 'rebase',
162 extensions.wrapcommand(getattr(module, 'cmdtable'), 'rebase',
167 overrides.overriderebase)
163 overrides.overriderebase)
168 if name == 'transplant':
164 if name == 'transplant':
169 extensions.wrapcommand(getattr(module, 'cmdtable'), 'transplant',
165 extensions.wrapcommand(getattr(module, 'cmdtable'), 'transplant',
170 overrides.overridetransplant)
166 overrides.overridetransplant)
171 if name == 'convert':
167 if name == 'convert':
172 convcmd = getattr(module, 'convcmd')
168 convcmd = getattr(module, 'convcmd')
173 hgsink = getattr(convcmd, 'mercurial_sink')
169 hgsink = getattr(convcmd, 'mercurial_sink')
174 extensions.wrapfunction(hgsink, 'before',
170 extensions.wrapfunction(hgsink, 'before',
175 overrides.mercurialsinkbefore)
171 overrides.mercurialsinkbefore)
176 extensions.wrapfunction(hgsink, 'after',
172 extensions.wrapfunction(hgsink, 'after',
177 overrides.mercurialsinkafter)
173 overrides.mercurialsinkafter)
@@ -1,110 +1,110 b''
1
1
2 $ echo "[extensions]" >> $HGRCPATH
2 $ echo "[extensions]" >> $HGRCPATH
3 $ echo "largefiles =" >> $HGRCPATH
3 $ echo "largefiles =" >> $HGRCPATH
4
4
5 Create the repository outside $HOME since largefiles write to
5 Create the repository outside $HOME since largefiles write to
6 $HOME/.cache/largefiles.
6 $HOME/.cache/largefiles.
7
7
8 $ hg init test
8 $ hg init test
9 $ cd test
9 $ cd test
10 $ echo "root" > root
10 $ echo "root" > root
11 $ hg add root
11 $ hg add root
12 $ hg commit -m "Root commit"
12 $ hg commit -m "Root commit"
13
13
14 $ echo "large" > foo
14 $ echo "large" > foo
15 $ hg add --large foo
15 $ hg add --large foo
16 $ hg commit -m "Add foo as a largefile"
16 $ hg commit -m "Add foo as a largefile"
17
17
18 $ hg update -r 0
18 $ hg update -r 0
19 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
20 getting changed largefiles
19 getting changed largefiles
21 0 largefiles updated, 1 removed
20 0 largefiles updated, 1 removed
21 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
22
22
23 $ echo "normal" > foo
23 $ echo "normal" > foo
24 $ hg add foo
24 $ hg add foo
25 $ hg commit -m "Add foo as normal file"
25 $ hg commit -m "Add foo as normal file"
26 created new head
26 created new head
27
27
28 Normal file in the working copy, keeping the normal version:
28 Normal file in the working copy, keeping the normal version:
29
29
30 $ echo "n" | hg merge --config ui.interactive=Yes
30 $ echo "n" | hg merge --config ui.interactive=Yes
31 foo has been turned into a largefile
31 foo has been turned into a largefile
32 use (l)argefile or keep as (n)ormal file? 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
32 use (l)argefile or keep as (n)ormal file? 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
33 (branch merge, don't forget to commit)
33 (branch merge, don't forget to commit)
34
34
35 $ hg status
35 $ hg status
36 $ cat foo
36 $ cat foo
37 normal
37 normal
38
38
39 Normal file in the working copy, keeping the largefile version:
39 Normal file in the working copy, keeping the largefile version:
40
40
41 $ hg update -q -C
41 $ hg update -q -C
42 $ echo "l" | hg merge --config ui.interactive=Yes
42 $ echo "l" | hg merge --config ui.interactive=Yes
43 foo has been turned into a largefile
43 foo has been turned into a largefile
44 use (l)argefile or keep as (n)ormal file? 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
44 use (l)argefile or keep as (n)ormal file? 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
45 (branch merge, don't forget to commit)
45 (branch merge, don't forget to commit)
46 getting changed largefiles
46 getting changed largefiles
47 1 largefiles updated, 0 removed
47 1 largefiles updated, 0 removed
48
48
49 $ hg status
49 $ hg status
50 M foo
50 M foo
51
51
52 $ hg diff --nodates
52 $ hg diff --nodates
53 diff -r fa129ab6b5a7 .hglf/foo
53 diff -r fa129ab6b5a7 .hglf/foo
54 --- /dev/null
54 --- /dev/null
55 +++ b/.hglf/foo
55 +++ b/.hglf/foo
56 @@ -0,0 +1,1 @@
56 @@ -0,0 +1,1 @@
57 +7f7097b041ccf68cc5561e9600da4655d21c6d18
57 +7f7097b041ccf68cc5561e9600da4655d21c6d18
58 diff -r fa129ab6b5a7 foo
58 diff -r fa129ab6b5a7 foo
59 --- a/foo
59 --- a/foo
60 +++ /dev/null
60 +++ /dev/null
61 @@ -1,1 +0,0 @@
61 @@ -1,1 +0,0 @@
62 -normal
62 -normal
63
63
64 $ cat foo
64 $ cat foo
65 large
65 large
66
66
67 Largefile in the working copy, keeping the normal version:
67 Largefile in the working copy, keeping the normal version:
68
68
69 $ hg update -q -C -r 1
69 $ hg update -q -C -r 1
70 $ echo "n" | hg merge --config ui.interactive=Yes
70 $ echo "n" | hg merge --config ui.interactive=Yes
71 foo has been turned into a normal file
71 foo has been turned into a normal file
72 keep as (l)argefile or use (n)ormal file? 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
72 keep as (l)argefile or use (n)ormal file? 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
73 (branch merge, don't forget to commit)
73 (branch merge, don't forget to commit)
74 getting changed largefiles
74 getting changed largefiles
75 0 largefiles updated, 0 removed
75 0 largefiles updated, 0 removed
76
76
77 $ hg status
77 $ hg status
78 M foo
78 M foo
79
79
80 $ hg diff --nodates
80 $ hg diff --nodates
81 diff -r ff521236428a .hglf/foo
81 diff -r ff521236428a .hglf/foo
82 --- a/.hglf/foo
82 --- a/.hglf/foo
83 +++ /dev/null
83 +++ /dev/null
84 @@ -1,1 +0,0 @@
84 @@ -1,1 +0,0 @@
85 -7f7097b041ccf68cc5561e9600da4655d21c6d18
85 -7f7097b041ccf68cc5561e9600da4655d21c6d18
86 diff -r ff521236428a foo
86 diff -r ff521236428a foo
87 --- /dev/null
87 --- /dev/null
88 +++ b/foo
88 +++ b/foo
89 @@ -0,0 +1,1 @@
89 @@ -0,0 +1,1 @@
90 +normal
90 +normal
91
91
92 $ cat foo
92 $ cat foo
93 normal
93 normal
94
94
95 Largefile in the working copy, keeping the largefile version:
95 Largefile in the working copy, keeping the largefile version:
96
96
97 $ hg update -q -C -r 1
97 $ hg update -q -C -r 1
98 $ echo "l" | hg merge --config ui.interactive=Yes
98 $ echo "l" | hg merge --config ui.interactive=Yes
99 foo has been turned into a normal file
99 foo has been turned into a normal file
100 keep as (l)argefile or use (n)ormal file? 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
100 keep as (l)argefile or use (n)ormal file? 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
101 (branch merge, don't forget to commit)
101 (branch merge, don't forget to commit)
102 getting changed largefiles
102 getting changed largefiles
103 1 largefiles updated, 0 removed
103 1 largefiles updated, 0 removed
104
104
105 $ hg status
105 $ hg status
106
106
107 $ cat foo
107 $ cat foo
108 large
108 large
109
109
110 $ cd ..
110 $ cd ..
@@ -1,123 +1,123 b''
1 Create user cache directory
1 Create user cache directory
2
2
3 $ USERCACHE=`pwd`/cache; export USERCACHE
3 $ USERCACHE=`pwd`/cache; export USERCACHE
4 $ cat <<EOF >> ${HGRCPATH}
4 $ cat <<EOF >> ${HGRCPATH}
5 > [extensions]
5 > [extensions]
6 > hgext.largefiles=
6 > hgext.largefiles=
7 > [largefiles]
7 > [largefiles]
8 > usercache=${USERCACHE}
8 > usercache=${USERCACHE}
9 > EOF
9 > EOF
10 $ mkdir -p ${USERCACHE}
10 $ mkdir -p ${USERCACHE}
11
11
12 Create source repo, and commit adding largefile.
12 Create source repo, and commit adding largefile.
13
13
14 $ hg init src
14 $ hg init src
15 $ cd src
15 $ cd src
16 $ echo large > large
16 $ echo large > large
17 $ hg add --large large
17 $ hg add --large large
18 $ hg commit -m 'add largefile'
18 $ hg commit -m 'add largefile'
19 $ cd ..
19 $ cd ..
20
20
21 Discard all cached largefiles in USERCACHE
21 Discard all cached largefiles in USERCACHE
22
22
23 $ rm -rf ${USERCACHE}
23 $ rm -rf ${USERCACHE}
24
24
25 Create mirror repo, and pull from source without largefile:
25 Create mirror repo, and pull from source without largefile:
26 "pull" is used instead of "clone" for suppression of (1) updating to
26 "pull" is used instead of "clone" for suppression of (1) updating to
27 tip (= cahcing largefile from source repo), and (2) recording source
27 tip (= cahcing largefile from source repo), and (2) recording source
28 repo as "default" path in .hg/hgrc.
28 repo as "default" path in .hg/hgrc.
29
29
30 $ hg init mirror
30 $ hg init mirror
31 $ cd mirror
31 $ cd mirror
32 $ hg pull ../src
32 $ hg pull ../src
33 pulling from ../src
33 pulling from ../src
34 requesting all changes
34 requesting all changes
35 adding changesets
35 adding changesets
36 adding manifests
36 adding manifests
37 adding file changes
37 adding file changes
38 added 1 changesets with 1 changes to 1 files
38 added 1 changesets with 1 changes to 1 files
39 (run 'hg update' to get a working copy)
39 (run 'hg update' to get a working copy)
40 caching new largefiles
40 caching new largefiles
41 0 largefiles cached
41 0 largefiles cached
42
42
43 Update working directory to "tip", which requires largefile("large"),
43 Update working directory to "tip", which requires largefile("large"),
44 but there is no cache file for it. So, hg must treat it as
44 but there is no cache file for it. So, hg must treat it as
45 "missing"(!) file.
45 "missing"(!) file.
46
46
47 $ hg update
47 $ hg update
48 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
49 getting changed largefiles
48 getting changed largefiles
50 error getting 7f7097b041ccf68cc5561e9600da4655d21c6d18 from file:$TESTTMP/mirror for large: can't get file locally (glob)
49 error getting 7f7097b041ccf68cc5561e9600da4655d21c6d18 from file:$TESTTMP/mirror for large: can't get file locally (glob)
51 0 largefiles updated, 0 removed
50 0 largefiles updated, 0 removed
51 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
52 $ hg status
52 $ hg status
53 ! large
53 ! large
54
54
55 Update working directory to null: this cleanup .hg/largefiles/dirstate
55 Update working directory to null: this cleanup .hg/largefiles/dirstate
56
56
57 $ hg update null
57 $ hg update null
58 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
59 getting changed largefiles
58 getting changed largefiles
60 0 largefiles updated, 0 removed
59 0 largefiles updated, 0 removed
60 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
61
61
62 Update working directory to tip, again.
62 Update working directory to tip, again.
63
63
64 $ hg update
64 $ hg update
65 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
66 getting changed largefiles
65 getting changed largefiles
67 error getting 7f7097b041ccf68cc5561e9600da4655d21c6d18 from file:$TESTTMP/mirror for large: can't get file locally (glob)
66 error getting 7f7097b041ccf68cc5561e9600da4655d21c6d18 from file:$TESTTMP/mirror for large: can't get file locally (glob)
68 0 largefiles updated, 0 removed
67 0 largefiles updated, 0 removed
68 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
69 $ hg status
69 $ hg status
70 ! large
70 ! large
71 $ cd ..
71 $ cd ..
72
72
73 #if unix-permissions
73 #if unix-permissions
74
74
75 Portable way to print file permissions:
75 Portable way to print file permissions:
76
76
77 $ cat > ls-l.py <<EOF
77 $ cat > ls-l.py <<EOF
78 > #!/usr/bin/env python
78 > #!/usr/bin/env python
79 > import sys, os
79 > import sys, os
80 > path = sys.argv[1]
80 > path = sys.argv[1]
81 > print '%03o' % (os.lstat(path).st_mode & 0777)
81 > print '%03o' % (os.lstat(path).st_mode & 0777)
82 > EOF
82 > EOF
83 $ chmod +x ls-l.py
83 $ chmod +x ls-l.py
84
84
85 Test that files in .hg/largefiles inherit mode from .hg/store, not
85 Test that files in .hg/largefiles inherit mode from .hg/store, not
86 from file in working copy:
86 from file in working copy:
87
87
88 $ cd src
88 $ cd src
89 $ chmod 750 .hg/store
89 $ chmod 750 .hg/store
90 $ chmod 660 large
90 $ chmod 660 large
91 $ echo change >> large
91 $ echo change >> large
92 $ hg commit -m change
92 $ hg commit -m change
93 $ ../ls-l.py .hg/largefiles/e151b474069de4ca6898f67ce2f2a7263adf8fea
93 $ ../ls-l.py .hg/largefiles/e151b474069de4ca6898f67ce2f2a7263adf8fea
94 640
94 640
95
95
96 Test permission of with files in .hg/largefiles created by update:
96 Test permission of with files in .hg/largefiles created by update:
97
97
98 $ cd ../mirror
98 $ cd ../mirror
99 $ rm -r "$USERCACHE" .hg/largefiles # avoid links
99 $ rm -r "$USERCACHE" .hg/largefiles # avoid links
100 $ chmod 750 .hg/store
100 $ chmod 750 .hg/store
101 $ hg pull ../src --update -q
101 $ hg pull ../src --update -q
102 $ ../ls-l.py .hg/largefiles/e151b474069de4ca6898f67ce2f2a7263adf8fea
102 $ ../ls-l.py .hg/largefiles/e151b474069de4ca6898f67ce2f2a7263adf8fea
103 640
103 640
104
104
105 Test permission of files created by push:
105 Test permission of files created by push:
106
106
107 $ hg serve -R ../src -d -p $HGPORT --pid-file hg.pid \
107 $ hg serve -R ../src -d -p $HGPORT --pid-file hg.pid \
108 > --config "web.allow_push=*" --config web.push_ssl=no
108 > --config "web.allow_push=*" --config web.push_ssl=no
109 $ cat hg.pid >> $DAEMON_PIDS
109 $ cat hg.pid >> $DAEMON_PIDS
110
110
111 $ echo change >> large
111 $ echo change >> large
112 $ hg commit -m change
112 $ hg commit -m change
113
113
114 $ rm -r "$USERCACHE"
114 $ rm -r "$USERCACHE"
115
115
116 $ hg push -q http://localhost:$HGPORT/
116 $ hg push -q http://localhost:$HGPORT/
117
117
118 $ ../ls-l.py ../src/.hg/largefiles/b734e14a0971e370408ab9bce8d56d8485e368a9
118 $ ../ls-l.py ../src/.hg/largefiles/b734e14a0971e370408ab9bce8d56d8485e368a9
119 640
119 640
120
120
121 $ cd ..
121 $ cd ..
122
122
123 #endif
123 #endif
@@ -1,67 +1,66 b''
1 Test how largefiles abort in case the disk runs full
1 Test how largefiles abort in case the disk runs full
2
2
3 $ cat > criple.py <<EOF
3 $ cat > criple.py <<EOF
4 > import os, errno, shutil
4 > import os, errno, shutil
5 > from mercurial import util
5 > from mercurial import util
6 > #
6 > #
7 > # this makes the original largefiles code abort:
7 > # this makes the original largefiles code abort:
8 > def copyfileobj(fsrc, fdst, length=16*1024):
8 > def copyfileobj(fsrc, fdst, length=16*1024):
9 > fdst.write(fsrc.read(4))
9 > fdst.write(fsrc.read(4))
10 > raise IOError(errno.ENOSPC, os.strerror(errno.ENOSPC))
10 > raise IOError(errno.ENOSPC, os.strerror(errno.ENOSPC))
11 > shutil.copyfileobj = copyfileobj
11 > shutil.copyfileobj = copyfileobj
12 > #
12 > #
13 > # this makes the rewritten code abort:
13 > # this makes the rewritten code abort:
14 > def filechunkiter(f, size=65536, limit=None):
14 > def filechunkiter(f, size=65536, limit=None):
15 > yield f.read(4)
15 > yield f.read(4)
16 > raise IOError(errno.ENOSPC, os.strerror(errno.ENOSPC))
16 > raise IOError(errno.ENOSPC, os.strerror(errno.ENOSPC))
17 > util.filechunkiter = filechunkiter
17 > util.filechunkiter = filechunkiter
18 > #
18 > #
19 > def oslink(src, dest):
19 > def oslink(src, dest):
20 > raise OSError("no hardlinks, try copying instead")
20 > raise OSError("no hardlinks, try copying instead")
21 > util.oslink = oslink
21 > util.oslink = oslink
22 > EOF
22 > EOF
23
23
24 $ echo "[extensions]" >> $HGRCPATH
24 $ echo "[extensions]" >> $HGRCPATH
25 $ echo "largefiles =" >> $HGRCPATH
25 $ echo "largefiles =" >> $HGRCPATH
26
26
27 $ hg init alice
27 $ hg init alice
28 $ cd alice
28 $ cd alice
29 $ echo "this is a very big file" > big
29 $ echo "this is a very big file" > big
30 $ hg add --large big
30 $ hg add --large big
31 $ hg commit --config extensions.criple=$TESTTMP/criple.py -m big
31 $ hg commit --config extensions.criple=$TESTTMP/criple.py -m big
32 abort: No space left on device
32 abort: No space left on device
33 [255]
33 [255]
34
34
35 The largefile is not created in .hg/largefiles:
35 The largefile is not created in .hg/largefiles:
36
36
37 $ ls .hg/largefiles
37 $ ls .hg/largefiles
38 dirstate
38 dirstate
39
39
40 The user cache is not even created:
40 The user cache is not even created:
41
41
42 >>> import os; os.path.exists("$HOME/.cache/largefiles/")
42 >>> import os; os.path.exists("$HOME/.cache/largefiles/")
43 False
43 False
44
44
45 Make the commit with space on the device:
45 Make the commit with space on the device:
46
46
47 $ hg commit -m big
47 $ hg commit -m big
48
48
49 Now make a clone with a full disk, and make sure lfutil.link function
49 Now make a clone with a full disk, and make sure lfutil.link function
50 makes copies instead of hardlinks:
50 makes copies instead of hardlinks:
51
51
52 $ cd ..
52 $ cd ..
53 $ hg --config extensions.criple=$TESTTMP/criple.py clone --pull alice bob
53 $ hg --config extensions.criple=$TESTTMP/criple.py clone --pull alice bob
54 requesting all changes
54 requesting all changes
55 adding changesets
55 adding changesets
56 adding manifests
56 adding manifests
57 adding file changes
57 adding file changes
58 added 1 changesets with 1 changes to 1 files
58 added 1 changesets with 1 changes to 1 files
59 updating to branch default
59 updating to branch default
60 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
61 getting changed largefiles
60 getting changed largefiles
62 abort: No space left on device
61 abort: No space left on device
63 [255]
62 [255]
64
63
65 The largefile is not created in .hg/largefiles:
64 The largefile is not created in .hg/largefiles:
66
65
67 $ ls bob/.hg/largefiles
66 $ ls bob/.hg/largefiles
@@ -1,1904 +1,1929 b''
1 $ USERCACHE="$TESTTMP/cache"; export USERCACHE
1 $ USERCACHE="$TESTTMP/cache"; export USERCACHE
2 $ mkdir "${USERCACHE}"
2 $ mkdir "${USERCACHE}"
3 $ cat >> $HGRCPATH <<EOF
3 $ cat >> $HGRCPATH <<EOF
4 > [extensions]
4 > [extensions]
5 > largefiles=
5 > largefiles=
6 > purge=
6 > purge=
7 > rebase=
7 > rebase=
8 > transplant=
8 > transplant=
9 > [phases]
9 > [phases]
10 > publish=False
10 > publish=False
11 > [largefiles]
11 > [largefiles]
12 > minsize=2
12 > minsize=2
13 > patterns=glob:**.dat
13 > patterns=glob:**.dat
14 > usercache=${USERCACHE}
14 > usercache=${USERCACHE}
15 > [hooks]
15 > [hooks]
16 > precommit=sh -c "echo \\"Invoking status precommit hook\\"; hg status"
16 > precommit=sh -c "echo \\"Invoking status precommit hook\\"; hg status"
17 > EOF
17 > EOF
18
18
19 Create the repo with a couple of revisions of both large and normal
19 Create the repo with a couple of revisions of both large and normal
20 files.
20 files.
21 Test status and dirstate of largefiles and that summary output is correct.
21 Test status and dirstate of largefiles and that summary output is correct.
22
22
23 $ hg init a
23 $ hg init a
24 $ cd a
24 $ cd a
25 $ mkdir sub
25 $ mkdir sub
26 $ echo normal1 > normal1
26 $ echo normal1 > normal1
27 $ echo normal2 > sub/normal2
27 $ echo normal2 > sub/normal2
28 $ echo large1 > large1
28 $ echo large1 > large1
29 $ echo large2 > sub/large2
29 $ echo large2 > sub/large2
30 $ hg add normal1 sub/normal2
30 $ hg add normal1 sub/normal2
31 $ hg add --large large1 sub/large2
31 $ hg add --large large1 sub/large2
32 $ hg commit -m "add files"
32 $ hg commit -m "add files"
33 Invoking status precommit hook
33 Invoking status precommit hook
34 A large1
34 A large1
35 A normal1
35 A normal1
36 A sub/large2
36 A sub/large2
37 A sub/normal2
37 A sub/normal2
38 $ touch large1 sub/large2
38 $ touch large1 sub/large2
39 $ sleep 1
39 $ sleep 1
40 $ hg st
40 $ hg st
41 $ hg debugstate --nodates
41 $ hg debugstate --nodates
42 n 644 41 .hglf/large1
42 n 644 41 .hglf/large1
43 n 644 41 .hglf/sub/large2
43 n 644 41 .hglf/sub/large2
44 n 644 8 normal1
44 n 644 8 normal1
45 n 644 8 sub/normal2
45 n 644 8 sub/normal2
46 $ hg debugstate --large
46 $ hg debugstate --large
47 n 644 7 large1
47 n 644 7 large1
48 n 644 7 sub/large2
48 n 644 7 sub/large2
49 $ echo normal11 > normal1
49 $ echo normal11 > normal1
50 $ echo normal22 > sub/normal2
50 $ echo normal22 > sub/normal2
51 $ echo large11 > large1
51 $ echo large11 > large1
52 $ echo large22 > sub/large2
52 $ echo large22 > sub/large2
53 $ hg commit -m "edit files"
53 $ hg commit -m "edit files"
54 Invoking status precommit hook
54 Invoking status precommit hook
55 M large1
55 M large1
56 M normal1
56 M normal1
57 M sub/large2
57 M sub/large2
58 M sub/normal2
58 M sub/normal2
59 $ hg sum --large
59 $ hg sum --large
60 parent: 1:ce8896473775 tip
60 parent: 1:ce8896473775 tip
61 edit files
61 edit files
62 branch: default
62 branch: default
63 commit: (clean)
63 commit: (clean)
64 update: (current)
64 update: (current)
65 largefiles: (no remote repo)
65 largefiles: (no remote repo)
66
66
67 Commit preserved largefile contents.
67 Commit preserved largefile contents.
68
68
69 $ cat normal1
69 $ cat normal1
70 normal11
70 normal11
71 $ cat large1
71 $ cat large1
72 large11
72 large11
73 $ cat sub/normal2
73 $ cat sub/normal2
74 normal22
74 normal22
75 $ cat sub/large2
75 $ cat sub/large2
76 large22
76 large22
77
77
78 Test status, subdir and unknown files
78 Test status, subdir and unknown files
79
79
80 $ echo unknown > sub/unknown
80 $ echo unknown > sub/unknown
81 $ hg st --all
81 $ hg st --all
82 ? sub/unknown
82 ? sub/unknown
83 C large1
83 C large1
84 C normal1
84 C normal1
85 C sub/large2
85 C sub/large2
86 C sub/normal2
86 C sub/normal2
87 $ hg st --all sub
87 $ hg st --all sub
88 ? sub/unknown
88 ? sub/unknown
89 C sub/large2
89 C sub/large2
90 C sub/normal2
90 C sub/normal2
91 $ rm sub/unknown
91 $ rm sub/unknown
92
92
93 Test messages and exit codes for remove warning cases
93 Test messages and exit codes for remove warning cases
94
94
95 $ hg remove -A large1
95 $ hg remove -A large1
96 not removing large1: file still exists
96 not removing large1: file still exists
97 [1]
97 [1]
98 $ echo 'modified' > large1
98 $ echo 'modified' > large1
99 $ hg remove large1
99 $ hg remove large1
100 not removing large1: file is modified (use -f to force removal)
100 not removing large1: file is modified (use -f to force removal)
101 [1]
101 [1]
102 $ echo 'new' > normalnew
102 $ echo 'new' > normalnew
103 $ hg add normalnew
103 $ hg add normalnew
104 $ echo 'new' > largenew
104 $ echo 'new' > largenew
105 $ hg add --large normalnew
105 $ hg add --large normalnew
106 normalnew already tracked!
106 normalnew already tracked!
107 $ hg remove normalnew largenew
107 $ hg remove normalnew largenew
108 not removing largenew: file is untracked
108 not removing largenew: file is untracked
109 not removing normalnew: file has been marked for add (use forget to undo)
109 not removing normalnew: file has been marked for add (use forget to undo)
110 [1]
110 [1]
111 $ rm normalnew largenew
111 $ rm normalnew largenew
112 $ hg up -Cq
112 $ hg up -Cq
113
113
114 Remove both largefiles and normal files.
114 Remove both largefiles and normal files.
115
115
116 $ hg remove normal1 large1
116 $ hg remove normal1 large1
117 $ hg status large1
117 $ hg status large1
118 R large1
118 R large1
119 $ hg commit -m "remove files"
119 $ hg commit -m "remove files"
120 Invoking status precommit hook
120 Invoking status precommit hook
121 R large1
121 R large1
122 R normal1
122 R normal1
123 $ ls
123 $ ls
124 sub
124 sub
125 $ echo "testlargefile" > large1-test
125 $ echo "testlargefile" > large1-test
126 $ hg add --large large1-test
126 $ hg add --large large1-test
127 $ hg st
127 $ hg st
128 A large1-test
128 A large1-test
129 $ hg rm large1-test
129 $ hg rm large1-test
130 not removing large1-test: file has been marked for add (use forget to undo)
130 not removing large1-test: file has been marked for add (use forget to undo)
131 [1]
131 [1]
132 $ hg st
132 $ hg st
133 A large1-test
133 A large1-test
134 $ hg forget large1-test
134 $ hg forget large1-test
135 $ hg st
135 $ hg st
136 ? large1-test
136 ? large1-test
137 $ hg remove large1-test
137 $ hg remove large1-test
138 not removing large1-test: file is untracked
138 not removing large1-test: file is untracked
139 [1]
139 [1]
140 $ hg forget large1-test
140 $ hg forget large1-test
141 not removing large1-test: file is already untracked
141 not removing large1-test: file is already untracked
142 [1]
142 [1]
143 $ rm large1-test
143 $ rm large1-test
144
144
145 Copy both largefiles and normal files (testing that status output is correct).
145 Copy both largefiles and normal files (testing that status output is correct).
146
146
147 $ hg cp sub/normal2 normal1
147 $ hg cp sub/normal2 normal1
148 $ hg cp sub/large2 large1
148 $ hg cp sub/large2 large1
149 $ hg commit -m "copy files"
149 $ hg commit -m "copy files"
150 Invoking status precommit hook
150 Invoking status precommit hook
151 A large1
151 A large1
152 A normal1
152 A normal1
153 $ cat normal1
153 $ cat normal1
154 normal22
154 normal22
155 $ cat large1
155 $ cat large1
156 large22
156 large22
157
157
158 Test moving largefiles and verify that normal files are also unaffected.
158 Test moving largefiles and verify that normal files are also unaffected.
159
159
160 $ hg mv normal1 normal3
160 $ hg mv normal1 normal3
161 $ hg mv large1 large3
161 $ hg mv large1 large3
162 $ hg mv sub/normal2 sub/normal4
162 $ hg mv sub/normal2 sub/normal4
163 $ hg mv sub/large2 sub/large4
163 $ hg mv sub/large2 sub/large4
164 $ hg commit -m "move files"
164 $ hg commit -m "move files"
165 Invoking status precommit hook
165 Invoking status precommit hook
166 A large3
166 A large3
167 A normal3
167 A normal3
168 A sub/large4
168 A sub/large4
169 A sub/normal4
169 A sub/normal4
170 R large1
170 R large1
171 R normal1
171 R normal1
172 R sub/large2
172 R sub/large2
173 R sub/normal2
173 R sub/normal2
174 $ cat normal3
174 $ cat normal3
175 normal22
175 normal22
176 $ cat large3
176 $ cat large3
177 large22
177 large22
178 $ cat sub/normal4
178 $ cat sub/normal4
179 normal22
179 normal22
180 $ cat sub/large4
180 $ cat sub/large4
181 large22
181 large22
182
182
183 Test copies and moves from a directory other than root (issue3516)
183 Test copies and moves from a directory other than root (issue3516)
184
184
185 $ cd ..
185 $ cd ..
186 $ hg init lf_cpmv
186 $ hg init lf_cpmv
187 $ cd lf_cpmv
187 $ cd lf_cpmv
188 $ mkdir dira
188 $ mkdir dira
189 $ mkdir dira/dirb
189 $ mkdir dira/dirb
190 $ touch dira/dirb/largefile
190 $ touch dira/dirb/largefile
191 $ hg add --large dira/dirb/largefile
191 $ hg add --large dira/dirb/largefile
192 $ hg commit -m "added"
192 $ hg commit -m "added"
193 Invoking status precommit hook
193 Invoking status precommit hook
194 A dira/dirb/largefile
194 A dira/dirb/largefile
195 $ cd dira
195 $ cd dira
196 $ hg cp dirb/largefile foo/largefile
196 $ hg cp dirb/largefile foo/largefile
197 $ hg ci -m "deep copy"
197 $ hg ci -m "deep copy"
198 Invoking status precommit hook
198 Invoking status precommit hook
199 A dira/foo/largefile
199 A dira/foo/largefile
200 $ find . | sort
200 $ find . | sort
201 .
201 .
202 ./dirb
202 ./dirb
203 ./dirb/largefile
203 ./dirb/largefile
204 ./foo
204 ./foo
205 ./foo/largefile
205 ./foo/largefile
206 $ hg mv foo/largefile baz/largefile
206 $ hg mv foo/largefile baz/largefile
207 $ hg ci -m "moved"
207 $ hg ci -m "moved"
208 Invoking status precommit hook
208 Invoking status precommit hook
209 A dira/baz/largefile
209 A dira/baz/largefile
210 R dira/foo/largefile
210 R dira/foo/largefile
211 $ find . | sort
211 $ find . | sort
212 .
212 .
213 ./baz
213 ./baz
214 ./baz/largefile
214 ./baz/largefile
215 ./dirb
215 ./dirb
216 ./dirb/largefile
216 ./dirb/largefile
217 ./foo
217 ./foo
218 $ cd ../../a
218 $ cd ../../a
219
219
220 #if serve
220 #if serve
221 Test display of largefiles in hgweb
221 Test display of largefiles in hgweb
222
222
223 $ hg serve -d -p $HGPORT --pid-file ../hg.pid
223 $ hg serve -d -p $HGPORT --pid-file ../hg.pid
224 $ cat ../hg.pid >> $DAEMON_PIDS
224 $ cat ../hg.pid >> $DAEMON_PIDS
225 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT 'file/tip/?style=raw'
225 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT 'file/tip/?style=raw'
226 200 Script output follows
226 200 Script output follows
227
227
228
228
229 drwxr-xr-x sub
229 drwxr-xr-x sub
230 -rw-r--r-- 41 large3
230 -rw-r--r-- 41 large3
231 -rw-r--r-- 9 normal3
231 -rw-r--r-- 9 normal3
232
232
233
233
234 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT 'file/tip/sub/?style=raw'
234 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT 'file/tip/sub/?style=raw'
235 200 Script output follows
235 200 Script output follows
236
236
237
237
238 -rw-r--r-- 41 large4
238 -rw-r--r-- 41 large4
239 -rw-r--r-- 9 normal4
239 -rw-r--r-- 9 normal4
240
240
241
241
242 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
242 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
243 #endif
243 #endif
244
244
245 Test archiving the various revisions. These hit corner cases known with
245 Test archiving the various revisions. These hit corner cases known with
246 archiving.
246 archiving.
247
247
248 $ hg archive -r 0 ../archive0
248 $ hg archive -r 0 ../archive0
249 $ hg archive -r 1 ../archive1
249 $ hg archive -r 1 ../archive1
250 $ hg archive -r 2 ../archive2
250 $ hg archive -r 2 ../archive2
251 $ hg archive -r 3 ../archive3
251 $ hg archive -r 3 ../archive3
252 $ hg archive -r 4 ../archive4
252 $ hg archive -r 4 ../archive4
253 $ cd ../archive0
253 $ cd ../archive0
254 $ cat normal1
254 $ cat normal1
255 normal1
255 normal1
256 $ cat large1
256 $ cat large1
257 large1
257 large1
258 $ cat sub/normal2
258 $ cat sub/normal2
259 normal2
259 normal2
260 $ cat sub/large2
260 $ cat sub/large2
261 large2
261 large2
262 $ cd ../archive1
262 $ cd ../archive1
263 $ cat normal1
263 $ cat normal1
264 normal11
264 normal11
265 $ cat large1
265 $ cat large1
266 large11
266 large11
267 $ cat sub/normal2
267 $ cat sub/normal2
268 normal22
268 normal22
269 $ cat sub/large2
269 $ cat sub/large2
270 large22
270 large22
271 $ cd ../archive2
271 $ cd ../archive2
272 $ ls
272 $ ls
273 sub
273 sub
274 $ cat sub/normal2
274 $ cat sub/normal2
275 normal22
275 normal22
276 $ cat sub/large2
276 $ cat sub/large2
277 large22
277 large22
278 $ cd ../archive3
278 $ cd ../archive3
279 $ cat normal1
279 $ cat normal1
280 normal22
280 normal22
281 $ cat large1
281 $ cat large1
282 large22
282 large22
283 $ cat sub/normal2
283 $ cat sub/normal2
284 normal22
284 normal22
285 $ cat sub/large2
285 $ cat sub/large2
286 large22
286 large22
287 $ cd ../archive4
287 $ cd ../archive4
288 $ cat normal3
288 $ cat normal3
289 normal22
289 normal22
290 $ cat large3
290 $ cat large3
291 large22
291 large22
292 $ cat sub/normal4
292 $ cat sub/normal4
293 normal22
293 normal22
294 $ cat sub/large4
294 $ cat sub/large4
295 large22
295 large22
296
296
297 Commit corner case: specify files to commit.
297 Commit corner case: specify files to commit.
298
298
299 $ cd ../a
299 $ cd ../a
300 $ echo normal3 > normal3
300 $ echo normal3 > normal3
301 $ echo large3 > large3
301 $ echo large3 > large3
302 $ echo normal4 > sub/normal4
302 $ echo normal4 > sub/normal4
303 $ echo large4 > sub/large4
303 $ echo large4 > sub/large4
304 $ hg commit normal3 large3 sub/normal4 sub/large4 -m "edit files again"
304 $ hg commit normal3 large3 sub/normal4 sub/large4 -m "edit files again"
305 Invoking status precommit hook
305 Invoking status precommit hook
306 M large3
306 M large3
307 M normal3
307 M normal3
308 M sub/large4
308 M sub/large4
309 M sub/normal4
309 M sub/normal4
310 $ cat normal3
310 $ cat normal3
311 normal3
311 normal3
312 $ cat large3
312 $ cat large3
313 large3
313 large3
314 $ cat sub/normal4
314 $ cat sub/normal4
315 normal4
315 normal4
316 $ cat sub/large4
316 $ cat sub/large4
317 large4
317 large4
318
318
319 One more commit corner case: commit from a subdirectory.
319 One more commit corner case: commit from a subdirectory.
320
320
321 $ cd ../a
321 $ cd ../a
322 $ echo normal33 > normal3
322 $ echo normal33 > normal3
323 $ echo large33 > large3
323 $ echo large33 > large3
324 $ echo normal44 > sub/normal4
324 $ echo normal44 > sub/normal4
325 $ echo large44 > sub/large4
325 $ echo large44 > sub/large4
326 $ cd sub
326 $ cd sub
327 $ hg commit -m "edit files yet again"
327 $ hg commit -m "edit files yet again"
328 Invoking status precommit hook
328 Invoking status precommit hook
329 M large3
329 M large3
330 M normal3
330 M normal3
331 M sub/large4
331 M sub/large4
332 M sub/normal4
332 M sub/normal4
333 $ cat ../normal3
333 $ cat ../normal3
334 normal33
334 normal33
335 $ cat ../large3
335 $ cat ../large3
336 large33
336 large33
337 $ cat normal4
337 $ cat normal4
338 normal44
338 normal44
339 $ cat large4
339 $ cat large4
340 large44
340 large44
341
341
342 Committing standins is not allowed.
342 Committing standins is not allowed.
343
343
344 $ cd ..
344 $ cd ..
345 $ echo large3 > large3
345 $ echo large3 > large3
346 $ hg commit .hglf/large3 -m "try to commit standin"
346 $ hg commit .hglf/large3 -m "try to commit standin"
347 abort: file ".hglf/large3" is a largefile standin
347 abort: file ".hglf/large3" is a largefile standin
348 (commit the largefile itself instead)
348 (commit the largefile itself instead)
349 [255]
349 [255]
350
350
351 Corner cases for adding largefiles.
351 Corner cases for adding largefiles.
352
352
353 $ echo large5 > large5
353 $ echo large5 > large5
354 $ hg add --large large5
354 $ hg add --large large5
355 $ hg add --large large5
355 $ hg add --large large5
356 large5 already a largefile
356 large5 already a largefile
357 $ mkdir sub2
357 $ mkdir sub2
358 $ echo large6 > sub2/large6
358 $ echo large6 > sub2/large6
359 $ echo large7 > sub2/large7
359 $ echo large7 > sub2/large7
360 $ hg add --large sub2
360 $ hg add --large sub2
361 adding sub2/large6 as a largefile (glob)
361 adding sub2/large6 as a largefile (glob)
362 adding sub2/large7 as a largefile (glob)
362 adding sub2/large7 as a largefile (glob)
363 $ hg st
363 $ hg st
364 M large3
364 M large3
365 A large5
365 A large5
366 A sub2/large6
366 A sub2/large6
367 A sub2/large7
367 A sub2/large7
368
368
369 Committing directories containing only largefiles.
369 Committing directories containing only largefiles.
370
370
371 $ mkdir -p z/y/x/m
371 $ mkdir -p z/y/x/m
372 $ touch z/y/x/m/large1
372 $ touch z/y/x/m/large1
373 $ touch z/y/x/large2
373 $ touch z/y/x/large2
374 $ hg add --large z/y/x/m/large1 z/y/x/large2
374 $ hg add --large z/y/x/m/large1 z/y/x/large2
375 $ hg commit -m "Subdir with directory only containing largefiles" z
375 $ hg commit -m "Subdir with directory only containing largefiles" z
376 Invoking status precommit hook
376 Invoking status precommit hook
377 M large3
377 M large3
378 A large5
378 A large5
379 A sub2/large6
379 A sub2/large6
380 A sub2/large7
380 A sub2/large7
381 A z/y/x/large2
381 A z/y/x/large2
382 A z/y/x/m/large1
382 A z/y/x/m/large1
383 $ hg rollback --quiet
383 $ hg rollback --quiet
384 $ touch z/y/x/m/normal
384 $ touch z/y/x/m/normal
385 $ hg add z/y/x/m/normal
385 $ hg add z/y/x/m/normal
386 $ hg commit -m "Subdir with mixed contents" z
386 $ hg commit -m "Subdir with mixed contents" z
387 Invoking status precommit hook
387 Invoking status precommit hook
388 M large3
388 M large3
389 A large5
389 A large5
390 A sub2/large6
390 A sub2/large6
391 A sub2/large7
391 A sub2/large7
392 A z/y/x/large2
392 A z/y/x/large2
393 A z/y/x/m/large1
393 A z/y/x/m/large1
394 A z/y/x/m/normal
394 A z/y/x/m/normal
395 $ hg st
395 $ hg st
396 M large3
396 M large3
397 A large5
397 A large5
398 A sub2/large6
398 A sub2/large6
399 A sub2/large7
399 A sub2/large7
400 $ hg rollback --quiet
400 $ hg rollback --quiet
401 $ hg revert z/y/x/large2 z/y/x/m/large1
401 $ hg revert z/y/x/large2 z/y/x/m/large1
402 $ rm z/y/x/large2 z/y/x/m/large1
402 $ rm z/y/x/large2 z/y/x/m/large1
403 $ hg commit -m "Subdir with normal contents" z
403 $ hg commit -m "Subdir with normal contents" z
404 Invoking status precommit hook
404 Invoking status precommit hook
405 M large3
405 M large3
406 A large5
406 A large5
407 A sub2/large6
407 A sub2/large6
408 A sub2/large7
408 A sub2/large7
409 A z/y/x/m/normal
409 A z/y/x/m/normal
410 $ hg st
410 $ hg st
411 M large3
411 M large3
412 A large5
412 A large5
413 A sub2/large6
413 A sub2/large6
414 A sub2/large7
414 A sub2/large7
415 $ hg rollback --quiet
415 $ hg rollback --quiet
416 $ hg revert --quiet z
416 $ hg revert --quiet z
417 $ hg commit -m "Empty subdir" z
417 $ hg commit -m "Empty subdir" z
418 abort: z: no match under directory!
418 abort: z: no match under directory!
419 [255]
419 [255]
420 $ rm -rf z
420 $ rm -rf z
421 $ hg ci -m "standin" .hglf
421 $ hg ci -m "standin" .hglf
422 abort: file ".hglf" is a largefile standin
422 abort: file ".hglf" is a largefile standin
423 (commit the largefile itself instead)
423 (commit the largefile itself instead)
424 [255]
424 [255]
425
425
426 Test "hg status" with combination of 'file pattern' and 'directory
426 Test "hg status" with combination of 'file pattern' and 'directory
427 pattern' for largefiles:
427 pattern' for largefiles:
428
428
429 $ hg status sub2/large6 sub2
429 $ hg status sub2/large6 sub2
430 A sub2/large6
430 A sub2/large6
431 A sub2/large7
431 A sub2/large7
432
432
433 Config settings (pattern **.dat, minsize 2 MB) are respected.
433 Config settings (pattern **.dat, minsize 2 MB) are respected.
434
434
435 $ echo testdata > test.dat
435 $ echo testdata > test.dat
436 $ dd bs=1k count=2k if=/dev/zero of=reallylarge > /dev/null 2> /dev/null
436 $ dd bs=1k count=2k if=/dev/zero of=reallylarge > /dev/null 2> /dev/null
437 $ hg add
437 $ hg add
438 adding reallylarge as a largefile
438 adding reallylarge as a largefile
439 adding test.dat as a largefile
439 adding test.dat as a largefile
440
440
441 Test that minsize and --lfsize handle float values;
441 Test that minsize and --lfsize handle float values;
442 also tests that --lfsize overrides largefiles.minsize.
442 also tests that --lfsize overrides largefiles.minsize.
443 (0.250 MB = 256 kB = 262144 B)
443 (0.250 MB = 256 kB = 262144 B)
444
444
445 $ dd if=/dev/zero of=ratherlarge bs=1024 count=256 > /dev/null 2> /dev/null
445 $ dd if=/dev/zero of=ratherlarge bs=1024 count=256 > /dev/null 2> /dev/null
446 $ dd if=/dev/zero of=medium bs=1024 count=128 > /dev/null 2> /dev/null
446 $ dd if=/dev/zero of=medium bs=1024 count=128 > /dev/null 2> /dev/null
447 $ hg --config largefiles.minsize=.25 add
447 $ hg --config largefiles.minsize=.25 add
448 adding ratherlarge as a largefile
448 adding ratherlarge as a largefile
449 adding medium
449 adding medium
450 $ hg forget medium
450 $ hg forget medium
451 $ hg --config largefiles.minsize=.25 add --lfsize=.125
451 $ hg --config largefiles.minsize=.25 add --lfsize=.125
452 adding medium as a largefile
452 adding medium as a largefile
453 $ dd if=/dev/zero of=notlarge bs=1024 count=127 > /dev/null 2> /dev/null
453 $ dd if=/dev/zero of=notlarge bs=1024 count=127 > /dev/null 2> /dev/null
454 $ hg --config largefiles.minsize=.25 add --lfsize=.125
454 $ hg --config largefiles.minsize=.25 add --lfsize=.125
455 adding notlarge
455 adding notlarge
456 $ hg forget notlarge
456 $ hg forget notlarge
457
457
458 Test forget on largefiles.
458 Test forget on largefiles.
459
459
460 $ hg forget large3 large5 test.dat reallylarge ratherlarge medium
460 $ hg forget large3 large5 test.dat reallylarge ratherlarge medium
461 $ hg commit -m "add/edit more largefiles"
461 $ hg commit -m "add/edit more largefiles"
462 Invoking status precommit hook
462 Invoking status precommit hook
463 A sub2/large6
463 A sub2/large6
464 A sub2/large7
464 A sub2/large7
465 R large3
465 R large3
466 ? large5
466 ? large5
467 ? medium
467 ? medium
468 ? notlarge
468 ? notlarge
469 ? ratherlarge
469 ? ratherlarge
470 ? reallylarge
470 ? reallylarge
471 ? test.dat
471 ? test.dat
472 $ hg st
472 $ hg st
473 ? large3
473 ? large3
474 ? large5
474 ? large5
475 ? medium
475 ? medium
476 ? notlarge
476 ? notlarge
477 ? ratherlarge
477 ? ratherlarge
478 ? reallylarge
478 ? reallylarge
479 ? test.dat
479 ? test.dat
480
480
481 Purge with largefiles: verify that largefiles are still in the working
481 Purge with largefiles: verify that largefiles are still in the working
482 dir after a purge.
482 dir after a purge.
483
483
484 $ hg purge --all
484 $ hg purge --all
485 $ cat sub/large4
485 $ cat sub/large4
486 large44
486 large44
487 $ cat sub2/large6
487 $ cat sub2/large6
488 large6
488 large6
489 $ cat sub2/large7
489 $ cat sub2/large7
490 large7
490 large7
491
491
492 Test addremove: verify that files that should be added as largfiles are added as
492 Test addremove: verify that files that should be added as largfiles are added as
493 such and that already-existing largfiles are not added as normal files by
493 such and that already-existing largfiles are not added as normal files by
494 accident.
494 accident.
495
495
496 $ rm normal3
496 $ rm normal3
497 $ rm sub/large4
497 $ rm sub/large4
498 $ echo "testing addremove with patterns" > testaddremove.dat
498 $ echo "testing addremove with patterns" > testaddremove.dat
499 $ echo "normaladdremove" > normaladdremove
499 $ echo "normaladdremove" > normaladdremove
500 $ hg addremove
500 $ hg addremove
501 removing sub/large4
501 removing sub/large4
502 adding testaddremove.dat as a largefile
502 adding testaddremove.dat as a largefile
503 removing normal3
503 removing normal3
504 adding normaladdremove
504 adding normaladdremove
505
505
506 Test addremove with -R
506 Test addremove with -R
507
507
508 $ hg up -C
508 $ hg up -C
509 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
510 getting changed largefiles
509 getting changed largefiles
511 1 largefiles updated, 0 removed
510 1 largefiles updated, 0 removed
511 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
512 $ rm normal3
512 $ rm normal3
513 $ rm sub/large4
513 $ rm sub/large4
514 $ echo "testing addremove with patterns" > testaddremove.dat
514 $ echo "testing addremove with patterns" > testaddremove.dat
515 $ echo "normaladdremove" > normaladdremove
515 $ echo "normaladdremove" > normaladdremove
516 $ cd ..
516 $ cd ..
517 $ hg -R a addremove
517 $ hg -R a addremove
518 removing sub/large4
518 removing sub/large4
519 adding a/testaddremove.dat as a largefile (glob)
519 adding a/testaddremove.dat as a largefile (glob)
520 removing normal3
520 removing normal3
521 adding normaladdremove
521 adding normaladdremove
522 $ cd a
522 $ cd a
523
523
524 Test 3364
524 Test 3364
525 $ hg clone . ../addrm
525 $ hg clone . ../addrm
526 updating to branch default
526 updating to branch default
527 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
528 getting changed largefiles
527 getting changed largefiles
529 3 largefiles updated, 0 removed
528 3 largefiles updated, 0 removed
529 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
530 $ cd ../addrm
530 $ cd ../addrm
531 $ cat >> .hg/hgrc <<EOF
531 $ cat >> .hg/hgrc <<EOF
532 > [hooks]
532 > [hooks]
533 > post-commit.stat=sh -c "echo \\"Invoking status postcommit hook\\"; hg status -A"
533 > post-commit.stat=sh -c "echo \\"Invoking status postcommit hook\\"; hg status -A"
534 > EOF
534 > EOF
535 $ touch foo
535 $ touch foo
536 $ hg add --large foo
536 $ hg add --large foo
537 $ hg ci -m "add foo"
537 $ hg ci -m "add foo"
538 Invoking status precommit hook
538 Invoking status precommit hook
539 A foo
539 A foo
540 Invoking status postcommit hook
540 Invoking status postcommit hook
541 C foo
541 C foo
542 C normal3
542 C normal3
543 C sub/large4
543 C sub/large4
544 C sub/normal4
544 C sub/normal4
545 C sub2/large6
545 C sub2/large6
546 C sub2/large7
546 C sub2/large7
547 $ rm foo
547 $ rm foo
548 $ hg st
548 $ hg st
549 ! foo
549 ! foo
550 hmm.. no precommit invoked, but there is a postcommit??
550 hmm.. no precommit invoked, but there is a postcommit??
551 $ hg ci -m "will not checkin"
551 $ hg ci -m "will not checkin"
552 nothing changed
552 nothing changed
553 Invoking status postcommit hook
553 Invoking status postcommit hook
554 ! foo
554 ! foo
555 C normal3
555 C normal3
556 C sub/large4
556 C sub/large4
557 C sub/normal4
557 C sub/normal4
558 C sub2/large6
558 C sub2/large6
559 C sub2/large7
559 C sub2/large7
560 [1]
560 [1]
561 $ hg addremove
561 $ hg addremove
562 removing foo
562 removing foo
563 $ hg st
563 $ hg st
564 R foo
564 R foo
565 $ hg ci -m "used to say nothing changed"
565 $ hg ci -m "used to say nothing changed"
566 Invoking status precommit hook
566 Invoking status precommit hook
567 R foo
567 R foo
568 Invoking status postcommit hook
568 Invoking status postcommit hook
569 C normal3
569 C normal3
570 C sub/large4
570 C sub/large4
571 C sub/normal4
571 C sub/normal4
572 C sub2/large6
572 C sub2/large6
573 C sub2/large7
573 C sub2/large7
574 $ hg st
574 $ hg st
575
575
576 Test 3507 (both normal files and largefiles were a problem)
576 Test 3507 (both normal files and largefiles were a problem)
577
577
578 $ touch normal
578 $ touch normal
579 $ touch large
579 $ touch large
580 $ hg add normal
580 $ hg add normal
581 $ hg add --large large
581 $ hg add --large large
582 $ hg ci -m "added"
582 $ hg ci -m "added"
583 Invoking status precommit hook
583 Invoking status precommit hook
584 A large
584 A large
585 A normal
585 A normal
586 Invoking status postcommit hook
586 Invoking status postcommit hook
587 C large
587 C large
588 C normal
588 C normal
589 C normal3
589 C normal3
590 C sub/large4
590 C sub/large4
591 C sub/normal4
591 C sub/normal4
592 C sub2/large6
592 C sub2/large6
593 C sub2/large7
593 C sub2/large7
594 $ hg remove normal
594 $ hg remove normal
595 $ hg addremove --traceback
595 $ hg addremove --traceback
596 $ hg ci -m "addremoved normal"
596 $ hg ci -m "addremoved normal"
597 Invoking status precommit hook
597 Invoking status precommit hook
598 R normal
598 R normal
599 Invoking status postcommit hook
599 Invoking status postcommit hook
600 C large
600 C large
601 C normal3
601 C normal3
602 C sub/large4
602 C sub/large4
603 C sub/normal4
603 C sub/normal4
604 C sub2/large6
604 C sub2/large6
605 C sub2/large7
605 C sub2/large7
606 $ hg up -C '.^'
606 $ hg up -C '.^'
607 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
608 getting changed largefiles
607 getting changed largefiles
609 0 largefiles updated, 0 removed
608 0 largefiles updated, 0 removed
609 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
610 $ hg remove large
610 $ hg remove large
611 $ hg addremove --traceback
611 $ hg addremove --traceback
612 $ hg ci -m "removed large"
612 $ hg ci -m "removed large"
613 Invoking status precommit hook
613 Invoking status precommit hook
614 R large
614 R large
615 created new head
615 created new head
616 Invoking status postcommit hook
616 Invoking status postcommit hook
617 C normal
617 C normal
618 C normal3
618 C normal3
619 C sub/large4
619 C sub/large4
620 C sub/normal4
620 C sub/normal4
621 C sub2/large6
621 C sub2/large6
622 C sub2/large7
622 C sub2/large7
623
623
624 Test commit -A (issue 3542)
624 Test commit -A (issue 3542)
625 $ echo large8 > large8
625 $ echo large8 > large8
626 $ hg add --large large8
626 $ hg add --large large8
627 $ hg ci -Am 'this used to add large8 as normal and commit both'
627 $ hg ci -Am 'this used to add large8 as normal and commit both'
628 Invoking status precommit hook
628 Invoking status precommit hook
629 A large8
629 A large8
630 Invoking status postcommit hook
630 Invoking status postcommit hook
631 C large8
631 C large8
632 C normal
632 C normal
633 C normal3
633 C normal3
634 C sub/large4
634 C sub/large4
635 C sub/normal4
635 C sub/normal4
636 C sub2/large6
636 C sub2/large6
637 C sub2/large7
637 C sub2/large7
638 $ rm large8
638 $ rm large8
639 $ hg ci -Am 'this used to not notice the rm'
639 $ hg ci -Am 'this used to not notice the rm'
640 removing large8
640 removing large8
641 Invoking status precommit hook
641 Invoking status precommit hook
642 R large8
642 R large8
643 Invoking status postcommit hook
643 Invoking status postcommit hook
644 C normal
644 C normal
645 C normal3
645 C normal3
646 C sub/large4
646 C sub/large4
647 C sub/normal4
647 C sub/normal4
648 C sub2/large6
648 C sub2/large6
649 C sub2/large7
649 C sub2/large7
650
650
651 Test that a standin can't be added as a large file
651 Test that a standin can't be added as a large file
652
652
653 $ touch large
653 $ touch large
654 $ hg add --large large
654 $ hg add --large large
655 $ hg ci -m "add"
655 $ hg ci -m "add"
656 Invoking status precommit hook
656 Invoking status precommit hook
657 A large
657 A large
658 Invoking status postcommit hook
658 Invoking status postcommit hook
659 C large
659 C large
660 C normal
660 C normal
661 C normal3
661 C normal3
662 C sub/large4
662 C sub/large4
663 C sub/normal4
663 C sub/normal4
664 C sub2/large6
664 C sub2/large6
665 C sub2/large7
665 C sub2/large7
666 $ hg remove large
666 $ hg remove large
667 $ touch large
667 $ touch large
668 $ hg addremove --config largefiles.patterns=**large --traceback
668 $ hg addremove --config largefiles.patterns=**large --traceback
669 adding large as a largefile
669 adding large as a largefile
670
670
671 Test that outgoing --large works (with revsets too)
671 Test that outgoing --large works (with revsets too)
672 $ hg outgoing --rev '.^' --large
672 $ hg outgoing --rev '.^' --large
673 comparing with $TESTTMP/a (glob)
673 comparing with $TESTTMP/a (glob)
674 searching for changes
674 searching for changes
675 changeset: 8:c02fd3b77ec4
675 changeset: 8:c02fd3b77ec4
676 user: test
676 user: test
677 date: Thu Jan 01 00:00:00 1970 +0000
677 date: Thu Jan 01 00:00:00 1970 +0000
678 summary: add foo
678 summary: add foo
679
679
680 changeset: 9:289dd08c9bbb
680 changeset: 9:289dd08c9bbb
681 user: test
681 user: test
682 date: Thu Jan 01 00:00:00 1970 +0000
682 date: Thu Jan 01 00:00:00 1970 +0000
683 summary: used to say nothing changed
683 summary: used to say nothing changed
684
684
685 changeset: 10:34f23ac6ac12
685 changeset: 10:34f23ac6ac12
686 user: test
686 user: test
687 date: Thu Jan 01 00:00:00 1970 +0000
687 date: Thu Jan 01 00:00:00 1970 +0000
688 summary: added
688 summary: added
689
689
690 changeset: 12:710c1b2f523c
690 changeset: 12:710c1b2f523c
691 parent: 10:34f23ac6ac12
691 parent: 10:34f23ac6ac12
692 user: test
692 user: test
693 date: Thu Jan 01 00:00:00 1970 +0000
693 date: Thu Jan 01 00:00:00 1970 +0000
694 summary: removed large
694 summary: removed large
695
695
696 changeset: 13:0a3e75774479
696 changeset: 13:0a3e75774479
697 user: test
697 user: test
698 date: Thu Jan 01 00:00:00 1970 +0000
698 date: Thu Jan 01 00:00:00 1970 +0000
699 summary: this used to add large8 as normal and commit both
699 summary: this used to add large8 as normal and commit both
700
700
701 changeset: 14:84f3d378175c
701 changeset: 14:84f3d378175c
702 user: test
702 user: test
703 date: Thu Jan 01 00:00:00 1970 +0000
703 date: Thu Jan 01 00:00:00 1970 +0000
704 summary: this used to not notice the rm
704 summary: this used to not notice the rm
705
705
706 searching for changes
706 searching for changes
707 largefiles to upload:
707 largefiles to upload:
708 foo
708 foo
709 large
709 large
710 large8
710 large8
711
711
712 $ cd ../a
712 $ cd ../a
713
713
714 Clone a largefiles repo.
714 Clone a largefiles repo.
715
715
716 $ hg clone . ../b
716 $ hg clone . ../b
717 updating to branch default
717 updating to branch default
718 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
719 getting changed largefiles
718 getting changed largefiles
720 3 largefiles updated, 0 removed
719 3 largefiles updated, 0 removed
720 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
721 $ cd ../b
721 $ cd ../b
722 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
722 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
723 7:daea875e9014 add/edit more largefiles
723 7:daea875e9014 add/edit more largefiles
724 6:4355d653f84f edit files yet again
724 6:4355d653f84f edit files yet again
725 5:9d5af5072dbd edit files again
725 5:9d5af5072dbd edit files again
726 4:74c02385b94c move files
726 4:74c02385b94c move files
727 3:9e8fbc4bce62 copy files
727 3:9e8fbc4bce62 copy files
728 2:51a0ae4d5864 remove files
728 2:51a0ae4d5864 remove files
729 1:ce8896473775 edit files
729 1:ce8896473775 edit files
730 0:30d30fe6a5be add files
730 0:30d30fe6a5be add files
731 $ cat normal3
731 $ cat normal3
732 normal33
732 normal33
733 $ cat sub/normal4
733 $ cat sub/normal4
734 normal44
734 normal44
735 $ cat sub/large4
735 $ cat sub/large4
736 large44
736 large44
737 $ cat sub2/large6
737 $ cat sub2/large6
738 large6
738 large6
739 $ cat sub2/large7
739 $ cat sub2/large7
740 large7
740 large7
741 $ cd ..
741 $ cd ..
742 $ hg clone a -r 3 c
742 $ hg clone a -r 3 c
743 adding changesets
743 adding changesets
744 adding manifests
744 adding manifests
745 adding file changes
745 adding file changes
746 added 4 changesets with 10 changes to 4 files
746 added 4 changesets with 10 changes to 4 files
747 updating to branch default
747 updating to branch default
748 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
749 getting changed largefiles
748 getting changed largefiles
750 2 largefiles updated, 0 removed
749 2 largefiles updated, 0 removed
750 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
751 $ cd c
751 $ cd c
752 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
752 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
753 3:9e8fbc4bce62 copy files
753 3:9e8fbc4bce62 copy files
754 2:51a0ae4d5864 remove files
754 2:51a0ae4d5864 remove files
755 1:ce8896473775 edit files
755 1:ce8896473775 edit files
756 0:30d30fe6a5be add files
756 0:30d30fe6a5be add files
757 $ cat normal1
757 $ cat normal1
758 normal22
758 normal22
759 $ cat large1
759 $ cat large1
760 large22
760 large22
761 $ cat sub/normal2
761 $ cat sub/normal2
762 normal22
762 normal22
763 $ cat sub/large2
763 $ cat sub/large2
764 large22
764 large22
765
765
766 Old revisions of a clone have correct largefiles content (this also
766 Old revisions of a clone have correct largefiles content (this also
767 tests update).
767 tests update).
768
768
769 $ hg update -r 1
769 $ hg update -r 1
770 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
771 getting changed largefiles
770 getting changed largefiles
772 1 largefiles updated, 0 removed
771 1 largefiles updated, 0 removed
772 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
773 $ cat large1
773 $ cat large1
774 large11
774 large11
775 $ cat sub/large2
775 $ cat sub/large2
776 large22
776 large22
777 $ cd ..
777 $ cd ..
778
778
779 Test cloning with --all-largefiles flag
779 Test cloning with --all-largefiles flag
780
780
781 $ rm "${USERCACHE}"/*
781 $ rm "${USERCACHE}"/*
782 $ hg clone --all-largefiles a a-backup
782 $ hg clone --all-largefiles a a-backup
783 updating to branch default
783 updating to branch default
784 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
785 getting changed largefiles
784 getting changed largefiles
786 3 largefiles updated, 0 removed
785 3 largefiles updated, 0 removed
786 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
787 8 additional largefiles cached
787 8 additional largefiles cached
788
788
789 $ rm "${USERCACHE}"/*
789 $ rm "${USERCACHE}"/*
790 $ hg clone --all-largefiles -u 0 a a-clone0
790 $ hg clone --all-largefiles -u 0 a a-clone0
791 updating to branch default
791 updating to branch default
792 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
793 getting changed largefiles
792 getting changed largefiles
794 2 largefiles updated, 0 removed
793 2 largefiles updated, 0 removed
794 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
795 9 additional largefiles cached
795 9 additional largefiles cached
796 $ hg -R a-clone0 sum
796 $ hg -R a-clone0 sum
797 parent: 0:30d30fe6a5be
797 parent: 0:30d30fe6a5be
798 add files
798 add files
799 branch: default
799 branch: default
800 commit: (clean)
800 commit: (clean)
801 update: 7 new changesets (update)
801 update: 7 new changesets (update)
802
802
803 $ rm "${USERCACHE}"/*
803 $ rm "${USERCACHE}"/*
804 $ hg clone --all-largefiles -u 1 a a-clone1
804 $ hg clone --all-largefiles -u 1 a a-clone1
805 updating to branch default
805 updating to branch default
806 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
807 getting changed largefiles
806 getting changed largefiles
808 2 largefiles updated, 0 removed
807 2 largefiles updated, 0 removed
808 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
809 8 additional largefiles cached
809 8 additional largefiles cached
810 $ hg -R a-clone1 sum
810 $ hg -R a-clone1 sum
811 parent: 1:ce8896473775
811 parent: 1:ce8896473775
812 edit files
812 edit files
813 branch: default
813 branch: default
814 commit: (clean)
814 commit: (clean)
815 update: 6 new changesets (update)
815 update: 6 new changesets (update)
816
816
817 $ rm "${USERCACHE}"/*
817 $ rm "${USERCACHE}"/*
818 $ hg clone --all-largefiles -U a a-clone-u
818 $ hg clone --all-largefiles -U a a-clone-u
819 11 additional largefiles cached
819 11 additional largefiles cached
820 $ hg -R a-clone-u sum
820 $ hg -R a-clone-u sum
821 parent: -1:000000000000 (no revision checked out)
821 parent: -1:000000000000 (no revision checked out)
822 branch: default
822 branch: default
823 commit: (clean)
823 commit: (clean)
824 update: 8 new changesets (update)
824 update: 8 new changesets (update)
825
825
826 $ mkdir xyz
826 $ mkdir xyz
827 $ cd xyz
827 $ cd xyz
828 $ hg clone ../a
828 $ hg clone ../a
829 destination directory: a
829 destination directory: a
830 updating to branch default
830 updating to branch default
831 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
832 getting changed largefiles
831 getting changed largefiles
833 3 largefiles updated, 0 removed
832 3 largefiles updated, 0 removed
833 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
834 $ cd ..
834 $ cd ..
835
835
836 Ensure base clone command argument validation
836 Ensure base clone command argument validation
837
837
838 $ hg clone -U -u 0 a a-clone-failure
838 $ hg clone -U -u 0 a a-clone-failure
839 abort: cannot specify both --noupdate and --updaterev
839 abort: cannot specify both --noupdate and --updaterev
840 [255]
840 [255]
841
841
842 $ hg clone --all-largefiles a ssh://localhost/a
842 $ hg clone --all-largefiles a ssh://localhost/a
843 abort: --all-largefiles is incompatible with non-local destination ssh://localhost/a
843 abort: --all-largefiles is incompatible with non-local destination ssh://localhost/a
844 [255]
844 [255]
845
845
846 Test pulling with --all-largefiles flag. Also test that the largefiles are
846 Test pulling with --all-largefiles flag. Also test that the largefiles are
847 downloaded from 'default' instead of 'default-push' when no source is specified
847 downloaded from 'default' instead of 'default-push' when no source is specified
848 (issue3584)
848 (issue3584)
849
849
850 $ rm -Rf a-backup
850 $ rm -Rf a-backup
851 $ hg clone -r 1 a a-backup
851 $ hg clone -r 1 a a-backup
852 adding changesets
852 adding changesets
853 adding manifests
853 adding manifests
854 adding file changes
854 adding file changes
855 added 2 changesets with 8 changes to 4 files
855 added 2 changesets with 8 changes to 4 files
856 updating to branch default
856 updating to branch default
857 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
858 getting changed largefiles
857 getting changed largefiles
859 2 largefiles updated, 0 removed
858 2 largefiles updated, 0 removed
859 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
860 $ rm "${USERCACHE}"/*
860 $ rm "${USERCACHE}"/*
861 $ cd a-backup
861 $ cd a-backup
862 $ hg pull --all-largefiles --config paths.default-push=bogus/path
862 $ hg pull --all-largefiles --config paths.default-push=bogus/path
863 pulling from $TESTTMP/a (glob)
863 pulling from $TESTTMP/a (glob)
864 searching for changes
864 searching for changes
865 adding changesets
865 adding changesets
866 adding manifests
866 adding manifests
867 adding file changes
867 adding file changes
868 added 6 changesets with 16 changes to 8 files
868 added 6 changesets with 16 changes to 8 files
869 (run 'hg update' to get a working copy)
869 (run 'hg update' to get a working copy)
870 caching new largefiles
870 caching new largefiles
871 3 largefiles cached
871 3 largefiles cached
872 3 additional largefiles cached
872 3 additional largefiles cached
873 $ cd ..
873 $ cd ..
874
874
875 Rebasing between two repositories does not revert largefiles to old
875 Rebasing between two repositories does not revert largefiles to old
876 revisions (this was a very bad bug that took a lot of work to fix).
876 revisions (this was a very bad bug that took a lot of work to fix).
877
877
878 $ hg clone a d
878 $ hg clone a d
879 updating to branch default
879 updating to branch default
880 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
881 getting changed largefiles
880 getting changed largefiles
882 3 largefiles updated, 0 removed
881 3 largefiles updated, 0 removed
882 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
883 $ cd b
883 $ cd b
884 $ echo large4-modified > sub/large4
884 $ echo large4-modified > sub/large4
885 $ echo normal3-modified > normal3
885 $ echo normal3-modified > normal3
886 $ hg commit -m "modify normal file and largefile in repo b"
886 $ hg commit -m "modify normal file and largefile in repo b"
887 Invoking status precommit hook
887 Invoking status precommit hook
888 M normal3
888 M normal3
889 M sub/large4
889 M sub/large4
890 $ cd ../d
890 $ cd ../d
891 $ echo large6-modified > sub2/large6
891 $ echo large6-modified > sub2/large6
892 $ echo normal4-modified > sub/normal4
892 $ echo normal4-modified > sub/normal4
893 $ hg commit -m "modify normal file largefile in repo d"
893 $ hg commit -m "modify normal file largefile in repo d"
894 Invoking status precommit hook
894 Invoking status precommit hook
895 M sub/normal4
895 M sub/normal4
896 M sub2/large6
896 M sub2/large6
897 $ cd ..
897 $ cd ..
898 $ hg clone d e
898 $ hg clone d e
899 updating to branch default
899 updating to branch default
900 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
901 getting changed largefiles
900 getting changed largefiles
902 3 largefiles updated, 0 removed
901 3 largefiles updated, 0 removed
902 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
903 $ cd d
903 $ cd d
904
904
905 More rebase testing, but also test that the largefiles are downloaded from
905 More rebase testing, but also test that the largefiles are downloaded from
906 'default' instead of 'default-push' when no source is specified (issue3584).
906 'default' instead of 'default-push' when no source is specified (issue3584).
907 The error messages go away if repo 'b' is created with --all-largefiles.
907 The error messages go away if repo 'b' is created with --all-largefiles.
908 $ hg pull --rebase --all-largefiles --config paths.default-push=bogus/path --config paths.default=../b
908 $ hg pull --rebase --all-largefiles --config paths.default-push=bogus/path --config paths.default=../b
909 pulling from $TESTTMP/b (glob)
909 pulling from $TESTTMP/b (glob)
910 searching for changes
910 searching for changes
911 adding changesets
911 adding changesets
912 adding manifests
912 adding manifests
913 adding file changes
913 adding file changes
914 added 1 changesets with 2 changes to 2 files (+1 heads)
914 added 1 changesets with 2 changes to 2 files (+1 heads)
915 Invoking status precommit hook
915 Invoking status precommit hook
916 M sub/normal4
916 M sub/normal4
917 M sub2/large6
917 M sub2/large6
918 saved backup bundle to $TESTTMP/d/.hg/strip-backup/f574fb32bb45-backup.hg (glob)
918 saved backup bundle to $TESTTMP/d/.hg/strip-backup/f574fb32bb45-backup.hg (glob)
919 error getting eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 from file:$TESTTMP/b for large3: can't get file locally (glob)
919 error getting eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 from file:$TESTTMP/b for large3: can't get file locally (glob)
920 error getting eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 from file:$TESTTMP/b for sub/large4: can't get file locally (glob)
920 error getting eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 from file:$TESTTMP/b for sub/large4: can't get file locally (glob)
921 error getting eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 from file:$TESTTMP/b for large1: can't get file locally (glob)
921 error getting eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 from file:$TESTTMP/b for large1: can't get file locally (glob)
922 error getting eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 from file:$TESTTMP/b for sub/large2: can't get file locally (glob)
922 error getting eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 from file:$TESTTMP/b for sub/large2: can't get file locally (glob)
923 error getting eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 from file:$TESTTMP/b for sub/large2: can't get file locally (glob)
923 error getting eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 from file:$TESTTMP/b for sub/large2: can't get file locally (glob)
924 error getting 5f78770c0e77ba4287ad6ef3071c9bf9c379742f from file:$TESTTMP/b for large1: can't get file locally (glob)
924 error getting 5f78770c0e77ba4287ad6ef3071c9bf9c379742f from file:$TESTTMP/b for large1: can't get file locally (glob)
925 error getting eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 from file:$TESTTMP/b for sub/large2: can't get file locally (glob)
925 error getting eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 from file:$TESTTMP/b for sub/large2: can't get file locally (glob)
926 error getting 4669e532d5b2c093a78eca010077e708a071bb64 from file:$TESTTMP/b for large1: can't get file locally (glob)
926 error getting 4669e532d5b2c093a78eca010077e708a071bb64 from file:$TESTTMP/b for large1: can't get file locally (glob)
927 error getting 1deebade43c8c498a3c8daddac0244dc55d1331d from file:$TESTTMP/b for sub/large2: can't get file locally (glob)
927 error getting 1deebade43c8c498a3c8daddac0244dc55d1331d from file:$TESTTMP/b for sub/large2: can't get file locally (glob)
928 0 additional largefiles cached
928 0 additional largefiles cached
929 9 largefiles failed to download
929 9 largefiles failed to download
930 nothing to rebase
930 nothing to rebase
931 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
931 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
932 9:598410d3eb9a modify normal file largefile in repo d
932 9:598410d3eb9a modify normal file largefile in repo d
933 8:a381d2c8c80e modify normal file and largefile in repo b
933 8:a381d2c8c80e modify normal file and largefile in repo b
934 7:daea875e9014 add/edit more largefiles
934 7:daea875e9014 add/edit more largefiles
935 6:4355d653f84f edit files yet again
935 6:4355d653f84f edit files yet again
936 5:9d5af5072dbd edit files again
936 5:9d5af5072dbd edit files again
937 4:74c02385b94c move files
937 4:74c02385b94c move files
938 3:9e8fbc4bce62 copy files
938 3:9e8fbc4bce62 copy files
939 2:51a0ae4d5864 remove files
939 2:51a0ae4d5864 remove files
940 1:ce8896473775 edit files
940 1:ce8896473775 edit files
941 0:30d30fe6a5be add files
941 0:30d30fe6a5be add files
942 $ cat normal3
942 $ cat normal3
943 normal3-modified
943 normal3-modified
944 $ cat sub/normal4
944 $ cat sub/normal4
945 normal4-modified
945 normal4-modified
946 $ cat sub/large4
946 $ cat sub/large4
947 large4-modified
947 large4-modified
948 $ cat sub2/large6
948 $ cat sub2/large6
949 large6-modified
949 large6-modified
950 $ cat sub2/large7
950 $ cat sub2/large7
951 large7
951 large7
952 $ cd ../e
952 $ cd ../e
953 $ hg pull ../b
953 $ hg pull ../b
954 pulling from ../b
954 pulling from ../b
955 searching for changes
955 searching for changes
956 adding changesets
956 adding changesets
957 adding manifests
957 adding manifests
958 adding file changes
958 adding file changes
959 added 1 changesets with 2 changes to 2 files (+1 heads)
959 added 1 changesets with 2 changes to 2 files (+1 heads)
960 (run 'hg heads' to see heads, 'hg merge' to merge)
960 (run 'hg heads' to see heads, 'hg merge' to merge)
961 caching new largefiles
961 caching new largefiles
962 0 largefiles cached
962 0 largefiles cached
963 $ hg rebase
963 $ hg rebase
964 Invoking status precommit hook
964 Invoking status precommit hook
965 M sub/normal4
965 M sub/normal4
966 M sub2/large6
966 M sub2/large6
967 saved backup bundle to $TESTTMP/e/.hg/strip-backup/f574fb32bb45-backup.hg (glob)
967 saved backup bundle to $TESTTMP/e/.hg/strip-backup/f574fb32bb45-backup.hg (glob)
968 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
968 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
969 9:598410d3eb9a modify normal file largefile in repo d
969 9:598410d3eb9a modify normal file largefile in repo d
970 8:a381d2c8c80e modify normal file and largefile in repo b
970 8:a381d2c8c80e modify normal file and largefile in repo b
971 7:daea875e9014 add/edit more largefiles
971 7:daea875e9014 add/edit more largefiles
972 6:4355d653f84f edit files yet again
972 6:4355d653f84f edit files yet again
973 5:9d5af5072dbd edit files again
973 5:9d5af5072dbd edit files again
974 4:74c02385b94c move files
974 4:74c02385b94c move files
975 3:9e8fbc4bce62 copy files
975 3:9e8fbc4bce62 copy files
976 2:51a0ae4d5864 remove files
976 2:51a0ae4d5864 remove files
977 1:ce8896473775 edit files
977 1:ce8896473775 edit files
978 0:30d30fe6a5be add files
978 0:30d30fe6a5be add files
979 $ cat normal3
979 $ cat normal3
980 normal3-modified
980 normal3-modified
981 $ cat sub/normal4
981 $ cat sub/normal4
982 normal4-modified
982 normal4-modified
983 $ cat sub/large4
983 $ cat sub/large4
984 large4-modified
984 large4-modified
985 $ cat sub2/large6
985 $ cat sub2/large6
986 large6-modified
986 large6-modified
987 $ cat sub2/large7
987 $ cat sub2/large7
988 large7
988 large7
989
989
990 Log on largefiles
990 Log on largefiles
991
991
992 - same output
992 - same output
993 $ hg log --template '{rev}:{node|short} {desc|firstline}\n' .hglf/sub/large4
993 $ hg log --template '{rev}:{node|short} {desc|firstline}\n' .hglf/sub/large4
994 8:a381d2c8c80e modify normal file and largefile in repo b
994 8:a381d2c8c80e modify normal file and largefile in repo b
995 6:4355d653f84f edit files yet again
995 6:4355d653f84f edit files yet again
996 5:9d5af5072dbd edit files again
996 5:9d5af5072dbd edit files again
997 4:74c02385b94c move files
997 4:74c02385b94c move files
998 $ hg log --template '{rev}:{node|short} {desc|firstline}\n' sub/large4
998 $ hg log --template '{rev}:{node|short} {desc|firstline}\n' sub/large4
999 8:a381d2c8c80e modify normal file and largefile in repo b
999 8:a381d2c8c80e modify normal file and largefile in repo b
1000 6:4355d653f84f edit files yet again
1000 6:4355d653f84f edit files yet again
1001 5:9d5af5072dbd edit files again
1001 5:9d5af5072dbd edit files again
1002 4:74c02385b94c move files
1002 4:74c02385b94c move files
1003
1003
1004 - .hglf only matches largefiles, without .hglf it matches 9 bco sub/normal
1004 - .hglf only matches largefiles, without .hglf it matches 9 bco sub/normal
1005 $ hg log --template '{rev}:{node|short} {desc|firstline}\n' .hglf/sub
1005 $ hg log --template '{rev}:{node|short} {desc|firstline}\n' .hglf/sub
1006 8:a381d2c8c80e modify normal file and largefile in repo b
1006 8:a381d2c8c80e modify normal file and largefile in repo b
1007 6:4355d653f84f edit files yet again
1007 6:4355d653f84f edit files yet again
1008 5:9d5af5072dbd edit files again
1008 5:9d5af5072dbd edit files again
1009 4:74c02385b94c move files
1009 4:74c02385b94c move files
1010 1:ce8896473775 edit files
1010 1:ce8896473775 edit files
1011 0:30d30fe6a5be add files
1011 0:30d30fe6a5be add files
1012 $ hg log --template '{rev}:{node|short} {desc|firstline}\n' sub
1012 $ hg log --template '{rev}:{node|short} {desc|firstline}\n' sub
1013 9:598410d3eb9a modify normal file largefile in repo d
1013 9:598410d3eb9a modify normal file largefile in repo d
1014 8:a381d2c8c80e modify normal file and largefile in repo b
1014 8:a381d2c8c80e modify normal file and largefile in repo b
1015 6:4355d653f84f edit files yet again
1015 6:4355d653f84f edit files yet again
1016 5:9d5af5072dbd edit files again
1016 5:9d5af5072dbd edit files again
1017 4:74c02385b94c move files
1017 4:74c02385b94c move files
1018 1:ce8896473775 edit files
1018 1:ce8896473775 edit files
1019 0:30d30fe6a5be add files
1019 0:30d30fe6a5be add files
1020
1020
1021 - globbing gives same result
1021 - globbing gives same result
1022 $ hg log --template '{rev}:{node|short} {desc|firstline}\n' 'glob:sub/*'
1022 $ hg log --template '{rev}:{node|short} {desc|firstline}\n' 'glob:sub/*'
1023 9:598410d3eb9a modify normal file largefile in repo d
1023 9:598410d3eb9a modify normal file largefile in repo d
1024 8:a381d2c8c80e modify normal file and largefile in repo b
1024 8:a381d2c8c80e modify normal file and largefile in repo b
1025 6:4355d653f84f edit files yet again
1025 6:4355d653f84f edit files yet again
1026 5:9d5af5072dbd edit files again
1026 5:9d5af5072dbd edit files again
1027 4:74c02385b94c move files
1027 4:74c02385b94c move files
1028 1:ce8896473775 edit files
1028 1:ce8896473775 edit files
1029 0:30d30fe6a5be add files
1029 0:30d30fe6a5be add files
1030
1030
1031 Rollback on largefiles.
1031 Rollback on largefiles.
1032
1032
1033 $ echo large4-modified-again > sub/large4
1033 $ echo large4-modified-again > sub/large4
1034 $ hg commit -m "Modify large4 again"
1034 $ hg commit -m "Modify large4 again"
1035 Invoking status precommit hook
1035 Invoking status precommit hook
1036 M sub/large4
1036 M sub/large4
1037 $ hg rollback
1037 $ hg rollback
1038 repository tip rolled back to revision 9 (undo commit)
1038 repository tip rolled back to revision 9 (undo commit)
1039 working directory now based on revision 9
1039 working directory now based on revision 9
1040 $ hg st
1040 $ hg st
1041 M sub/large4
1041 M sub/large4
1042 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
1042 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
1043 9:598410d3eb9a modify normal file largefile in repo d
1043 9:598410d3eb9a modify normal file largefile in repo d
1044 8:a381d2c8c80e modify normal file and largefile in repo b
1044 8:a381d2c8c80e modify normal file and largefile in repo b
1045 7:daea875e9014 add/edit more largefiles
1045 7:daea875e9014 add/edit more largefiles
1046 6:4355d653f84f edit files yet again
1046 6:4355d653f84f edit files yet again
1047 5:9d5af5072dbd edit files again
1047 5:9d5af5072dbd edit files again
1048 4:74c02385b94c move files
1048 4:74c02385b94c move files
1049 3:9e8fbc4bce62 copy files
1049 3:9e8fbc4bce62 copy files
1050 2:51a0ae4d5864 remove files
1050 2:51a0ae4d5864 remove files
1051 1:ce8896473775 edit files
1051 1:ce8896473775 edit files
1052 0:30d30fe6a5be add files
1052 0:30d30fe6a5be add files
1053 $ cat sub/large4
1053 $ cat sub/large4
1054 large4-modified-again
1054 large4-modified-again
1055
1055
1056 "update --check" refuses to update with uncommitted changes.
1056 "update --check" refuses to update with uncommitted changes.
1057 $ hg update --check 8
1057 $ hg update --check 8
1058 abort: uncommitted local changes
1058 abort: uncommitted local changes
1059 [255]
1059 [255]
1060
1060
1061 "update --clean" leaves correct largefiles in working copy, even when there is
1061 "update --clean" leaves correct largefiles in working copy, even when there is
1062 .orig files from revert in .hglf.
1062 .orig files from revert in .hglf.
1063
1063
1064 $ echo mistake > sub2/large7
1064 $ echo mistake > sub2/large7
1065 $ hg revert sub2/large7
1065 $ hg revert sub2/large7
1066 $ hg -q update --clean -r null
1066 $ hg -q update --clean -r null
1067 $ hg update --clean
1067 $ hg update --clean
1068 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1069 getting changed largefiles
1068 getting changed largefiles
1070 3 largefiles updated, 0 removed
1069 3 largefiles updated, 0 removed
1070 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1071 $ cat normal3
1071 $ cat normal3
1072 normal3-modified
1072 normal3-modified
1073 $ cat sub/normal4
1073 $ cat sub/normal4
1074 normal4-modified
1074 normal4-modified
1075 $ cat sub/large4
1075 $ cat sub/large4
1076 large4-modified
1076 large4-modified
1077 $ cat sub2/large6
1077 $ cat sub2/large6
1078 large6-modified
1078 large6-modified
1079 $ cat sub2/large7
1079 $ cat sub2/large7
1080 large7
1080 large7
1081 $ cat sub2/large7.orig
1081 $ cat sub2/large7.orig
1082 mistake
1082 mistake
1083 $ cat .hglf/sub2/large7.orig
1083 $ cat .hglf/sub2/large7.orig
1084 9dbfb2c79b1c40981b258c3efa1b10b03f18ad31
1084 9dbfb2c79b1c40981b258c3efa1b10b03f18ad31
1085
1085
1086 demonstrate misfeature: .orig file is overwritten on every update -C,
1086 demonstrate misfeature: .orig file is overwritten on every update -C,
1087 also when clean:
1087 also when clean:
1088 $ hg update --clean
1088 $ hg update --clean
1089 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1090 getting changed largefiles
1089 getting changed largefiles
1091 0 largefiles updated, 0 removed
1090 0 largefiles updated, 0 removed
1091 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1092 $ cat sub2/large7.orig
1092 $ cat sub2/large7.orig
1093 large7
1093 large7
1094 $ rm sub2/large7.orig .hglf/sub2/large7.orig
1094 $ rm sub2/large7.orig .hglf/sub2/large7.orig
1095
1095
1096 Now "update check" is happy.
1096 Now "update check" is happy.
1097 $ hg update --check 8
1097 $ hg update --check 8
1098 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1099 getting changed largefiles
1098 getting changed largefiles
1100 1 largefiles updated, 0 removed
1099 1 largefiles updated, 0 removed
1100 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1101 $ hg update --check
1101 $ hg update --check
1102 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1103 getting changed largefiles
1102 getting changed largefiles
1104 1 largefiles updated, 0 removed
1103 1 largefiles updated, 0 removed
1104 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1105
1105
1106 Test removing empty largefiles directories on update
1106 Test removing empty largefiles directories on update
1107 $ test -d sub2 && echo "sub2 exists"
1107 $ test -d sub2 && echo "sub2 exists"
1108 sub2 exists
1108 sub2 exists
1109 $ hg update -q null
1109 $ hg update -q null
1110 $ test -d sub2 && echo "error: sub2 should not exist anymore"
1110 $ test -d sub2 && echo "error: sub2 should not exist anymore"
1111 [1]
1111 [1]
1112 $ hg update -q
1112 $ hg update -q
1113
1113
1114 Test hg remove removes empty largefiles directories
1114 Test hg remove removes empty largefiles directories
1115 $ test -d sub2 && echo "sub2 exists"
1115 $ test -d sub2 && echo "sub2 exists"
1116 sub2 exists
1116 sub2 exists
1117 $ hg remove sub2/*
1117 $ hg remove sub2/*
1118 $ test -d sub2 && echo "error: sub2 should not exist anymore"
1118 $ test -d sub2 && echo "error: sub2 should not exist anymore"
1119 [1]
1119 [1]
1120 $ hg revert sub2/large6 sub2/large7
1120 $ hg revert sub2/large6 sub2/large7
1121
1121
1122 "revert" works on largefiles (and normal files too).
1122 "revert" works on largefiles (and normal files too).
1123 $ echo hack3 >> normal3
1123 $ echo hack3 >> normal3
1124 $ echo hack4 >> sub/normal4
1124 $ echo hack4 >> sub/normal4
1125 $ echo hack4 >> sub/large4
1125 $ echo hack4 >> sub/large4
1126 $ rm sub2/large6
1126 $ rm sub2/large6
1127 $ hg revert sub2/large6
1127 $ hg revert sub2/large6
1128 $ hg rm sub2/large6
1128 $ hg rm sub2/large6
1129 $ echo new >> sub2/large8
1129 $ echo new >> sub2/large8
1130 $ hg add --large sub2/large8
1130 $ hg add --large sub2/large8
1131 # XXX we don't really want to report that we're reverting the standin;
1131 # XXX we don't really want to report that we're reverting the standin;
1132 # that's just an implementation detail. But I don't see an obvious fix. ;-(
1132 # that's just an implementation detail. But I don't see an obvious fix. ;-(
1133 $ hg revert sub
1133 $ hg revert sub
1134 reverting .hglf/sub/large4 (glob)
1134 reverting .hglf/sub/large4 (glob)
1135 reverting sub/normal4 (glob)
1135 reverting sub/normal4 (glob)
1136 $ hg status
1136 $ hg status
1137 M normal3
1137 M normal3
1138 A sub2/large8
1138 A sub2/large8
1139 R sub2/large6
1139 R sub2/large6
1140 ? sub/large4.orig
1140 ? sub/large4.orig
1141 ? sub/normal4.orig
1141 ? sub/normal4.orig
1142 $ cat sub/normal4
1142 $ cat sub/normal4
1143 normal4-modified
1143 normal4-modified
1144 $ cat sub/large4
1144 $ cat sub/large4
1145 large4-modified
1145 large4-modified
1146 $ hg revert -a --no-backup
1146 $ hg revert -a --no-backup
1147 undeleting .hglf/sub2/large6 (glob)
1147 undeleting .hglf/sub2/large6 (glob)
1148 forgetting .hglf/sub2/large8 (glob)
1148 forgetting .hglf/sub2/large8 (glob)
1149 reverting normal3
1149 reverting normal3
1150 $ hg status
1150 $ hg status
1151 ? sub/large4.orig
1151 ? sub/large4.orig
1152 ? sub/normal4.orig
1152 ? sub/normal4.orig
1153 ? sub2/large8
1153 ? sub2/large8
1154 $ cat normal3
1154 $ cat normal3
1155 normal3-modified
1155 normal3-modified
1156 $ cat sub2/large6
1156 $ cat sub2/large6
1157 large6-modified
1157 large6-modified
1158 $ rm sub/*.orig sub2/large8
1158 $ rm sub/*.orig sub2/large8
1159
1159
1160 revert some files to an older revision
1160 revert some files to an older revision
1161 $ hg revert --no-backup -r 8 sub2
1161 $ hg revert --no-backup -r 8 sub2
1162 reverting .hglf/sub2/large6 (glob)
1162 reverting .hglf/sub2/large6 (glob)
1163 $ cat sub2/large6
1163 $ cat sub2/large6
1164 large6
1164 large6
1165 $ hg revert --no-backup -C -r '.^' sub2
1165 $ hg revert --no-backup -C -r '.^' sub2
1166 reverting .hglf/sub2/large6 (glob)
1166 reverting .hglf/sub2/large6 (glob)
1167 $ hg revert --no-backup sub2
1167 $ hg revert --no-backup sub2
1168 reverting .hglf/sub2/large6 (glob)
1168 reverting .hglf/sub2/large6 (glob)
1169 $ hg status
1169 $ hg status
1170
1170
1171 "verify --large" actually verifies largefiles
1171 "verify --large" actually verifies largefiles
1172
1172
1173 $ hg verify --large
1173 $ hg verify --large
1174 checking changesets
1174 checking changesets
1175 checking manifests
1175 checking manifests
1176 crosschecking files in changesets and manifests
1176 crosschecking files in changesets and manifests
1177 checking files
1177 checking files
1178 10 files, 10 changesets, 28 total revisions
1178 10 files, 10 changesets, 28 total revisions
1179 searching 1 changesets for largefiles
1179 searching 1 changesets for largefiles
1180 verified existence of 3 revisions of 3 largefiles
1180 verified existence of 3 revisions of 3 largefiles
1181
1181
1182 Merging does not revert to old versions of largefiles and also check
1182 Merging does not revert to old versions of largefiles and also check
1183 that merging after having pulled from a non-default remote works
1183 that merging after having pulled from a non-default remote works
1184 correctly.
1184 correctly.
1185
1185
1186 $ cd ..
1186 $ cd ..
1187 $ hg clone -r 7 e temp
1187 $ hg clone -r 7 e temp
1188 adding changesets
1188 adding changesets
1189 adding manifests
1189 adding manifests
1190 adding file changes
1190 adding file changes
1191 added 8 changesets with 24 changes to 10 files
1191 added 8 changesets with 24 changes to 10 files
1192 updating to branch default
1192 updating to branch default
1193 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1194 getting changed largefiles
1193 getting changed largefiles
1195 3 largefiles updated, 0 removed
1194 3 largefiles updated, 0 removed
1195 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1196 $ hg clone temp f
1196 $ hg clone temp f
1197 updating to branch default
1197 updating to branch default
1198 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1199 getting changed largefiles
1198 getting changed largefiles
1200 3 largefiles updated, 0 removed
1199 3 largefiles updated, 0 removed
1200 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1201 # Delete the largefiles in the largefiles system cache so that we have an
1201 # Delete the largefiles in the largefiles system cache so that we have an
1202 # opportunity to test that caching after a pull works.
1202 # opportunity to test that caching after a pull works.
1203 $ rm "${USERCACHE}"/*
1203 $ rm "${USERCACHE}"/*
1204 $ cd f
1204 $ cd f
1205 $ echo "large4-merge-test" > sub/large4
1205 $ echo "large4-merge-test" > sub/large4
1206 $ hg commit -m "Modify large4 to test merge"
1206 $ hg commit -m "Modify large4 to test merge"
1207 Invoking status precommit hook
1207 Invoking status precommit hook
1208 M sub/large4
1208 M sub/large4
1209 $ hg pull ../e
1209 $ hg pull ../e
1210 pulling from ../e
1210 pulling from ../e
1211 searching for changes
1211 searching for changes
1212 adding changesets
1212 adding changesets
1213 adding manifests
1213 adding manifests
1214 adding file changes
1214 adding file changes
1215 added 2 changesets with 4 changes to 4 files (+1 heads)
1215 added 2 changesets with 4 changes to 4 files (+1 heads)
1216 (run 'hg heads' to see heads, 'hg merge' to merge)
1216 (run 'hg heads' to see heads, 'hg merge' to merge)
1217 caching new largefiles
1217 caching new largefiles
1218 2 largefiles cached
1218 2 largefiles cached
1219 $ hg merge
1219 $ hg merge
1220 merging sub/large4
1220 merging sub/large4
1221 largefile sub/large4 has a merge conflict
1221 largefile sub/large4 has a merge conflict
1222 keep (l)ocal or take (o)ther? l
1222 keep (l)ocal or take (o)ther? l
1223 3 files updated, 1 files merged, 0 files removed, 0 files unresolved
1223 3 files updated, 1 files merged, 0 files removed, 0 files unresolved
1224 (branch merge, don't forget to commit)
1224 (branch merge, don't forget to commit)
1225 getting changed largefiles
1225 getting changed largefiles
1226 1 largefiles updated, 0 removed
1226 1 largefiles updated, 0 removed
1227 $ hg commit -m "Merge repos e and f"
1227 $ hg commit -m "Merge repos e and f"
1228 Invoking status precommit hook
1228 Invoking status precommit hook
1229 M normal3
1229 M normal3
1230 M sub/normal4
1230 M sub/normal4
1231 M sub2/large6
1231 M sub2/large6
1232 $ cat normal3
1232 $ cat normal3
1233 normal3-modified
1233 normal3-modified
1234 $ cat sub/normal4
1234 $ cat sub/normal4
1235 normal4-modified
1235 normal4-modified
1236 $ cat sub/large4
1236 $ cat sub/large4
1237 large4-merge-test
1237 large4-merge-test
1238 $ cat sub2/large6
1238 $ cat sub2/large6
1239 large6-modified
1239 large6-modified
1240 $ cat sub2/large7
1240 $ cat sub2/large7
1241 large7
1241 large7
1242
1242
1243 Test status after merging with a branch that introduces a new largefile:
1243 Test status after merging with a branch that introduces a new largefile:
1244
1244
1245 $ echo large > large
1245 $ echo large > large
1246 $ hg add --large large
1246 $ hg add --large large
1247 $ hg commit -m 'add largefile'
1247 $ hg commit -m 'add largefile'
1248 Invoking status precommit hook
1248 Invoking status precommit hook
1249 A large
1249 A large
1250 $ hg update -q ".^"
1250 $ hg update -q ".^"
1251 $ echo change >> normal3
1251 $ echo change >> normal3
1252 $ hg commit -m 'some change'
1252 $ hg commit -m 'some change'
1253 Invoking status precommit hook
1253 Invoking status precommit hook
1254 M normal3
1254 M normal3
1255 created new head
1255 created new head
1256 $ hg merge
1256 $ hg merge
1257 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1257 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1258 (branch merge, don't forget to commit)
1258 (branch merge, don't forget to commit)
1259 getting changed largefiles
1259 getting changed largefiles
1260 1 largefiles updated, 0 removed
1260 1 largefiles updated, 0 removed
1261 $ hg status
1261 $ hg status
1262 M large
1262 M large
1263
1263
1264 - make sure update of merge with removed largefiles fails as expected
1264 - make sure update of merge with removed largefiles fails as expected
1265 $ hg rm sub2/large6
1265 $ hg rm sub2/large6
1266 $ hg up -r.
1266 $ hg up -r.
1267 abort: outstanding uncommitted merges
1267 abort: outstanding uncommitted merges
1268 [255]
1268 [255]
1269
1269
1270 - revert should be able to revert files introduced in a pending merge
1270 - revert should be able to revert files introduced in a pending merge
1271 $ hg revert --all -r .
1271 $ hg revert --all -r .
1272 removing .hglf/large
1272 removing .hglf/large
1273 undeleting .hglf/sub2/large6
1273 undeleting .hglf/sub2/large6
1274
1274
1275 Test that a normal file and a largefile with the same name and path cannot
1275 Test that a normal file and a largefile with the same name and path cannot
1276 coexist.
1276 coexist.
1277
1277
1278 $ rm sub2/large7
1278 $ rm sub2/large7
1279 $ echo "largeasnormal" > sub2/large7
1279 $ echo "largeasnormal" > sub2/large7
1280 $ hg add sub2/large7
1280 $ hg add sub2/large7
1281 sub2/large7 already a largefile
1281 sub2/large7 already a largefile
1282
1282
1283 Test that transplanting a largefile change works correctly.
1283 Test that transplanting a largefile change works correctly.
1284
1284
1285 $ cd ..
1285 $ cd ..
1286 $ hg clone -r 8 d g
1286 $ hg clone -r 8 d g
1287 adding changesets
1287 adding changesets
1288 adding manifests
1288 adding manifests
1289 adding file changes
1289 adding file changes
1290 added 9 changesets with 26 changes to 10 files
1290 added 9 changesets with 26 changes to 10 files
1291 updating to branch default
1291 updating to branch default
1292 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1293 getting changed largefiles
1292 getting changed largefiles
1294 3 largefiles updated, 0 removed
1293 3 largefiles updated, 0 removed
1294 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1295 $ cd g
1295 $ cd g
1296 $ hg transplant -s ../d 598410d3eb9a
1296 $ hg transplant -s ../d 598410d3eb9a
1297 searching for changes
1297 searching for changes
1298 searching for changes
1298 searching for changes
1299 adding changesets
1299 adding changesets
1300 adding manifests
1300 adding manifests
1301 adding file changes
1301 adding file changes
1302 added 1 changesets with 2 changes to 2 files
1302 added 1 changesets with 2 changes to 2 files
1303 getting changed largefiles
1303 getting changed largefiles
1304 1 largefiles updated, 0 removed
1304 1 largefiles updated, 0 removed
1305 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
1305 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
1306 9:598410d3eb9a modify normal file largefile in repo d
1306 9:598410d3eb9a modify normal file largefile in repo d
1307 8:a381d2c8c80e modify normal file and largefile in repo b
1307 8:a381d2c8c80e modify normal file and largefile in repo b
1308 7:daea875e9014 add/edit more largefiles
1308 7:daea875e9014 add/edit more largefiles
1309 6:4355d653f84f edit files yet again
1309 6:4355d653f84f edit files yet again
1310 5:9d5af5072dbd edit files again
1310 5:9d5af5072dbd edit files again
1311 4:74c02385b94c move files
1311 4:74c02385b94c move files
1312 3:9e8fbc4bce62 copy files
1312 3:9e8fbc4bce62 copy files
1313 2:51a0ae4d5864 remove files
1313 2:51a0ae4d5864 remove files
1314 1:ce8896473775 edit files
1314 1:ce8896473775 edit files
1315 0:30d30fe6a5be add files
1315 0:30d30fe6a5be add files
1316 $ cat normal3
1316 $ cat normal3
1317 normal3-modified
1317 normal3-modified
1318 $ cat sub/normal4
1318 $ cat sub/normal4
1319 normal4-modified
1319 normal4-modified
1320 $ cat sub/large4
1320 $ cat sub/large4
1321 large4-modified
1321 large4-modified
1322 $ cat sub2/large6
1322 $ cat sub2/large6
1323 large6-modified
1323 large6-modified
1324 $ cat sub2/large7
1324 $ cat sub2/large7
1325 large7
1325 large7
1326
1326
1327 Cat a largefile
1327 Cat a largefile
1328 $ hg cat normal3
1328 $ hg cat normal3
1329 normal3-modified
1329 normal3-modified
1330 $ hg cat sub/large4
1330 $ hg cat sub/large4
1331 large4-modified
1331 large4-modified
1332 $ rm "${USERCACHE}"/*
1332 $ rm "${USERCACHE}"/*
1333 $ hg cat -r a381d2c8c80e -o cat.out sub/large4
1333 $ hg cat -r a381d2c8c80e -o cat.out sub/large4
1334 $ cat cat.out
1334 $ cat cat.out
1335 large4-modified
1335 large4-modified
1336 $ rm cat.out
1336 $ rm cat.out
1337 $ hg cat -r a381d2c8c80e normal3
1337 $ hg cat -r a381d2c8c80e normal3
1338 normal3-modified
1338 normal3-modified
1339 $ hg cat -r '.^' normal3
1339 $ hg cat -r '.^' normal3
1340 normal3-modified
1340 normal3-modified
1341 $ hg cat -r '.^' sub/large4
1341 $ hg cat -r '.^' sub/large4
1342 large4-modified
1342 large4-modified
1343
1343
1344 Test that renaming a largefile results in correct output for status
1344 Test that renaming a largefile results in correct output for status
1345
1345
1346 $ hg rename sub/large4 large4-renamed
1346 $ hg rename sub/large4 large4-renamed
1347 $ hg commit -m "test rename output"
1347 $ hg commit -m "test rename output"
1348 Invoking status precommit hook
1348 Invoking status precommit hook
1349 A large4-renamed
1349 A large4-renamed
1350 R sub/large4
1350 R sub/large4
1351 $ cat large4-renamed
1351 $ cat large4-renamed
1352 large4-modified
1352 large4-modified
1353 $ cd sub2
1353 $ cd sub2
1354 $ hg rename large6 large6-renamed
1354 $ hg rename large6 large6-renamed
1355 $ hg st
1355 $ hg st
1356 A sub2/large6-renamed
1356 A sub2/large6-renamed
1357 R sub2/large6
1357 R sub2/large6
1358 $ cd ..
1358 $ cd ..
1359
1359
1360 Test --normal flag
1360 Test --normal flag
1361
1361
1362 $ dd if=/dev/zero bs=2k count=11k > new-largefile 2> /dev/null
1362 $ dd if=/dev/zero bs=2k count=11k > new-largefile 2> /dev/null
1363 $ hg add --normal --large new-largefile
1363 $ hg add --normal --large new-largefile
1364 abort: --normal cannot be used with --large
1364 abort: --normal cannot be used with --large
1365 [255]
1365 [255]
1366 $ hg add --normal new-largefile
1366 $ hg add --normal new-largefile
1367 new-largefile: up to 69 MB of RAM may be required to manage this file
1367 new-largefile: up to 69 MB of RAM may be required to manage this file
1368 (use 'hg revert new-largefile' to cancel the pending addition)
1368 (use 'hg revert new-largefile' to cancel the pending addition)
1369 $ cd ..
1369 $ cd ..
1370
1370
1371 #if serve
1371 #if serve
1372 vanilla clients not locked out from largefiles servers on vanilla repos
1372 vanilla clients not locked out from largefiles servers on vanilla repos
1373 $ mkdir r1
1373 $ mkdir r1
1374 $ cd r1
1374 $ cd r1
1375 $ hg init
1375 $ hg init
1376 $ echo c1 > f1
1376 $ echo c1 > f1
1377 $ hg add f1
1377 $ hg add f1
1378 $ hg commit -m "m1"
1378 $ hg commit -m "m1"
1379 Invoking status precommit hook
1379 Invoking status precommit hook
1380 A f1
1380 A f1
1381 $ cd ..
1381 $ cd ..
1382 $ hg serve -R r1 -d -p $HGPORT --pid-file hg.pid
1382 $ hg serve -R r1 -d -p $HGPORT --pid-file hg.pid
1383 $ cat hg.pid >> $DAEMON_PIDS
1383 $ cat hg.pid >> $DAEMON_PIDS
1384 $ hg --config extensions.largefiles=! clone http://localhost:$HGPORT r2
1384 $ hg --config extensions.largefiles=! clone http://localhost:$HGPORT r2
1385 requesting all changes
1385 requesting all changes
1386 adding changesets
1386 adding changesets
1387 adding manifests
1387 adding manifests
1388 adding file changes
1388 adding file changes
1389 added 1 changesets with 1 changes to 1 files
1389 added 1 changesets with 1 changes to 1 files
1390 updating to branch default
1390 updating to branch default
1391 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1391 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1392
1392
1393 largefiles clients still work with vanilla servers
1393 largefiles clients still work with vanilla servers
1394 $ hg --config extensions.largefiles=! serve -R r1 -d -p $HGPORT1 --pid-file hg.pid
1394 $ hg --config extensions.largefiles=! serve -R r1 -d -p $HGPORT1 --pid-file hg.pid
1395 $ cat hg.pid >> $DAEMON_PIDS
1395 $ cat hg.pid >> $DAEMON_PIDS
1396 $ hg clone http://localhost:$HGPORT1 r3
1396 $ hg clone http://localhost:$HGPORT1 r3
1397 requesting all changes
1397 requesting all changes
1398 adding changesets
1398 adding changesets
1399 adding manifests
1399 adding manifests
1400 adding file changes
1400 adding file changes
1401 added 1 changesets with 1 changes to 1 files
1401 added 1 changesets with 1 changes to 1 files
1402 updating to branch default
1402 updating to branch default
1403 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1403 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1404 #endif
1404 #endif
1405
1405
1406
1406
1407 vanilla clients locked out from largefiles http repos
1407 vanilla clients locked out from largefiles http repos
1408 $ mkdir r4
1408 $ mkdir r4
1409 $ cd r4
1409 $ cd r4
1410 $ hg init
1410 $ hg init
1411 $ echo c1 > f1
1411 $ echo c1 > f1
1412 $ hg add --large f1
1412 $ hg add --large f1
1413 $ hg commit -m "m1"
1413 $ hg commit -m "m1"
1414 Invoking status precommit hook
1414 Invoking status precommit hook
1415 A f1
1415 A f1
1416 $ cd ..
1416 $ cd ..
1417
1417
1418 largefiles can be pushed locally (issue3583)
1418 largefiles can be pushed locally (issue3583)
1419 $ hg init dest
1419 $ hg init dest
1420 $ cd r4
1420 $ cd r4
1421 $ hg outgoing ../dest
1421 $ hg outgoing ../dest
1422 comparing with ../dest
1422 comparing with ../dest
1423 searching for changes
1423 searching for changes
1424 changeset: 0:639881c12b4c
1424 changeset: 0:639881c12b4c
1425 tag: tip
1425 tag: tip
1426 user: test
1426 user: test
1427 date: Thu Jan 01 00:00:00 1970 +0000
1427 date: Thu Jan 01 00:00:00 1970 +0000
1428 summary: m1
1428 summary: m1
1429
1429
1430 $ hg push ../dest
1430 $ hg push ../dest
1431 pushing to ../dest
1431 pushing to ../dest
1432 searching for changes
1432 searching for changes
1433 searching for changes
1433 searching for changes
1434 adding changesets
1434 adding changesets
1435 adding manifests
1435 adding manifests
1436 adding file changes
1436 adding file changes
1437 added 1 changesets with 1 changes to 1 files
1437 added 1 changesets with 1 changes to 1 files
1438
1438
1439 exit code with nothing outgoing (issue3611)
1439 exit code with nothing outgoing (issue3611)
1440 $ hg outgoing ../dest
1440 $ hg outgoing ../dest
1441 comparing with ../dest
1441 comparing with ../dest
1442 searching for changes
1442 searching for changes
1443 no changes found
1443 no changes found
1444 [1]
1444 [1]
1445 $ cd ..
1445 $ cd ..
1446
1446
1447 #if serve
1447 #if serve
1448 $ hg serve -R r4 -d -p $HGPORT2 --pid-file hg.pid
1448 $ hg serve -R r4 -d -p $HGPORT2 --pid-file hg.pid
1449 $ cat hg.pid >> $DAEMON_PIDS
1449 $ cat hg.pid >> $DAEMON_PIDS
1450 $ hg --config extensions.largefiles=! clone http://localhost:$HGPORT2 r5
1450 $ hg --config extensions.largefiles=! clone http://localhost:$HGPORT2 r5
1451 abort: remote error:
1451 abort: remote error:
1452
1452
1453 This repository uses the largefiles extension.
1453 This repository uses the largefiles extension.
1454
1454
1455 Please enable it in your Mercurial config file.
1455 Please enable it in your Mercurial config file.
1456 [255]
1456 [255]
1457
1457
1458 used all HGPORTs, kill all daemons
1458 used all HGPORTs, kill all daemons
1459 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
1459 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
1460 #endif
1460 #endif
1461
1461
1462 vanilla clients locked out from largefiles ssh repos
1462 vanilla clients locked out from largefiles ssh repos
1463 $ hg --config extensions.largefiles=! clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/r4 r5
1463 $ hg --config extensions.largefiles=! clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/r4 r5
1464 abort: remote error:
1464 abort: remote error:
1465
1465
1466 This repository uses the largefiles extension.
1466 This repository uses the largefiles extension.
1467
1467
1468 Please enable it in your Mercurial config file.
1468 Please enable it in your Mercurial config file.
1469 [255]
1469 [255]
1470
1470
1471 #if serve
1471 #if serve
1472
1472
1473 largefiles clients refuse to push largefiles repos to vanilla servers
1473 largefiles clients refuse to push largefiles repos to vanilla servers
1474 $ mkdir r6
1474 $ mkdir r6
1475 $ cd r6
1475 $ cd r6
1476 $ hg init
1476 $ hg init
1477 $ echo c1 > f1
1477 $ echo c1 > f1
1478 $ hg add f1
1478 $ hg add f1
1479 $ hg commit -m "m1"
1479 $ hg commit -m "m1"
1480 Invoking status precommit hook
1480 Invoking status precommit hook
1481 A f1
1481 A f1
1482 $ cat >> .hg/hgrc <<!
1482 $ cat >> .hg/hgrc <<!
1483 > [web]
1483 > [web]
1484 > push_ssl = false
1484 > push_ssl = false
1485 > allow_push = *
1485 > allow_push = *
1486 > !
1486 > !
1487 $ cd ..
1487 $ cd ..
1488 $ hg clone r6 r7
1488 $ hg clone r6 r7
1489 updating to branch default
1489 updating to branch default
1490 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1490 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1491 $ cd r7
1491 $ cd r7
1492 $ echo c2 > f2
1492 $ echo c2 > f2
1493 $ hg add --large f2
1493 $ hg add --large f2
1494 $ hg commit -m "m2"
1494 $ hg commit -m "m2"
1495 Invoking status precommit hook
1495 Invoking status precommit hook
1496 A f2
1496 A f2
1497 $ hg --config extensions.largefiles=! -R ../r6 serve -d -p $HGPORT --pid-file ../hg.pid
1497 $ hg --config extensions.largefiles=! -R ../r6 serve -d -p $HGPORT --pid-file ../hg.pid
1498 $ cat ../hg.pid >> $DAEMON_PIDS
1498 $ cat ../hg.pid >> $DAEMON_PIDS
1499 $ hg push http://localhost:$HGPORT
1499 $ hg push http://localhost:$HGPORT
1500 pushing to http://localhost:$HGPORT/
1500 pushing to http://localhost:$HGPORT/
1501 searching for changes
1501 searching for changes
1502 abort: http://localhost:$HGPORT/ does not appear to be a largefile store
1502 abort: http://localhost:$HGPORT/ does not appear to be a largefile store
1503 [255]
1503 [255]
1504 $ cd ..
1504 $ cd ..
1505
1505
1506 putlfile errors are shown (issue3123)
1506 putlfile errors are shown (issue3123)
1507 Corrupt the cached largefile in r7 and in the usercache (required for testing on vfat)
1507 Corrupt the cached largefile in r7 and in the usercache (required for testing on vfat)
1508 $ echo corruption > "$TESTTMP/r7/.hg/largefiles/4cdac4d8b084d0b599525cf732437fb337d422a8"
1508 $ echo corruption > "$TESTTMP/r7/.hg/largefiles/4cdac4d8b084d0b599525cf732437fb337d422a8"
1509 $ echo corruption > "$USERCACHE/4cdac4d8b084d0b599525cf732437fb337d422a8"
1509 $ echo corruption > "$USERCACHE/4cdac4d8b084d0b599525cf732437fb337d422a8"
1510 $ hg init empty
1510 $ hg init empty
1511 $ hg serve -R empty -d -p $HGPORT1 --pid-file hg.pid \
1511 $ hg serve -R empty -d -p $HGPORT1 --pid-file hg.pid \
1512 > --config 'web.allow_push=*' --config web.push_ssl=False
1512 > --config 'web.allow_push=*' --config web.push_ssl=False
1513 $ cat hg.pid >> $DAEMON_PIDS
1513 $ cat hg.pid >> $DAEMON_PIDS
1514 $ hg push -R r7 http://localhost:$HGPORT1
1514 $ hg push -R r7 http://localhost:$HGPORT1
1515 pushing to http://localhost:$HGPORT1/
1515 pushing to http://localhost:$HGPORT1/
1516 searching for changes
1516 searching for changes
1517 remote: largefiles: failed to put 4cdac4d8b084d0b599525cf732437fb337d422a8 into store: largefile contents do not match hash
1517 remote: largefiles: failed to put 4cdac4d8b084d0b599525cf732437fb337d422a8 into store: largefile contents do not match hash
1518 abort: remotestore: could not put $TESTTMP/r7/.hg/largefiles/4cdac4d8b084d0b599525cf732437fb337d422a8 to remote store http://localhost:$HGPORT1/ (glob)
1518 abort: remotestore: could not put $TESTTMP/r7/.hg/largefiles/4cdac4d8b084d0b599525cf732437fb337d422a8 to remote store http://localhost:$HGPORT1/ (glob)
1519 [255]
1519 [255]
1520 $ rm -rf empty
1520 $ rm -rf empty
1521
1521
1522 Push a largefiles repository to a served empty repository
1522 Push a largefiles repository to a served empty repository
1523 $ hg init r8
1523 $ hg init r8
1524 $ echo c3 > r8/f1
1524 $ echo c3 > r8/f1
1525 $ hg add --large r8/f1 -R r8
1525 $ hg add --large r8/f1 -R r8
1526 $ hg commit -m "m1" -R r8
1526 $ hg commit -m "m1" -R r8
1527 Invoking status precommit hook
1527 Invoking status precommit hook
1528 A f1
1528 A f1
1529 $ hg init empty
1529 $ hg init empty
1530 $ hg serve -R empty -d -p $HGPORT2 --pid-file hg.pid \
1530 $ hg serve -R empty -d -p $HGPORT2 --pid-file hg.pid \
1531 > --config 'web.allow_push=*' --config web.push_ssl=False
1531 > --config 'web.allow_push=*' --config web.push_ssl=False
1532 $ cat hg.pid >> $DAEMON_PIDS
1532 $ cat hg.pid >> $DAEMON_PIDS
1533 $ rm "${USERCACHE}"/*
1533 $ rm "${USERCACHE}"/*
1534 $ hg push -R r8 http://localhost:$HGPORT2
1534 $ hg push -R r8 http://localhost:$HGPORT2
1535 pushing to http://localhost:$HGPORT2/
1535 pushing to http://localhost:$HGPORT2/
1536 searching for changes
1536 searching for changes
1537 searching for changes
1537 searching for changes
1538 remote: adding changesets
1538 remote: adding changesets
1539 remote: adding manifests
1539 remote: adding manifests
1540 remote: adding file changes
1540 remote: adding file changes
1541 remote: added 1 changesets with 1 changes to 1 files
1541 remote: added 1 changesets with 1 changes to 1 files
1542
1542
1543 Clone over http, with largefiles being pulled on update, not on clone.
1543 Clone over http, with largefiles being pulled on update, not on clone.
1544
1544
1545 $ hg clone -q http://localhost:$HGPORT2/ http-clone -U
1545 $ hg clone -q http://localhost:$HGPORT2/ http-clone -U
1546
1546
1547 $ hg -R http-clone --debug up --config largefiles.usercache=http-clone-usercache
1547 $ hg -R http-clone --debug up --config largefiles.usercache=http-clone-usercache
1548 resolving manifests
1548 resolving manifests
1549 overwrite: False, partial: False
1549 overwrite: False, partial: False
1550 ancestor: 000000000000, local: 000000000000+, remote: cf03e5bb9936
1550 ancestor: 000000000000, local: 000000000000+, remote: cf03e5bb9936
1551 .hglf/f1: remote created -> g
1551 .hglf/f1: remote created -> g
1552 updating: .hglf/f1 1/1 files (100.00%)
1552 updating: .hglf/f1 1/1 files (100.00%)
1553 getting .hglf/f1
1553 getting .hglf/f1
1554 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1555 getting changed largefiles
1554 getting changed largefiles
1556 using http://localhost:$HGPORT2/
1555 using http://localhost:$HGPORT2/
1557 sending capabilities command
1556 sending capabilities command
1558 getting largefiles: 0/1 lfile (0.00%)
1557 getting largefiles: 0/1 lfile (0.00%)
1559 getting f1:02a439e5c31c526465ab1a0ca1f431f76b827b90
1558 getting f1:02a439e5c31c526465ab1a0ca1f431f76b827b90
1560 sending batch command
1559 sending batch command
1561 sending getlfile command
1560 sending getlfile command
1562 found 02a439e5c31c526465ab1a0ca1f431f76b827b90 in store
1561 found 02a439e5c31c526465ab1a0ca1f431f76b827b90 in store
1563 1 largefiles updated, 0 removed
1562 1 largefiles updated, 0 removed
1563 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1564
1564
1565 $ ls http-clone-usercache/*
1565 $ ls http-clone-usercache/*
1566 http-clone-usercache/02a439e5c31c526465ab1a0ca1f431f76b827b90
1566 http-clone-usercache/02a439e5c31c526465ab1a0ca1f431f76b827b90
1567
1567
1568 $ rm -rf empty http-clone http-clone-usercache
1568 $ rm -rf empty http-clone http-clone-usercache
1569
1569
1570 used all HGPORTs, kill all daemons
1570 used all HGPORTs, kill all daemons
1571 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
1571 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
1572
1572
1573 #endif
1573 #endif
1574
1574
1575
1575
1576 #if unix-permissions
1576 #if unix-permissions
1577
1577
1578 Clone a local repository owned by another user
1578 Clone a local repository owned by another user
1579 We have to simulate that here by setting $HOME and removing write permissions
1579 We have to simulate that here by setting $HOME and removing write permissions
1580 $ ORIGHOME="$HOME"
1580 $ ORIGHOME="$HOME"
1581 $ mkdir alice
1581 $ mkdir alice
1582 $ HOME="`pwd`/alice"
1582 $ HOME="`pwd`/alice"
1583 $ cd alice
1583 $ cd alice
1584 $ hg init pubrepo
1584 $ hg init pubrepo
1585 $ cd pubrepo
1585 $ cd pubrepo
1586 $ dd if=/dev/zero bs=1k count=11k > a-large-file 2> /dev/null
1586 $ dd if=/dev/zero bs=1k count=11k > a-large-file 2> /dev/null
1587 $ hg add --large a-large-file
1587 $ hg add --large a-large-file
1588 $ hg commit -m "Add a large file"
1588 $ hg commit -m "Add a large file"
1589 Invoking status precommit hook
1589 Invoking status precommit hook
1590 A a-large-file
1590 A a-large-file
1591 $ cd ..
1591 $ cd ..
1592 $ chmod -R a-w pubrepo
1592 $ chmod -R a-w pubrepo
1593 $ cd ..
1593 $ cd ..
1594 $ mkdir bob
1594 $ mkdir bob
1595 $ HOME="`pwd`/bob"
1595 $ HOME="`pwd`/bob"
1596 $ cd bob
1596 $ cd bob
1597 $ hg clone --pull ../alice/pubrepo pubrepo
1597 $ hg clone --pull ../alice/pubrepo pubrepo
1598 requesting all changes
1598 requesting all changes
1599 adding changesets
1599 adding changesets
1600 adding manifests
1600 adding manifests
1601 adding file changes
1601 adding file changes
1602 added 1 changesets with 1 changes to 1 files
1602 added 1 changesets with 1 changes to 1 files
1603 updating to branch default
1603 updating to branch default
1604 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1605 getting changed largefiles
1604 getting changed largefiles
1606 1 largefiles updated, 0 removed
1605 1 largefiles updated, 0 removed
1606 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1607 $ cd ..
1607 $ cd ..
1608 $ chmod -R u+w alice/pubrepo
1608 $ chmod -R u+w alice/pubrepo
1609 $ HOME="$ORIGHOME"
1609 $ HOME="$ORIGHOME"
1610
1610
1611 #endif
1611 #endif
1612
1612
1613 #if symlink
1613 #if symlink
1614
1614
1615 Symlink to a large largefile should behave the same as a symlink to a normal file
1615 Symlink to a large largefile should behave the same as a symlink to a normal file
1616 $ hg init largesymlink
1616 $ hg init largesymlink
1617 $ cd largesymlink
1617 $ cd largesymlink
1618 $ dd if=/dev/zero bs=1k count=10k of=largefile 2>/dev/null
1618 $ dd if=/dev/zero bs=1k count=10k of=largefile 2>/dev/null
1619 $ hg add --large largefile
1619 $ hg add --large largefile
1620 $ hg commit -m "commit a large file"
1620 $ hg commit -m "commit a large file"
1621 Invoking status precommit hook
1621 Invoking status precommit hook
1622 A largefile
1622 A largefile
1623 $ ln -s largefile largelink
1623 $ ln -s largefile largelink
1624 $ hg add largelink
1624 $ hg add largelink
1625 $ hg commit -m "commit a large symlink"
1625 $ hg commit -m "commit a large symlink"
1626 Invoking status precommit hook
1626 Invoking status precommit hook
1627 A largelink
1627 A largelink
1628 $ rm -f largelink
1628 $ rm -f largelink
1629 $ hg up >/dev/null
1629 $ hg up >/dev/null
1630 $ test -f largelink
1630 $ test -f largelink
1631 [1]
1631 [1]
1632 $ test -L largelink
1632 $ test -L largelink
1633 [1]
1633 [1]
1634 $ rm -f largelink # make next part of the test independent of the previous
1634 $ rm -f largelink # make next part of the test independent of the previous
1635 $ hg up -C >/dev/null
1635 $ hg up -C >/dev/null
1636 $ test -f largelink
1636 $ test -f largelink
1637 $ test -L largelink
1637 $ test -L largelink
1638 $ cd ..
1638 $ cd ..
1639
1639
1640 #endif
1640 #endif
1641
1641
1642 test for pattern matching on 'hg status':
1642 test for pattern matching on 'hg status':
1643 to boost performance, largefiles checks whether specified patterns are
1643 to boost performance, largefiles checks whether specified patterns are
1644 related to largefiles in working directory (NOT to STANDIN) or not.
1644 related to largefiles in working directory (NOT to STANDIN) or not.
1645
1645
1646 $ hg init statusmatch
1646 $ hg init statusmatch
1647 $ cd statusmatch
1647 $ cd statusmatch
1648
1648
1649 $ mkdir -p a/b/c/d
1649 $ mkdir -p a/b/c/d
1650 $ echo normal > a/b/c/d/e.normal.txt
1650 $ echo normal > a/b/c/d/e.normal.txt
1651 $ hg add a/b/c/d/e.normal.txt
1651 $ hg add a/b/c/d/e.normal.txt
1652 $ echo large > a/b/c/d/e.large.txt
1652 $ echo large > a/b/c/d/e.large.txt
1653 $ hg add --large a/b/c/d/e.large.txt
1653 $ hg add --large a/b/c/d/e.large.txt
1654 $ mkdir -p a/b/c/x
1654 $ mkdir -p a/b/c/x
1655 $ echo normal > a/b/c/x/y.normal.txt
1655 $ echo normal > a/b/c/x/y.normal.txt
1656 $ hg add a/b/c/x/y.normal.txt
1656 $ hg add a/b/c/x/y.normal.txt
1657 $ hg commit -m 'add files'
1657 $ hg commit -m 'add files'
1658 Invoking status precommit hook
1658 Invoking status precommit hook
1659 A a/b/c/d/e.large.txt
1659 A a/b/c/d/e.large.txt
1660 A a/b/c/d/e.normal.txt
1660 A a/b/c/d/e.normal.txt
1661 A a/b/c/x/y.normal.txt
1661 A a/b/c/x/y.normal.txt
1662
1662
1663 (1) no pattern: no performance boost
1663 (1) no pattern: no performance boost
1664 $ hg status -A
1664 $ hg status -A
1665 C a/b/c/d/e.large.txt
1665 C a/b/c/d/e.large.txt
1666 C a/b/c/d/e.normal.txt
1666 C a/b/c/d/e.normal.txt
1667 C a/b/c/x/y.normal.txt
1667 C a/b/c/x/y.normal.txt
1668
1668
1669 (2) pattern not related to largefiles: performance boost
1669 (2) pattern not related to largefiles: performance boost
1670 $ hg status -A a/b/c/x
1670 $ hg status -A a/b/c/x
1671 C a/b/c/x/y.normal.txt
1671 C a/b/c/x/y.normal.txt
1672
1672
1673 (3) pattern related to largefiles: no performance boost
1673 (3) pattern related to largefiles: no performance boost
1674 $ hg status -A a/b/c/d
1674 $ hg status -A a/b/c/d
1675 C a/b/c/d/e.large.txt
1675 C a/b/c/d/e.large.txt
1676 C a/b/c/d/e.normal.txt
1676 C a/b/c/d/e.normal.txt
1677
1677
1678 (4) pattern related to STANDIN (not to largefiles): performance boost
1678 (4) pattern related to STANDIN (not to largefiles): performance boost
1679 $ hg status -A .hglf/a
1679 $ hg status -A .hglf/a
1680 C .hglf/a/b/c/d/e.large.txt
1680 C .hglf/a/b/c/d/e.large.txt
1681
1681
1682 (5) mixed case: no performance boost
1682 (5) mixed case: no performance boost
1683 $ hg status -A a/b/c/x a/b/c/d
1683 $ hg status -A a/b/c/x a/b/c/d
1684 C a/b/c/d/e.large.txt
1684 C a/b/c/d/e.large.txt
1685 C a/b/c/d/e.normal.txt
1685 C a/b/c/d/e.normal.txt
1686 C a/b/c/x/y.normal.txt
1686 C a/b/c/x/y.normal.txt
1687
1687
1688 verify that largefiles doesn't break filesets
1688 verify that largefiles doesn't break filesets
1689
1689
1690 $ hg log --rev . --exclude "set:binary()"
1690 $ hg log --rev . --exclude "set:binary()"
1691 changeset: 0:41bd42f10efa
1691 changeset: 0:41bd42f10efa
1692 tag: tip
1692 tag: tip
1693 user: test
1693 user: test
1694 date: Thu Jan 01 00:00:00 1970 +0000
1694 date: Thu Jan 01 00:00:00 1970 +0000
1695 summary: add files
1695 summary: add files
1696
1696
1697 verify that large files in subrepos handled properly
1697 verify that large files in subrepos handled properly
1698 $ hg init subrepo
1698 $ hg init subrepo
1699 $ echo "subrepo = subrepo" > .hgsub
1699 $ echo "subrepo = subrepo" > .hgsub
1700 $ hg add .hgsub
1700 $ hg add .hgsub
1701 $ hg ci -m "add subrepo"
1701 $ hg ci -m "add subrepo"
1702 Invoking status precommit hook
1702 Invoking status precommit hook
1703 A .hgsub
1703 A .hgsub
1704 ? .hgsubstate
1704 ? .hgsubstate
1705 $ echo "rev 1" > subrepo/large.txt
1705 $ echo "rev 1" > subrepo/large.txt
1706 $ hg -R subrepo add --large subrepo/large.txt
1706 $ hg -R subrepo add --large subrepo/large.txt
1707 $ hg sum
1707 $ hg sum
1708 parent: 1:8ee150ea2e9c tip
1708 parent: 1:8ee150ea2e9c tip
1709 add subrepo
1709 add subrepo
1710 branch: default
1710 branch: default
1711 commit: 1 subrepos
1711 commit: 1 subrepos
1712 update: (current)
1712 update: (current)
1713 $ hg st
1713 $ hg st
1714 $ hg st -S
1714 $ hg st -S
1715 A subrepo/large.txt
1715 A subrepo/large.txt
1716 $ hg ci -S -m "commit top repo"
1716 $ hg ci -S -m "commit top repo"
1717 committing subrepository subrepo
1717 committing subrepository subrepo
1718 Invoking status precommit hook
1718 Invoking status precommit hook
1719 A large.txt
1719 A large.txt
1720 Invoking status precommit hook
1720 Invoking status precommit hook
1721 M .hgsubstate
1721 M .hgsubstate
1722 # No differences
1722 # No differences
1723 $ hg st -S
1723 $ hg st -S
1724 $ hg sum
1724 $ hg sum
1725 parent: 2:ce4cd0c527a6 tip
1725 parent: 2:ce4cd0c527a6 tip
1726 commit top repo
1726 commit top repo
1727 branch: default
1727 branch: default
1728 commit: (clean)
1728 commit: (clean)
1729 update: (current)
1729 update: (current)
1730 $ echo "rev 2" > subrepo/large.txt
1730 $ echo "rev 2" > subrepo/large.txt
1731 $ hg st -S
1731 $ hg st -S
1732 M subrepo/large.txt
1732 M subrepo/large.txt
1733 $ hg sum
1733 $ hg sum
1734 parent: 2:ce4cd0c527a6 tip
1734 parent: 2:ce4cd0c527a6 tip
1735 commit top repo
1735 commit top repo
1736 branch: default
1736 branch: default
1737 commit: 1 subrepos
1737 commit: 1 subrepos
1738 update: (current)
1738 update: (current)
1739 $ hg ci -m "this commit should fail without -S"
1739 $ hg ci -m "this commit should fail without -S"
1740 abort: uncommitted changes in subrepo subrepo
1740 abort: uncommitted changes in subrepo subrepo
1741 (use --subrepos for recursive commit)
1741 (use --subrepos for recursive commit)
1742 [255]
1742 [255]
1743
1743
1744 Add a normal file to the subrepo, then test archiving
1744 Add a normal file to the subrepo, then test archiving
1745
1745
1746 $ echo 'normal file' > subrepo/normal.txt
1746 $ echo 'normal file' > subrepo/normal.txt
1747 $ hg -R subrepo add subrepo/normal.txt
1747 $ hg -R subrepo add subrepo/normal.txt
1748
1748
1749 Lock in subrepo, otherwise the change isn't archived
1749 Lock in subrepo, otherwise the change isn't archived
1750
1750
1751 $ hg ci -S -m "add normal file to top level"
1751 $ hg ci -S -m "add normal file to top level"
1752 committing subrepository subrepo
1752 committing subrepository subrepo
1753 Invoking status precommit hook
1753 Invoking status precommit hook
1754 M large.txt
1754 M large.txt
1755 A normal.txt
1755 A normal.txt
1756 Invoking status precommit hook
1756 Invoking status precommit hook
1757 M .hgsubstate
1757 M .hgsubstate
1758 $ hg archive -S lf_subrepo_archive
1758 $ hg archive -S ../lf_subrepo_archive
1759 $ find lf_subrepo_archive | sort
1759 $ find ../lf_subrepo_archive | sort
1760 lf_subrepo_archive
1760 ../lf_subrepo_archive
1761 lf_subrepo_archive/.hg_archival.txt
1761 ../lf_subrepo_archive/.hg_archival.txt
1762 lf_subrepo_archive/.hgsub
1762 ../lf_subrepo_archive/.hgsub
1763 lf_subrepo_archive/.hgsubstate
1763 ../lf_subrepo_archive/.hgsubstate
1764 lf_subrepo_archive/a
1764 ../lf_subrepo_archive/a
1765 lf_subrepo_archive/a/b
1765 ../lf_subrepo_archive/a/b
1766 lf_subrepo_archive/a/b/c
1766 ../lf_subrepo_archive/a/b/c
1767 lf_subrepo_archive/a/b/c/d
1767 ../lf_subrepo_archive/a/b/c/d
1768 lf_subrepo_archive/a/b/c/d/e.large.txt
1768 ../lf_subrepo_archive/a/b/c/d/e.large.txt
1769 lf_subrepo_archive/a/b/c/d/e.normal.txt
1769 ../lf_subrepo_archive/a/b/c/d/e.normal.txt
1770 lf_subrepo_archive/a/b/c/x
1770 ../lf_subrepo_archive/a/b/c/x
1771 lf_subrepo_archive/a/b/c/x/y.normal.txt
1771 ../lf_subrepo_archive/a/b/c/x/y.normal.txt
1772 lf_subrepo_archive/subrepo
1772 ../lf_subrepo_archive/subrepo
1773 lf_subrepo_archive/subrepo/large.txt
1773 ../lf_subrepo_archive/subrepo/large.txt
1774 lf_subrepo_archive/subrepo/normal.txt
1774 ../lf_subrepo_archive/subrepo/normal.txt
1775
1776 Test update with subrepos.
1777
1778 $ hg update 0
1779 getting changed largefiles
1780 0 largefiles updated, 1 removed
1781 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
1782 $ hg status -S
1783 $ hg update tip
1784 getting changed largefiles
1785 1 largefiles updated, 0 removed
1786 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1787 $ hg status -S
1788 # modify a large file
1789 $ echo "modified" > subrepo/large.txt
1790 $ hg st -S
1791 M subrepo/large.txt
1792 # update -C should revert the change.
1793 $ hg update -C
1794 getting changed largefiles
1795 1 largefiles updated, 0 removed
1796 getting changed largefiles
1797 0 largefiles updated, 0 removed
1798 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1799 $ hg status -S
1775
1800
1776 Test archiving a revision that references a subrepo that is not yet
1801 Test archiving a revision that references a subrepo that is not yet
1777 cloned (see test-subrepo-recursion.t):
1802 cloned (see test-subrepo-recursion.t):
1778
1803
1779 $ hg clone -U . ../empty
1804 $ hg clone -U . ../empty
1780 $ cd ../empty
1805 $ cd ../empty
1781 $ hg archive --subrepos -r tip ../archive.tar.gz
1806 $ hg archive --subrepos -r tip ../archive.tar.gz
1782 cloning subrepo subrepo from $TESTTMP/statusmatch/subrepo
1807 cloning subrepo subrepo from $TESTTMP/statusmatch/subrepo
1783 $ cd ..
1808 $ cd ..
1784
1809
1785 Test that addremove picks up largefiles prior to the initial commit (issue3541)
1810 Test that addremove picks up largefiles prior to the initial commit (issue3541)
1786
1811
1787 $ hg init addrm2
1812 $ hg init addrm2
1788 $ cd addrm2
1813 $ cd addrm2
1789 $ touch large.dat
1814 $ touch large.dat
1790 $ touch large2.dat
1815 $ touch large2.dat
1791 $ touch normal
1816 $ touch normal
1792 $ hg add --large large.dat
1817 $ hg add --large large.dat
1793 $ hg addremove -v
1818 $ hg addremove -v
1794 adding large2.dat as a largefile
1819 adding large2.dat as a largefile
1795 adding normal
1820 adding normal
1796
1821
1797 Test that forgetting all largefiles reverts to islfilesrepo() == False
1822 Test that forgetting all largefiles reverts to islfilesrepo() == False
1798 (addremove will add *.dat as normal files now)
1823 (addremove will add *.dat as normal files now)
1799 $ hg forget large.dat
1824 $ hg forget large.dat
1800 $ hg forget large2.dat
1825 $ hg forget large2.dat
1801 $ hg addremove -v
1826 $ hg addremove -v
1802 adding large.dat
1827 adding large.dat
1803 adding large2.dat
1828 adding large2.dat
1804
1829
1805 Test commit's addremove option prior to the first commit
1830 Test commit's addremove option prior to the first commit
1806 $ hg forget large.dat
1831 $ hg forget large.dat
1807 $ hg forget large2.dat
1832 $ hg forget large2.dat
1808 $ hg add --large large.dat
1833 $ hg add --large large.dat
1809 $ hg ci -Am "commit"
1834 $ hg ci -Am "commit"
1810 adding large2.dat as a largefile
1835 adding large2.dat as a largefile
1811 Invoking status precommit hook
1836 Invoking status precommit hook
1812 A large.dat
1837 A large.dat
1813 A large2.dat
1838 A large2.dat
1814 A normal
1839 A normal
1815 $ find .hglf | sort
1840 $ find .hglf | sort
1816 .hglf
1841 .hglf
1817 .hglf/large.dat
1842 .hglf/large.dat
1818 .hglf/large2.dat
1843 .hglf/large2.dat
1819
1844
1820 $ cd ..
1845 $ cd ..
1821
1846
1822 issue3651: summary/outgoing with largefiles shows "no remote repo"
1847 issue3651: summary/outgoing with largefiles shows "no remote repo"
1823 unexpectedly
1848 unexpectedly
1824
1849
1825 $ mkdir issue3651
1850 $ mkdir issue3651
1826 $ cd issue3651
1851 $ cd issue3651
1827
1852
1828 $ hg init src
1853 $ hg init src
1829 $ echo a > src/a
1854 $ echo a > src/a
1830 $ hg -R src add --large src/a
1855 $ hg -R src add --large src/a
1831 $ hg -R src commit -m '#0'
1856 $ hg -R src commit -m '#0'
1832 Invoking status precommit hook
1857 Invoking status precommit hook
1833 A a
1858 A a
1834
1859
1835 check messages when no remote repository is specified:
1860 check messages when no remote repository is specified:
1836 "no remote repo" route for "hg outgoing --large" is not tested here,
1861 "no remote repo" route for "hg outgoing --large" is not tested here,
1837 because it can't be reproduced easily.
1862 because it can't be reproduced easily.
1838
1863
1839 $ hg init clone1
1864 $ hg init clone1
1840 $ hg -R clone1 -q pull src
1865 $ hg -R clone1 -q pull src
1841 $ hg -R clone1 -q update
1866 $ hg -R clone1 -q update
1842 $ hg -R clone1 paths | grep default
1867 $ hg -R clone1 paths | grep default
1843 [1]
1868 [1]
1844
1869
1845 $ hg -R clone1 summary --large
1870 $ hg -R clone1 summary --large
1846 parent: 0:fc0bd45326d3 tip
1871 parent: 0:fc0bd45326d3 tip
1847 #0
1872 #0
1848 branch: default
1873 branch: default
1849 commit: (clean)
1874 commit: (clean)
1850 update: (current)
1875 update: (current)
1851 largefiles: (no remote repo)
1876 largefiles: (no remote repo)
1852
1877
1853 check messages when there is no files to upload:
1878 check messages when there is no files to upload:
1854
1879
1855 $ hg -q clone src clone2
1880 $ hg -q clone src clone2
1856 $ hg -R clone2 paths | grep default
1881 $ hg -R clone2 paths | grep default
1857 default = $TESTTMP/issue3651/src (glob)
1882 default = $TESTTMP/issue3651/src (glob)
1858
1883
1859 $ hg -R clone2 summary --large
1884 $ hg -R clone2 summary --large
1860 parent: 0:fc0bd45326d3 tip
1885 parent: 0:fc0bd45326d3 tip
1861 #0
1886 #0
1862 branch: default
1887 branch: default
1863 commit: (clean)
1888 commit: (clean)
1864 update: (current)
1889 update: (current)
1865 searching for changes
1890 searching for changes
1866 largefiles: (no files to upload)
1891 largefiles: (no files to upload)
1867 $ hg -R clone2 outgoing --large
1892 $ hg -R clone2 outgoing --large
1868 comparing with $TESTTMP/issue3651/src (glob)
1893 comparing with $TESTTMP/issue3651/src (glob)
1869 searching for changes
1894 searching for changes
1870 no changes found
1895 no changes found
1871 searching for changes
1896 searching for changes
1872 largefiles: no files to upload
1897 largefiles: no files to upload
1873 [1]
1898 [1]
1874
1899
1875 check messages when there are files to upload:
1900 check messages when there are files to upload:
1876
1901
1877 $ echo b > clone2/b
1902 $ echo b > clone2/b
1878 $ hg -R clone2 add --large clone2/b
1903 $ hg -R clone2 add --large clone2/b
1879 $ hg -R clone2 commit -m '#1'
1904 $ hg -R clone2 commit -m '#1'
1880 Invoking status precommit hook
1905 Invoking status precommit hook
1881 A b
1906 A b
1882 $ hg -R clone2 summary --large
1907 $ hg -R clone2 summary --large
1883 parent: 1:1acbe71ce432 tip
1908 parent: 1:1acbe71ce432 tip
1884 #1
1909 #1
1885 branch: default
1910 branch: default
1886 commit: (clean)
1911 commit: (clean)
1887 update: (current)
1912 update: (current)
1888 searching for changes
1913 searching for changes
1889 largefiles: 1 to upload
1914 largefiles: 1 to upload
1890 $ hg -R clone2 outgoing --large
1915 $ hg -R clone2 outgoing --large
1891 comparing with $TESTTMP/issue3651/src (glob)
1916 comparing with $TESTTMP/issue3651/src (glob)
1892 searching for changes
1917 searching for changes
1893 changeset: 1:1acbe71ce432
1918 changeset: 1:1acbe71ce432
1894 tag: tip
1919 tag: tip
1895 user: test
1920 user: test
1896 date: Thu Jan 01 00:00:00 1970 +0000
1921 date: Thu Jan 01 00:00:00 1970 +0000
1897 summary: #1
1922 summary: #1
1898
1923
1899 searching for changes
1924 searching for changes
1900 largefiles to upload:
1925 largefiles to upload:
1901 b
1926 b
1902
1927
1903
1928
1904 $ cd ..
1929 $ cd ..
@@ -1,356 +1,356 b''
1 $ USERCACHE="$TESTTMP/cache"; export USERCACHE
1 $ USERCACHE="$TESTTMP/cache"; export USERCACHE
2 $ mkdir "${USERCACHE}"
2 $ mkdir "${USERCACHE}"
3 $ cat >> $HGRCPATH <<EOF
3 $ cat >> $HGRCPATH <<EOF
4 > [extensions]
4 > [extensions]
5 > largefiles =
5 > largefiles =
6 > share =
6 > share =
7 > graphlog =
7 > graphlog =
8 > mq =
8 > mq =
9 > convert =
9 > convert =
10 > [largefiles]
10 > [largefiles]
11 > minsize = 0.5
11 > minsize = 0.5
12 > patterns = **.other
12 > patterns = **.other
13 > **.dat
13 > **.dat
14 > usercache=${USERCACHE}
14 > usercache=${USERCACHE}
15 > EOF
15 > EOF
16
16
17 "lfconvert" works
17 "lfconvert" works
18 $ hg init bigfile-repo
18 $ hg init bigfile-repo
19 $ cd bigfile-repo
19 $ cd bigfile-repo
20 $ cat >> .hg/hgrc <<EOF
20 $ cat >> .hg/hgrc <<EOF
21 > [extensions]
21 > [extensions]
22 > largefiles = !
22 > largefiles = !
23 > EOF
23 > EOF
24 $ mkdir sub
24 $ mkdir sub
25 $ dd if=/dev/zero bs=1k count=256 > large 2> /dev/null
25 $ dd if=/dev/zero bs=1k count=256 > large 2> /dev/null
26 $ dd if=/dev/zero bs=1k count=256 > large2 2> /dev/null
26 $ dd if=/dev/zero bs=1k count=256 > large2 2> /dev/null
27 $ echo normal > normal1
27 $ echo normal > normal1
28 $ echo alsonormal > sub/normal2
28 $ echo alsonormal > sub/normal2
29 $ dd if=/dev/zero bs=1k count=10 > sub/maybelarge.dat 2> /dev/null
29 $ dd if=/dev/zero bs=1k count=10 > sub/maybelarge.dat 2> /dev/null
30 $ hg addremove
30 $ hg addremove
31 adding large
31 adding large
32 adding large2
32 adding large2
33 adding normal1
33 adding normal1
34 adding sub/maybelarge.dat
34 adding sub/maybelarge.dat
35 adding sub/normal2
35 adding sub/normal2
36 $ hg commit -m"add large, normal1" large normal1
36 $ hg commit -m"add large, normal1" large normal1
37 $ hg commit -m"add sub/*" sub
37 $ hg commit -m"add sub/*" sub
38
38
39 Test tag parsing
39 Test tag parsing
40 $ cat >> .hgtags <<EOF
40 $ cat >> .hgtags <<EOF
41 > IncorrectlyFormattedTag!
41 > IncorrectlyFormattedTag!
42 > invalidhash sometag
42 > invalidhash sometag
43 > 0123456789abcdef anothertag
43 > 0123456789abcdef anothertag
44 > EOF
44 > EOF
45 $ hg add .hgtags
45 $ hg add .hgtags
46 $ hg commit -m"add large2" large2 .hgtags
46 $ hg commit -m"add large2" large2 .hgtags
47
47
48 Test link+rename largefile codepath
48 Test link+rename largefile codepath
49 $ [ -d .hg/largefiles ] && echo fail || echo pass
49 $ [ -d .hg/largefiles ] && echo fail || echo pass
50 pass
50 pass
51 $ cd ..
51 $ cd ..
52 $ hg lfconvert --size 0.2 bigfile-repo largefiles-repo
52 $ hg lfconvert --size 0.2 bigfile-repo largefiles-repo
53 initializing destination largefiles-repo
53 initializing destination largefiles-repo
54 skipping incorrectly formatted tag IncorrectlyFormattedTag!
54 skipping incorrectly formatted tag IncorrectlyFormattedTag!
55 skipping incorrectly formatted id invalidhash
55 skipping incorrectly formatted id invalidhash
56 no mapping for id 0123456789abcdef
56 no mapping for id 0123456789abcdef
57 #if symlink
57 #if symlink
58 $ hg --cwd bigfile-repo rename large2 large3
58 $ hg --cwd bigfile-repo rename large2 large3
59 $ ln -sf large bigfile-repo/large3
59 $ ln -sf large bigfile-repo/large3
60 $ hg --cwd bigfile-repo commit -m"make large2 a symlink" large2 large3
60 $ hg --cwd bigfile-repo commit -m"make large2 a symlink" large2 large3
61 $ hg lfconvert --size 0.2 bigfile-repo largefiles-repo-symlink
61 $ hg lfconvert --size 0.2 bigfile-repo largefiles-repo-symlink
62 initializing destination largefiles-repo-symlink
62 initializing destination largefiles-repo-symlink
63 skipping incorrectly formatted tag IncorrectlyFormattedTag!
63 skipping incorrectly formatted tag IncorrectlyFormattedTag!
64 skipping incorrectly formatted id invalidhash
64 skipping incorrectly formatted id invalidhash
65 no mapping for id 0123456789abcdef
65 no mapping for id 0123456789abcdef
66 abort: renamed/copied largefile large3 becomes symlink
66 abort: renamed/copied largefile large3 becomes symlink
67 [255]
67 [255]
68 #endif
68 #endif
69 $ cd bigfile-repo
69 $ cd bigfile-repo
70 $ hg strip --no-backup 2
70 $ hg strip --no-backup 2
71 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
71 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
72 $ cd ..
72 $ cd ..
73 $ rm -rf largefiles-repo largefiles-repo-symlink
73 $ rm -rf largefiles-repo largefiles-repo-symlink
74
74
75 $ hg lfconvert --size 0.2 bigfile-repo largefiles-repo
75 $ hg lfconvert --size 0.2 bigfile-repo largefiles-repo
76 initializing destination largefiles-repo
76 initializing destination largefiles-repo
77
77
78 "lfconvert" converts content correctly
78 "lfconvert" converts content correctly
79 $ cd largefiles-repo
79 $ cd largefiles-repo
80 $ hg up
80 $ hg up
81 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
82 getting changed largefiles
81 getting changed largefiles
83 2 largefiles updated, 0 removed
82 2 largefiles updated, 0 removed
83 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
84 $ hg locate
84 $ hg locate
85 .hglf/large
85 .hglf/large
86 .hglf/sub/maybelarge.dat
86 .hglf/sub/maybelarge.dat
87 normal1
87 normal1
88 sub/normal2
88 sub/normal2
89 $ cat normal1
89 $ cat normal1
90 normal
90 normal
91 $ cat sub/normal2
91 $ cat sub/normal2
92 alsonormal
92 alsonormal
93 $ "$TESTDIR/md5sum.py" large sub/maybelarge.dat
93 $ "$TESTDIR/md5sum.py" large sub/maybelarge.dat
94 ec87a838931d4d5d2e94a04644788a55 large
94 ec87a838931d4d5d2e94a04644788a55 large
95 1276481102f218c981e0324180bafd9f sub/maybelarge.dat
95 1276481102f218c981e0324180bafd9f sub/maybelarge.dat
96
96
97 "lfconvert" adds 'largefiles' to .hg/requires.
97 "lfconvert" adds 'largefiles' to .hg/requires.
98 $ cat .hg/requires
98 $ cat .hg/requires
99 dotencode
99 dotencode
100 fncache
100 fncache
101 largefiles
101 largefiles
102 revlogv1
102 revlogv1
103 store
103 store
104
104
105 "lfconvert" includes a newline at the end of the standin files.
105 "lfconvert" includes a newline at the end of the standin files.
106 $ cat .hglf/large .hglf/sub/maybelarge.dat
106 $ cat .hglf/large .hglf/sub/maybelarge.dat
107 2e000fa7e85759c7f4c254d4d9c33ef481e459a7
107 2e000fa7e85759c7f4c254d4d9c33ef481e459a7
108 34e163be8e43c5631d8b92e9c43ab0bf0fa62b9c
108 34e163be8e43c5631d8b92e9c43ab0bf0fa62b9c
109 $ cd ..
109 $ cd ..
110
110
111 add some changesets to rename/remove/merge
111 add some changesets to rename/remove/merge
112 $ cd bigfile-repo
112 $ cd bigfile-repo
113 $ hg mv -q sub stuff
113 $ hg mv -q sub stuff
114 $ hg commit -m"rename sub/ to stuff/"
114 $ hg commit -m"rename sub/ to stuff/"
115 $ hg update -q 1
115 $ hg update -q 1
116 $ echo blah >> normal3
116 $ echo blah >> normal3
117 $ echo blah >> sub/normal2
117 $ echo blah >> sub/normal2
118 $ echo blah >> sub/maybelarge.dat
118 $ echo blah >> sub/maybelarge.dat
119 $ "$TESTDIR/md5sum.py" sub/maybelarge.dat
119 $ "$TESTDIR/md5sum.py" sub/maybelarge.dat
120 1dd0b99ff80e19cff409702a1d3f5e15 sub/maybelarge.dat
120 1dd0b99ff80e19cff409702a1d3f5e15 sub/maybelarge.dat
121 $ hg commit -A -m"add normal3, modify sub/*"
121 $ hg commit -A -m"add normal3, modify sub/*"
122 adding normal3
122 adding normal3
123 created new head
123 created new head
124 $ hg rm large normal3
124 $ hg rm large normal3
125 $ hg commit -q -m"remove large, normal3"
125 $ hg commit -q -m"remove large, normal3"
126 $ hg merge
126 $ hg merge
127 merging sub/maybelarge.dat and stuff/maybelarge.dat to stuff/maybelarge.dat
127 merging sub/maybelarge.dat and stuff/maybelarge.dat to stuff/maybelarge.dat
128 warning: $TESTTMP/bigfile-repo/stuff/maybelarge.dat looks like a binary file. (glob)
128 warning: $TESTTMP/bigfile-repo/stuff/maybelarge.dat looks like a binary file. (glob)
129 merging stuff/maybelarge.dat incomplete! (edit conflicts, then use 'hg resolve --mark')
129 merging stuff/maybelarge.dat incomplete! (edit conflicts, then use 'hg resolve --mark')
130 merging sub/normal2 and stuff/normal2 to stuff/normal2
130 merging sub/normal2 and stuff/normal2 to stuff/normal2
131 0 files updated, 1 files merged, 0 files removed, 1 files unresolved
131 0 files updated, 1 files merged, 0 files removed, 1 files unresolved
132 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
132 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
133 [1]
133 [1]
134 $ hg cat -r . sub/maybelarge.dat > stuff/maybelarge.dat
134 $ hg cat -r . sub/maybelarge.dat > stuff/maybelarge.dat
135 $ hg resolve -m stuff/maybelarge.dat
135 $ hg resolve -m stuff/maybelarge.dat
136 $ hg commit -m"merge"
136 $ hg commit -m"merge"
137 $ hg glog --template "{rev}:{node|short} {desc|firstline}\n"
137 $ hg glog --template "{rev}:{node|short} {desc|firstline}\n"
138 @ 5:4884f215abda merge
138 @ 5:4884f215abda merge
139 |\
139 |\
140 | o 4:7285f817b77e remove large, normal3
140 | o 4:7285f817b77e remove large, normal3
141 | |
141 | |
142 | o 3:67e3892e3534 add normal3, modify sub/*
142 | o 3:67e3892e3534 add normal3, modify sub/*
143 | |
143 | |
144 o | 2:c96c8beb5d56 rename sub/ to stuff/
144 o | 2:c96c8beb5d56 rename sub/ to stuff/
145 |/
145 |/
146 o 1:020c65d24e11 add sub/*
146 o 1:020c65d24e11 add sub/*
147 |
147 |
148 o 0:117b8328f97a add large, normal1
148 o 0:117b8328f97a add large, normal1
149
149
150 $ cd ..
150 $ cd ..
151
151
152 lfconvert with rename, merge, and remove
152 lfconvert with rename, merge, and remove
153 $ rm -rf largefiles-repo
153 $ rm -rf largefiles-repo
154 $ hg lfconvert --size 0.2 bigfile-repo largefiles-repo
154 $ hg lfconvert --size 0.2 bigfile-repo largefiles-repo
155 initializing destination largefiles-repo
155 initializing destination largefiles-repo
156 $ cd largefiles-repo
156 $ cd largefiles-repo
157 $ hg glog --template "{rev}:{node|short} {desc|firstline}\n"
157 $ hg glog --template "{rev}:{node|short} {desc|firstline}\n"
158 o 5:8e05f5f2b77e merge
158 o 5:8e05f5f2b77e merge
159 |\
159 |\
160 | o 4:a5a02de7a8e4 remove large, normal3
160 | o 4:a5a02de7a8e4 remove large, normal3
161 | |
161 | |
162 | o 3:55759520c76f add normal3, modify sub/*
162 | o 3:55759520c76f add normal3, modify sub/*
163 | |
163 | |
164 o | 2:261ad3f3f037 rename sub/ to stuff/
164 o | 2:261ad3f3f037 rename sub/ to stuff/
165 |/
165 |/
166 o 1:334e5237836d add sub/*
166 o 1:334e5237836d add sub/*
167 |
167 |
168 o 0:d4892ec57ce2 add large, normal1
168 o 0:d4892ec57ce2 add large, normal1
169
169
170 $ hg locate -r 2
170 $ hg locate -r 2
171 .hglf/large
171 .hglf/large
172 .hglf/stuff/maybelarge.dat
172 .hglf/stuff/maybelarge.dat
173 normal1
173 normal1
174 stuff/normal2
174 stuff/normal2
175 $ hg locate -r 3
175 $ hg locate -r 3
176 .hglf/large
176 .hglf/large
177 .hglf/sub/maybelarge.dat
177 .hglf/sub/maybelarge.dat
178 normal1
178 normal1
179 normal3
179 normal3
180 sub/normal2
180 sub/normal2
181 $ hg locate -r 4
181 $ hg locate -r 4
182 .hglf/sub/maybelarge.dat
182 .hglf/sub/maybelarge.dat
183 normal1
183 normal1
184 sub/normal2
184 sub/normal2
185 $ hg locate -r 5
185 $ hg locate -r 5
186 .hglf/stuff/maybelarge.dat
186 .hglf/stuff/maybelarge.dat
187 normal1
187 normal1
188 stuff/normal2
188 stuff/normal2
189 $ hg update
189 $ hg update
190 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
191 getting changed largefiles
190 getting changed largefiles
192 1 largefiles updated, 0 removed
191 1 largefiles updated, 0 removed
192 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
193 $ cat stuff/normal2
193 $ cat stuff/normal2
194 alsonormal
194 alsonormal
195 blah
195 blah
196 $ "$TESTDIR/md5sum.py" stuff/maybelarge.dat
196 $ "$TESTDIR/md5sum.py" stuff/maybelarge.dat
197 1dd0b99ff80e19cff409702a1d3f5e15 stuff/maybelarge.dat
197 1dd0b99ff80e19cff409702a1d3f5e15 stuff/maybelarge.dat
198 $ cat .hglf/stuff/maybelarge.dat
198 $ cat .hglf/stuff/maybelarge.dat
199 76236b6a2c6102826c61af4297dd738fb3b1de38
199 76236b6a2c6102826c61af4297dd738fb3b1de38
200 $ cd ..
200 $ cd ..
201
201
202 "lfconvert" error cases
202 "lfconvert" error cases
203 $ hg lfconvert http://localhost/foo foo
203 $ hg lfconvert http://localhost/foo foo
204 abort: http://localhost/foo is not a local Mercurial repo
204 abort: http://localhost/foo is not a local Mercurial repo
205 [255]
205 [255]
206 $ hg lfconvert foo ssh://localhost/foo
206 $ hg lfconvert foo ssh://localhost/foo
207 abort: ssh://localhost/foo is not a local Mercurial repo
207 abort: ssh://localhost/foo is not a local Mercurial repo
208 [255]
208 [255]
209 $ hg lfconvert nosuchrepo foo
209 $ hg lfconvert nosuchrepo foo
210 abort: repository nosuchrepo not found!
210 abort: repository nosuchrepo not found!
211 [255]
211 [255]
212 $ hg share -q -U bigfile-repo shared
212 $ hg share -q -U bigfile-repo shared
213 $ printf 'bogus' > shared/.hg/sharedpath
213 $ printf 'bogus' > shared/.hg/sharedpath
214 $ hg lfconvert shared foo
214 $ hg lfconvert shared foo
215 abort: .hg/sharedpath points to nonexistent directory $TESTTMP/bogus! (glob)
215 abort: .hg/sharedpath points to nonexistent directory $TESTTMP/bogus! (glob)
216 [255]
216 [255]
217 $ hg lfconvert bigfile-repo largefiles-repo
217 $ hg lfconvert bigfile-repo largefiles-repo
218 initializing destination largefiles-repo
218 initializing destination largefiles-repo
219 abort: repository largefiles-repo already exists!
219 abort: repository largefiles-repo already exists!
220 [255]
220 [255]
221
221
222 add another largefile to the new largefiles repo
222 add another largefile to the new largefiles repo
223 $ cd largefiles-repo
223 $ cd largefiles-repo
224 $ dd if=/dev/zero bs=1k count=1k > anotherlarge 2> /dev/null
224 $ dd if=/dev/zero bs=1k count=1k > anotherlarge 2> /dev/null
225 $ hg add --lfsize=1 anotherlarge
225 $ hg add --lfsize=1 anotherlarge
226 $ hg commit -m "add anotherlarge (should be a largefile)"
226 $ hg commit -m "add anotherlarge (should be a largefile)"
227 $ cat .hglf/anotherlarge
227 $ cat .hglf/anotherlarge
228 3b71f43ff30f4b15b5cd85dd9e95ebc7e84eb5a3
228 3b71f43ff30f4b15b5cd85dd9e95ebc7e84eb5a3
229 $ cd ..
229 $ cd ..
230
230
231 round-trip: converting back to a normal (non-largefiles) repo with
231 round-trip: converting back to a normal (non-largefiles) repo with
232 "lfconvert --to-normal" should give the same as ../bigfile-repo
232 "lfconvert --to-normal" should give the same as ../bigfile-repo
233 $ cd largefiles-repo
233 $ cd largefiles-repo
234 $ hg lfconvert --to-normal . ../normal-repo
234 $ hg lfconvert --to-normal . ../normal-repo
235 initializing destination ../normal-repo
235 initializing destination ../normal-repo
236 $ cd ../normal-repo
236 $ cd ../normal-repo
237 $ cat >> .hg/hgrc <<EOF
237 $ cat >> .hg/hgrc <<EOF
238 > [extensions]
238 > [extensions]
239 > largefiles = !
239 > largefiles = !
240 > EOF
240 > EOF
241
241
242 # Hmmm: the changeset ID for rev 5 is different from the original
242 # Hmmm: the changeset ID for rev 5 is different from the original
243 # normal repo (../bigfile-repo), because the changelog filelist
243 # normal repo (../bigfile-repo), because the changelog filelist
244 # differs between the two incarnations of rev 5: this repo includes
244 # differs between the two incarnations of rev 5: this repo includes
245 # 'large' in the list, but ../bigfile-repo does not. Since rev 5
245 # 'large' in the list, but ../bigfile-repo does not. Since rev 5
246 # removes 'large' relative to the first parent in both repos, it seems
246 # removes 'large' relative to the first parent in both repos, it seems
247 # to me that lfconvert is doing a *better* job than
247 # to me that lfconvert is doing a *better* job than
248 # "hg remove" + "hg merge" + "hg commit".
248 # "hg remove" + "hg merge" + "hg commit".
249 # $ hg -R ../bigfile-repo debugdata -c 5
249 # $ hg -R ../bigfile-repo debugdata -c 5
250 # $ hg debugdata -c 5
250 # $ hg debugdata -c 5
251 $ hg glog --template "{rev}:{node|short} {desc|firstline}\n"
251 $ hg glog --template "{rev}:{node|short} {desc|firstline}\n"
252 o 6:1635824e6f59 add anotherlarge (should be a largefile)
252 o 6:1635824e6f59 add anotherlarge (should be a largefile)
253 |
253 |
254 o 5:7215f8deeaaf merge
254 o 5:7215f8deeaaf merge
255 |\
255 |\
256 | o 4:7285f817b77e remove large, normal3
256 | o 4:7285f817b77e remove large, normal3
257 | |
257 | |
258 | o 3:67e3892e3534 add normal3, modify sub/*
258 | o 3:67e3892e3534 add normal3, modify sub/*
259 | |
259 | |
260 o | 2:c96c8beb5d56 rename sub/ to stuff/
260 o | 2:c96c8beb5d56 rename sub/ to stuff/
261 |/
261 |/
262 o 1:020c65d24e11 add sub/*
262 o 1:020c65d24e11 add sub/*
263 |
263 |
264 o 0:117b8328f97a add large, normal1
264 o 0:117b8328f97a add large, normal1
265
265
266 $ hg update
266 $ hg update
267 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
267 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
268 $ hg locate
268 $ hg locate
269 anotherlarge
269 anotherlarge
270 normal1
270 normal1
271 stuff/maybelarge.dat
271 stuff/maybelarge.dat
272 stuff/normal2
272 stuff/normal2
273 $ [ -d .hg/largefiles ] && echo fail || echo pass
273 $ [ -d .hg/largefiles ] && echo fail || echo pass
274 pass
274 pass
275
275
276 $ cd ..
276 $ cd ..
277
277
278 Clearing the usercache ensures that commitctx doesn't try to cache largefiles
278 Clearing the usercache ensures that commitctx doesn't try to cache largefiles
279 from the working dir on a convert.
279 from the working dir on a convert.
280 $ rm "${USERCACHE}"/*
280 $ rm "${USERCACHE}"/*
281 $ hg convert largefiles-repo
281 $ hg convert largefiles-repo
282 assuming destination largefiles-repo-hg
282 assuming destination largefiles-repo-hg
283 initializing destination largefiles-repo-hg repository
283 initializing destination largefiles-repo-hg repository
284 scanning source...
284 scanning source...
285 sorting...
285 sorting...
286 converting...
286 converting...
287 6 add large, normal1
287 6 add large, normal1
288 5 add sub/*
288 5 add sub/*
289 4 rename sub/ to stuff/
289 4 rename sub/ to stuff/
290 3 add normal3, modify sub/*
290 3 add normal3, modify sub/*
291 2 remove large, normal3
291 2 remove large, normal3
292 1 merge
292 1 merge
293 0 add anotherlarge (should be a largefile)
293 0 add anotherlarge (should be a largefile)
294
294
295 $ hg -R largefiles-repo-hg glog --template "{rev}:{node|short} {desc|firstline}\n"
295 $ hg -R largefiles-repo-hg glog --template "{rev}:{node|short} {desc|firstline}\n"
296 o 6:17126745edfd add anotherlarge (should be a largefile)
296 o 6:17126745edfd add anotherlarge (should be a largefile)
297 |
297 |
298 o 5:9cc5aa7204f0 merge
298 o 5:9cc5aa7204f0 merge
299 |\
299 |\
300 | o 4:a5a02de7a8e4 remove large, normal3
300 | o 4:a5a02de7a8e4 remove large, normal3
301 | |
301 | |
302 | o 3:55759520c76f add normal3, modify sub/*
302 | o 3:55759520c76f add normal3, modify sub/*
303 | |
303 | |
304 o | 2:261ad3f3f037 rename sub/ to stuff/
304 o | 2:261ad3f3f037 rename sub/ to stuff/
305 |/
305 |/
306 o 1:334e5237836d add sub/*
306 o 1:334e5237836d add sub/*
307 |
307 |
308 o 0:d4892ec57ce2 add large, normal1
308 o 0:d4892ec57ce2 add large, normal1
309
309
310 Verify will fail (for now) if the usercache is purged before converting, since
310 Verify will fail (for now) if the usercache is purged before converting, since
311 largefiles are not cached in the converted repo's local store by the conversion
311 largefiles are not cached in the converted repo's local store by the conversion
312 process.
312 process.
313 $ hg -R largefiles-repo-hg verify --large --lfa
313 $ hg -R largefiles-repo-hg verify --large --lfa
314 checking changesets
314 checking changesets
315 checking manifests
315 checking manifests
316 crosschecking files in changesets and manifests
316 crosschecking files in changesets and manifests
317 checking files
317 checking files
318 8 files, 7 changesets, 12 total revisions
318 8 files, 7 changesets, 12 total revisions
319 searching 7 changesets for largefiles
319 searching 7 changesets for largefiles
320 changeset 0:d4892ec57ce2: large missing
320 changeset 0:d4892ec57ce2: large missing
321 (looked for hash 2e000fa7e85759c7f4c254d4d9c33ef481e459a7)
321 (looked for hash 2e000fa7e85759c7f4c254d4d9c33ef481e459a7)
322 changeset 1:334e5237836d: sub/maybelarge.dat missing
322 changeset 1:334e5237836d: sub/maybelarge.dat missing
323 (looked for hash 34e163be8e43c5631d8b92e9c43ab0bf0fa62b9c)
323 (looked for hash 34e163be8e43c5631d8b92e9c43ab0bf0fa62b9c)
324 changeset 2:261ad3f3f037: stuff/maybelarge.dat missing
324 changeset 2:261ad3f3f037: stuff/maybelarge.dat missing
325 (looked for hash 34e163be8e43c5631d8b92e9c43ab0bf0fa62b9c)
325 (looked for hash 34e163be8e43c5631d8b92e9c43ab0bf0fa62b9c)
326 changeset 3:55759520c76f: sub/maybelarge.dat missing
326 changeset 3:55759520c76f: sub/maybelarge.dat missing
327 (looked for hash 76236b6a2c6102826c61af4297dd738fb3b1de38)
327 (looked for hash 76236b6a2c6102826c61af4297dd738fb3b1de38)
328 changeset 5:9cc5aa7204f0: stuff/maybelarge.dat missing
328 changeset 5:9cc5aa7204f0: stuff/maybelarge.dat missing
329 (looked for hash 76236b6a2c6102826c61af4297dd738fb3b1de38)
329 (looked for hash 76236b6a2c6102826c61af4297dd738fb3b1de38)
330 changeset 6:17126745edfd: anotherlarge missing
330 changeset 6:17126745edfd: anotherlarge missing
331 (looked for hash 3b71f43ff30f4b15b5cd85dd9e95ebc7e84eb5a3)
331 (looked for hash 3b71f43ff30f4b15b5cd85dd9e95ebc7e84eb5a3)
332 verified existence of 6 revisions of 4 largefiles
332 verified existence of 6 revisions of 4 largefiles
333 [1]
333 [1]
334 $ hg -R largefiles-repo-hg showconfig paths
334 $ hg -R largefiles-repo-hg showconfig paths
335
335
336
336
337 Avoid a traceback if a largefile isn't available (issue3519)
337 Avoid a traceback if a largefile isn't available (issue3519)
338
338
339 Ensure the largefile can be cached in the source if necessary
339 Ensure the largefile can be cached in the source if necessary
340 $ hg clone -U largefiles-repo issue3519
340 $ hg clone -U largefiles-repo issue3519
341 $ rm -f "${USERCACHE}"/*
341 $ rm -f "${USERCACHE}"/*
342 $ hg lfconvert --to-normal issue3519 normalized3519
342 $ hg lfconvert --to-normal issue3519 normalized3519
343 initializing destination normalized3519
343 initializing destination normalized3519
344
344
345 Ensure the abort message is useful if a largefile is entirely unavailable
345 Ensure the abort message is useful if a largefile is entirely unavailable
346 $ rm -rf normalized3519
346 $ rm -rf normalized3519
347 $ rm "${USERCACHE}"/*
347 $ rm "${USERCACHE}"/*
348 $ rm issue3519/.hg/largefiles/*
348 $ rm issue3519/.hg/largefiles/*
349 $ rm largefiles-repo/.hg/largefiles/*
349 $ rm largefiles-repo/.hg/largefiles/*
350 $ hg lfconvert --to-normal issue3519 normalized3519
350 $ hg lfconvert --to-normal issue3519 normalized3519
351 initializing destination normalized3519
351 initializing destination normalized3519
352 error getting 2e000fa7e85759c7f4c254d4d9c33ef481e459a7 from file:$TESTTMP/largefiles-repo for large: can't get file locally (glob)
352 error getting 2e000fa7e85759c7f4c254d4d9c33ef481e459a7 from file:$TESTTMP/largefiles-repo for large: can't get file locally (glob)
353 abort: missing largefile 'large' from revision d4892ec57ce212905215fad1d9018f56b99202ad
353 abort: missing largefile 'large' from revision d4892ec57ce212905215fad1d9018f56b99202ad
354 [255]
354 [255]
355
355
356
356
General Comments 0
You need to be logged in to leave comments. Login now