##// END OF EJS Templates
largefiles: exit from remove with 1 on warnings...
Matt Harbison -
r17576:e0081bb5 stable
parent child Browse files
Show More
@@ -1,1082 +1,1087
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
15 node, archival, error, merge
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 lfutil.repoadd(repo, standins)
119 for f in lfutil.repoadd(repo, 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, reason):
140 def warn(files, reason):
141 for f in files:
141 for f in files:
142 ui.warn(_('not removing %s: %s (use forget to undo)\n')
142 ui.warn(_('not removing %s: %s (use forget to undo)\n')
143 % (m.rel(f), reason))
143 % (m.rel(f), reason))
144 return int(len(files) > 0)
145
146 result = 0
144
147
145 if after:
148 if after:
146 remove, forget = deleted, []
149 remove, forget = deleted, []
147 warn(modified + added + clean, _('file still exists'))
150 result = warn(modified + added + clean, _('file still exists'))
148 else:
151 else:
149 remove, forget = deleted + clean, []
152 remove, forget = deleted + clean, []
150 warn(modified, _('file is modified'))
153 result = warn(modified, _('file is modified'))
151 warn(added, _('file has been marked for add'))
154 result = warn(added, _('file has been marked for add')) or result
152
155
153 for f in sorted(remove + forget):
156 for f in sorted(remove + forget):
154 if ui.verbose or not m.exact(f):
157 if ui.verbose or not m.exact(f):
155 ui.status(_('removing %s\n') % m.rel(f))
158 ui.status(_('removing %s\n') % m.rel(f))
156
159
157 # Need to lock because standin files are deleted then removed from the
160 # Need to lock because standin files are deleted then removed from the
158 # repository and we could race inbetween.
161 # repository and we could race inbetween.
159 wlock = repo.wlock()
162 wlock = repo.wlock()
160 try:
163 try:
161 lfdirstate = lfutil.openlfdirstate(ui, repo)
164 lfdirstate = lfutil.openlfdirstate(ui, repo)
162 for f in remove:
165 for f in remove:
163 if not after:
166 if not after:
164 # If this is being called by addremove, notify the user that we
167 # If this is being called by addremove, notify the user that we
165 # are removing the file.
168 # are removing the file.
166 if getattr(repo, "_isaddremove", False):
169 if getattr(repo, "_isaddremove", False):
167 ui.status(_('removing %s\n') % f)
170 ui.status(_('removing %s\n') % f)
168 if os.path.exists(repo.wjoin(f)):
171 if os.path.exists(repo.wjoin(f)):
169 util.unlinkpath(repo.wjoin(f))
172 util.unlinkpath(repo.wjoin(f))
170 lfdirstate.remove(f)
173 lfdirstate.remove(f)
171 lfdirstate.write()
174 lfdirstate.write()
172 forget = [lfutil.standin(f) for f in forget]
175 forget = [lfutil.standin(f) for f in forget]
173 remove = [lfutil.standin(f) for f in remove]
176 remove = [lfutil.standin(f) for f in remove]
174 lfutil.repoforget(repo, forget)
177 lfutil.repoforget(repo, forget)
175 # If this is being called by addremove, let the original addremove
178 # If this is being called by addremove, let the original addremove
176 # function handle this.
179 # function handle this.
177 if not getattr(repo, "_isaddremove", False):
180 if not getattr(repo, "_isaddremove", False):
178 lfutil.reporemove(repo, remove, unlink=True)
181 lfutil.reporemove(repo, remove, unlink=True)
179 else:
182 else:
180 lfutil.reporemove(repo, remove, unlink=False)
183 lfutil.reporemove(repo, remove, unlink=False)
181 finally:
184 finally:
182 wlock.release()
185 wlock.release()
183
186
187 return result
188
184 # For overriding mercurial.hgweb.webcommands so that largefiles will
189 # For overriding mercurial.hgweb.webcommands so that largefiles will
185 # appear at their right place in the manifests.
190 # appear at their right place in the manifests.
186 def decodepath(orig, path):
191 def decodepath(orig, path):
187 return lfutil.splitstandin(path) or path
192 return lfutil.splitstandin(path) or path
188
193
189 # -- Wrappers: modify existing commands --------------------------------
194 # -- Wrappers: modify existing commands --------------------------------
190
195
191 # Add works by going through the files that the user wanted to add and
196 # Add works by going through the files that the user wanted to add and
192 # checking if they should be added as largefiles. Then it makes a new
197 # checking if they should be added as largefiles. Then it makes a new
193 # matcher which matches only the normal files and runs the original
198 # matcher which matches only the normal files and runs the original
194 # version of add.
199 # version of add.
195 def overrideadd(orig, ui, repo, *pats, **opts):
200 def overrideadd(orig, ui, repo, *pats, **opts):
196 normal = opts.pop('normal')
201 normal = opts.pop('normal')
197 if normal:
202 if normal:
198 if opts.get('large'):
203 if opts.get('large'):
199 raise util.Abort(_('--normal cannot be used with --large'))
204 raise util.Abort(_('--normal cannot be used with --large'))
200 return orig(ui, repo, *pats, **opts)
205 return orig(ui, repo, *pats, **opts)
201 bad = addlargefiles(ui, repo, *pats, **opts)
206 bad = addlargefiles(ui, repo, *pats, **opts)
202 installnormalfilesmatchfn(repo[None].manifest())
207 installnormalfilesmatchfn(repo[None].manifest())
203 result = orig(ui, repo, *pats, **opts)
208 result = orig(ui, repo, *pats, **opts)
204 restorematchfn()
209 restorematchfn()
205
210
206 return (result == 1 or bad) and 1 or 0
211 return (result == 1 or bad) and 1 or 0
207
212
208 def overrideremove(orig, ui, repo, *pats, **opts):
213 def overrideremove(orig, ui, repo, *pats, **opts):
209 installnormalfilesmatchfn(repo[None].manifest())
214 installnormalfilesmatchfn(repo[None].manifest())
210 orig(ui, repo, *pats, **opts)
215 result = orig(ui, repo, *pats, **opts)
211 restorematchfn()
216 restorematchfn()
212 removelargefiles(ui, repo, *pats, **opts)
217 return removelargefiles(ui, repo, *pats, **opts) or result
213
218
214 def overridestatusfn(orig, repo, rev2, **opts):
219 def overridestatusfn(orig, repo, rev2, **opts):
215 try:
220 try:
216 repo._repo.lfstatus = True
221 repo._repo.lfstatus = True
217 return orig(repo, rev2, **opts)
222 return orig(repo, rev2, **opts)
218 finally:
223 finally:
219 repo._repo.lfstatus = False
224 repo._repo.lfstatus = False
220
225
221 def overridestatus(orig, ui, repo, *pats, **opts):
226 def overridestatus(orig, ui, repo, *pats, **opts):
222 try:
227 try:
223 repo.lfstatus = True
228 repo.lfstatus = True
224 return orig(ui, repo, *pats, **opts)
229 return orig(ui, repo, *pats, **opts)
225 finally:
230 finally:
226 repo.lfstatus = False
231 repo.lfstatus = False
227
232
228 def overridedirty(orig, repo, ignoreupdate=False):
233 def overridedirty(orig, repo, ignoreupdate=False):
229 try:
234 try:
230 repo._repo.lfstatus = True
235 repo._repo.lfstatus = True
231 return orig(repo, ignoreupdate)
236 return orig(repo, ignoreupdate)
232 finally:
237 finally:
233 repo._repo.lfstatus = False
238 repo._repo.lfstatus = False
234
239
235 def overridelog(orig, ui, repo, *pats, **opts):
240 def overridelog(orig, ui, repo, *pats, **opts):
236 try:
241 try:
237 repo.lfstatus = True
242 repo.lfstatus = True
238 orig(ui, repo, *pats, **opts)
243 orig(ui, repo, *pats, **opts)
239 finally:
244 finally:
240 repo.lfstatus = False
245 repo.lfstatus = False
241
246
242 def overrideverify(orig, ui, repo, *pats, **opts):
247 def overrideverify(orig, ui, repo, *pats, **opts):
243 large = opts.pop('large', False)
248 large = opts.pop('large', False)
244 all = opts.pop('lfa', False)
249 all = opts.pop('lfa', False)
245 contents = opts.pop('lfc', False)
250 contents = opts.pop('lfc', False)
246
251
247 result = orig(ui, repo, *pats, **opts)
252 result = orig(ui, repo, *pats, **opts)
248 if large:
253 if large:
249 result = result or lfcommands.verifylfiles(ui, repo, all, contents)
254 result = result or lfcommands.verifylfiles(ui, repo, all, contents)
250 return result
255 return result
251
256
252 # Override needs to refresh standins so that update's normal merge
257 # Override needs to refresh standins so that update's normal merge
253 # will go through properly. Then the other update hook (overriding repo.update)
258 # will go through properly. Then the other update hook (overriding repo.update)
254 # will get the new files. Filemerge is also overriden so that the merge
259 # will get the new files. Filemerge is also overriden so that the merge
255 # will merge standins correctly.
260 # will merge standins correctly.
256 def overrideupdate(orig, ui, repo, *pats, **opts):
261 def overrideupdate(orig, ui, repo, *pats, **opts):
257 lfdirstate = lfutil.openlfdirstate(ui, repo)
262 lfdirstate = lfutil.openlfdirstate(ui, repo)
258 s = lfdirstate.status(match_.always(repo.root, repo.getcwd()), [], False,
263 s = lfdirstate.status(match_.always(repo.root, repo.getcwd()), [], False,
259 False, False)
264 False, False)
260 (unsure, modified, added, removed, missing, unknown, ignored, clean) = s
265 (unsure, modified, added, removed, missing, unknown, ignored, clean) = s
261
266
262 # Need to lock between the standins getting updated and their
267 # Need to lock between the standins getting updated and their
263 # largefiles getting updated
268 # largefiles getting updated
264 wlock = repo.wlock()
269 wlock = repo.wlock()
265 try:
270 try:
266 if opts['check']:
271 if opts['check']:
267 mod = len(modified) > 0
272 mod = len(modified) > 0
268 for lfile in unsure:
273 for lfile in unsure:
269 standin = lfutil.standin(lfile)
274 standin = lfutil.standin(lfile)
270 if repo['.'][standin].data().strip() != \
275 if repo['.'][standin].data().strip() != \
271 lfutil.hashfile(repo.wjoin(lfile)):
276 lfutil.hashfile(repo.wjoin(lfile)):
272 mod = True
277 mod = True
273 else:
278 else:
274 lfdirstate.normal(lfile)
279 lfdirstate.normal(lfile)
275 lfdirstate.write()
280 lfdirstate.write()
276 if mod:
281 if mod:
277 raise util.Abort(_('uncommitted local changes'))
282 raise util.Abort(_('uncommitted local changes'))
278 # XXX handle removed differently
283 # XXX handle removed differently
279 if not opts['clean']:
284 if not opts['clean']:
280 for lfile in unsure + modified + added:
285 for lfile in unsure + modified + added:
281 lfutil.updatestandin(repo, lfutil.standin(lfile))
286 lfutil.updatestandin(repo, lfutil.standin(lfile))
282 finally:
287 finally:
283 wlock.release()
288 wlock.release()
284 return orig(ui, repo, *pats, **opts)
289 return orig(ui, repo, *pats, **opts)
285
290
286 # Before starting the manifest merge, merge.updates will call
291 # Before starting the manifest merge, merge.updates will call
287 # _checkunknown to check if there are any files in the merged-in
292 # _checkunknown to check if there are any files in the merged-in
288 # changeset that collide with unknown files in the working copy.
293 # changeset that collide with unknown files in the working copy.
289 #
294 #
290 # The largefiles are seen as unknown, so this prevents us from merging
295 # The largefiles are seen as unknown, so this prevents us from merging
291 # in a file 'foo' if we already have a largefile with the same name.
296 # in a file 'foo' if we already have a largefile with the same name.
292 #
297 #
293 # The overridden function filters the unknown files by removing any
298 # The overridden function filters the unknown files by removing any
294 # largefiles. This makes the merge proceed and we can then handle this
299 # largefiles. This makes the merge proceed and we can then handle this
295 # case further in the overridden manifestmerge function below.
300 # case further in the overridden manifestmerge function below.
296 def overridecheckunknownfile(origfn, repo, wctx, mctx, f):
301 def overridecheckunknownfile(origfn, repo, wctx, mctx, f):
297 if lfutil.standin(f) in wctx:
302 if lfutil.standin(f) in wctx:
298 return False
303 return False
299 return origfn(repo, wctx, mctx, f)
304 return origfn(repo, wctx, mctx, f)
300
305
301 # The manifest merge handles conflicts on the manifest level. We want
306 # The manifest merge handles conflicts on the manifest level. We want
302 # to handle changes in largefile-ness of files at this level too.
307 # to handle changes in largefile-ness of files at this level too.
303 #
308 #
304 # The strategy is to run the original manifestmerge and then process
309 # The strategy is to run the original manifestmerge and then process
305 # the action list it outputs. There are two cases we need to deal with:
310 # the action list it outputs. There are two cases we need to deal with:
306 #
311 #
307 # 1. Normal file in p1, largefile in p2. Here the largefile is
312 # 1. Normal file in p1, largefile in p2. Here the largefile is
308 # detected via its standin file, which will enter the working copy
313 # detected via its standin file, which will enter the working copy
309 # with a "get" action. It is not "merge" since the standin is all
314 # with a "get" action. It is not "merge" since the standin is all
310 # Mercurial is concerned with at this level -- the link to the
315 # Mercurial is concerned with at this level -- the link to the
311 # existing normal file is not relevant here.
316 # existing normal file is not relevant here.
312 #
317 #
313 # 2. Largefile in p1, normal file in p2. Here we get a "merge" action
318 # 2. Largefile in p1, normal file in p2. Here we get a "merge" action
314 # since the largefile will be present in the working copy and
319 # since the largefile will be present in the working copy and
315 # different from the normal file in p2. Mercurial therefore
320 # different from the normal file in p2. Mercurial therefore
316 # triggers a merge action.
321 # triggers a merge action.
317 #
322 #
318 # In both cases, we prompt the user and emit new actions to either
323 # In both cases, we prompt the user and emit new actions to either
319 # remove the standin (if the normal file was kept) or to remove the
324 # remove the standin (if the normal file was kept) or to remove the
320 # normal file and get the standin (if the largefile was kept). The
325 # normal file and get the standin (if the largefile was kept). The
321 # default prompt answer is to use the largefile version since it was
326 # default prompt answer is to use the largefile version since it was
322 # presumably changed on purpose.
327 # presumably changed on purpose.
323 #
328 #
324 # Finally, the merge.applyupdates function will then take care of
329 # Finally, the merge.applyupdates function will then take care of
325 # writing the files into the working copy and lfcommands.updatelfiles
330 # writing the files into the working copy and lfcommands.updatelfiles
326 # will update the largefiles.
331 # will update the largefiles.
327 def overridemanifestmerge(origfn, repo, p1, p2, pa, overwrite, partial):
332 def overridemanifestmerge(origfn, repo, p1, p2, pa, overwrite, partial):
328 actions = origfn(repo, p1, p2, pa, overwrite, partial)
333 actions = origfn(repo, p1, p2, pa, overwrite, partial)
329 processed = []
334 processed = []
330
335
331 for action in actions:
336 for action in actions:
332 if overwrite:
337 if overwrite:
333 processed.append(action)
338 processed.append(action)
334 continue
339 continue
335 f, m = action[:2]
340 f, m = action[:2]
336
341
337 choices = (_('&Largefile'), _('&Normal file'))
342 choices = (_('&Largefile'), _('&Normal file'))
338 if m == "g" and lfutil.splitstandin(f) in p1 and f in p2:
343 if m == "g" and lfutil.splitstandin(f) in p1 and f in p2:
339 # Case 1: normal file in the working copy, largefile in
344 # Case 1: normal file in the working copy, largefile in
340 # the second parent
345 # the second parent
341 lfile = lfutil.splitstandin(f)
346 lfile = lfutil.splitstandin(f)
342 standin = f
347 standin = f
343 msg = _('%s has been turned into a largefile\n'
348 msg = _('%s has been turned into a largefile\n'
344 'use (l)argefile or keep as (n)ormal file?') % lfile
349 'use (l)argefile or keep as (n)ormal file?') % lfile
345 if repo.ui.promptchoice(msg, choices, 0) == 0:
350 if repo.ui.promptchoice(msg, choices, 0) == 0:
346 processed.append((lfile, "r"))
351 processed.append((lfile, "r"))
347 processed.append((standin, "g", p2.flags(standin)))
352 processed.append((standin, "g", p2.flags(standin)))
348 else:
353 else:
349 processed.append((standin, "r"))
354 processed.append((standin, "r"))
350 elif m == "g" and lfutil.standin(f) in p1 and f in p2:
355 elif m == "g" and lfutil.standin(f) in p1 and f in p2:
351 # Case 2: largefile in the working copy, normal file in
356 # Case 2: largefile in the working copy, normal file in
352 # the second parent
357 # the second parent
353 standin = lfutil.standin(f)
358 standin = lfutil.standin(f)
354 lfile = f
359 lfile = f
355 msg = _('%s has been turned into a normal file\n'
360 msg = _('%s has been turned into a normal file\n'
356 'keep as (l)argefile or use (n)ormal file?') % lfile
361 'keep as (l)argefile or use (n)ormal file?') % lfile
357 if repo.ui.promptchoice(msg, choices, 0) == 0:
362 if repo.ui.promptchoice(msg, choices, 0) == 0:
358 processed.append((lfile, "r"))
363 processed.append((lfile, "r"))
359 else:
364 else:
360 processed.append((standin, "r"))
365 processed.append((standin, "r"))
361 processed.append((lfile, "g", p2.flags(lfile)))
366 processed.append((lfile, "g", p2.flags(lfile)))
362 else:
367 else:
363 processed.append(action)
368 processed.append(action)
364
369
365 return processed
370 return processed
366
371
367 # Override filemerge to prompt the user about how they wish to merge
372 # Override filemerge to prompt the user about how they wish to merge
368 # largefiles. This will handle identical edits, and copy/rename +
373 # largefiles. This will handle identical edits, and copy/rename +
369 # edit without prompting the user.
374 # edit without prompting the user.
370 def overridefilemerge(origfn, repo, mynode, orig, fcd, fco, fca):
375 def overridefilemerge(origfn, repo, mynode, orig, fcd, fco, fca):
371 # Use better variable names here. Because this is a wrapper we cannot
376 # Use better variable names here. Because this is a wrapper we cannot
372 # change the variable names in the function declaration.
377 # change the variable names in the function declaration.
373 fcdest, fcother, fcancestor = fcd, fco, fca
378 fcdest, fcother, fcancestor = fcd, fco, fca
374 if not lfutil.isstandin(orig):
379 if not lfutil.isstandin(orig):
375 return origfn(repo, mynode, orig, fcdest, fcother, fcancestor)
380 return origfn(repo, mynode, orig, fcdest, fcother, fcancestor)
376 else:
381 else:
377 if not fcother.cmp(fcdest): # files identical?
382 if not fcother.cmp(fcdest): # files identical?
378 return None
383 return None
379
384
380 # backwards, use working dir parent as ancestor
385 # backwards, use working dir parent as ancestor
381 if fcancestor == fcother:
386 if fcancestor == fcother:
382 fcancestor = fcdest.parents()[0]
387 fcancestor = fcdest.parents()[0]
383
388
384 if orig != fcother.path():
389 if orig != fcother.path():
385 repo.ui.status(_('merging %s and %s to %s\n')
390 repo.ui.status(_('merging %s and %s to %s\n')
386 % (lfutil.splitstandin(orig),
391 % (lfutil.splitstandin(orig),
387 lfutil.splitstandin(fcother.path()),
392 lfutil.splitstandin(fcother.path()),
388 lfutil.splitstandin(fcdest.path())))
393 lfutil.splitstandin(fcdest.path())))
389 else:
394 else:
390 repo.ui.status(_('merging %s\n')
395 repo.ui.status(_('merging %s\n')
391 % lfutil.splitstandin(fcdest.path()))
396 % lfutil.splitstandin(fcdest.path()))
392
397
393 if fcancestor.path() != fcother.path() and fcother.data() == \
398 if fcancestor.path() != fcother.path() and fcother.data() == \
394 fcancestor.data():
399 fcancestor.data():
395 return 0
400 return 0
396 if fcancestor.path() != fcdest.path() and fcdest.data() == \
401 if fcancestor.path() != fcdest.path() and fcdest.data() == \
397 fcancestor.data():
402 fcancestor.data():
398 repo.wwrite(fcdest.path(), fcother.data(), fcother.flags())
403 repo.wwrite(fcdest.path(), fcother.data(), fcother.flags())
399 return 0
404 return 0
400
405
401 if repo.ui.promptchoice(_('largefile %s has a merge conflict\n'
406 if repo.ui.promptchoice(_('largefile %s has a merge conflict\n'
402 'keep (l)ocal or take (o)ther?') %
407 'keep (l)ocal or take (o)ther?') %
403 lfutil.splitstandin(orig),
408 lfutil.splitstandin(orig),
404 (_('&Local'), _('&Other')), 0) == 0:
409 (_('&Local'), _('&Other')), 0) == 0:
405 return 0
410 return 0
406 else:
411 else:
407 repo.wwrite(fcdest.path(), fcother.data(), fcother.flags())
412 repo.wwrite(fcdest.path(), fcother.data(), fcother.flags())
408 return 0
413 return 0
409
414
410 # Copy first changes the matchers to match standins instead of
415 # Copy first changes the matchers to match standins instead of
411 # largefiles. Then it overrides util.copyfile in that function it
416 # largefiles. Then it overrides util.copyfile in that function it
412 # checks if the destination largefile already exists. It also keeps a
417 # checks if the destination largefile already exists. It also keeps a
413 # list of copied files so that the largefiles can be copied and the
418 # list of copied files so that the largefiles can be copied and the
414 # dirstate updated.
419 # dirstate updated.
415 def overridecopy(orig, ui, repo, pats, opts, rename=False):
420 def overridecopy(orig, ui, repo, pats, opts, rename=False):
416 # doesn't remove largefile on rename
421 # doesn't remove largefile on rename
417 if len(pats) < 2:
422 if len(pats) < 2:
418 # this isn't legal, let the original function deal with it
423 # this isn't legal, let the original function deal with it
419 return orig(ui, repo, pats, opts, rename)
424 return orig(ui, repo, pats, opts, rename)
420
425
421 def makestandin(relpath):
426 def makestandin(relpath):
422 path = scmutil.canonpath(repo.root, repo.getcwd(), relpath)
427 path = scmutil.canonpath(repo.root, repo.getcwd(), relpath)
423 return os.path.join(repo.wjoin(lfutil.standin(path)))
428 return os.path.join(repo.wjoin(lfutil.standin(path)))
424
429
425 fullpats = scmutil.expandpats(pats)
430 fullpats = scmutil.expandpats(pats)
426 dest = fullpats[-1]
431 dest = fullpats[-1]
427
432
428 if os.path.isdir(dest):
433 if os.path.isdir(dest):
429 if not os.path.isdir(makestandin(dest)):
434 if not os.path.isdir(makestandin(dest)):
430 os.makedirs(makestandin(dest))
435 os.makedirs(makestandin(dest))
431 # This could copy both lfiles and normal files in one command,
436 # This could copy both lfiles and normal files in one command,
432 # but we don't want to do that. First replace their matcher to
437 # but we don't want to do that. First replace their matcher to
433 # only match normal files and run it, then replace it to just
438 # only match normal files and run it, then replace it to just
434 # match largefiles and run it again.
439 # match largefiles and run it again.
435 nonormalfiles = False
440 nonormalfiles = False
436 nolfiles = False
441 nolfiles = False
437 try:
442 try:
438 try:
443 try:
439 installnormalfilesmatchfn(repo[None].manifest())
444 installnormalfilesmatchfn(repo[None].manifest())
440 result = orig(ui, repo, pats, opts, rename)
445 result = orig(ui, repo, pats, opts, rename)
441 except util.Abort, e:
446 except util.Abort, e:
442 if str(e) != _('no files to copy'):
447 if str(e) != _('no files to copy'):
443 raise e
448 raise e
444 else:
449 else:
445 nonormalfiles = True
450 nonormalfiles = True
446 result = 0
451 result = 0
447 finally:
452 finally:
448 restorematchfn()
453 restorematchfn()
449
454
450 # The first rename can cause our current working directory to be removed.
455 # The first rename can cause our current working directory to be removed.
451 # In that case there is nothing left to copy/rename so just quit.
456 # In that case there is nothing left to copy/rename so just quit.
452 try:
457 try:
453 repo.getcwd()
458 repo.getcwd()
454 except OSError:
459 except OSError:
455 return result
460 return result
456
461
457 try:
462 try:
458 try:
463 try:
459 # When we call orig below it creates the standins but we don't add
464 # When we call orig below it creates the standins but we don't add
460 # them to the dir state until later so lock during that time.
465 # them to the dir state until later so lock during that time.
461 wlock = repo.wlock()
466 wlock = repo.wlock()
462
467
463 manifest = repo[None].manifest()
468 manifest = repo[None].manifest()
464 oldmatch = None # for the closure
469 oldmatch = None # for the closure
465 def overridematch(ctx, pats=[], opts={}, globbed=False,
470 def overridematch(ctx, pats=[], opts={}, globbed=False,
466 default='relpath'):
471 default='relpath'):
467 newpats = []
472 newpats = []
468 # The patterns were previously mangled to add the standin
473 # The patterns were previously mangled to add the standin
469 # directory; we need to remove that now
474 # directory; we need to remove that now
470 for pat in pats:
475 for pat in pats:
471 if match_.patkind(pat) is None and lfutil.shortname in pat:
476 if match_.patkind(pat) is None and lfutil.shortname in pat:
472 newpats.append(pat.replace(lfutil.shortname, ''))
477 newpats.append(pat.replace(lfutil.shortname, ''))
473 else:
478 else:
474 newpats.append(pat)
479 newpats.append(pat)
475 match = oldmatch(ctx, newpats, opts, globbed, default)
480 match = oldmatch(ctx, newpats, opts, globbed, default)
476 m = copy.copy(match)
481 m = copy.copy(match)
477 lfile = lambda f: lfutil.standin(f) in manifest
482 lfile = lambda f: lfutil.standin(f) in manifest
478 m._files = [lfutil.standin(f) for f in m._files if lfile(f)]
483 m._files = [lfutil.standin(f) for f in m._files if lfile(f)]
479 m._fmap = set(m._files)
484 m._fmap = set(m._files)
480 origmatchfn = m.matchfn
485 origmatchfn = m.matchfn
481 m.matchfn = lambda f: (lfutil.isstandin(f) and
486 m.matchfn = lambda f: (lfutil.isstandin(f) and
482 (f in manifest) and
487 (f in manifest) and
483 origmatchfn(lfutil.splitstandin(f)) or
488 origmatchfn(lfutil.splitstandin(f)) or
484 None)
489 None)
485 return m
490 return m
486 oldmatch = installmatchfn(overridematch)
491 oldmatch = installmatchfn(overridematch)
487 listpats = []
492 listpats = []
488 for pat in pats:
493 for pat in pats:
489 if match_.patkind(pat) is not None:
494 if match_.patkind(pat) is not None:
490 listpats.append(pat)
495 listpats.append(pat)
491 else:
496 else:
492 listpats.append(makestandin(pat))
497 listpats.append(makestandin(pat))
493
498
494 try:
499 try:
495 origcopyfile = util.copyfile
500 origcopyfile = util.copyfile
496 copiedfiles = []
501 copiedfiles = []
497 def overridecopyfile(src, dest):
502 def overridecopyfile(src, dest):
498 if (lfutil.shortname in src and
503 if (lfutil.shortname in src and
499 dest.startswith(repo.wjoin(lfutil.shortname))):
504 dest.startswith(repo.wjoin(lfutil.shortname))):
500 destlfile = dest.replace(lfutil.shortname, '')
505 destlfile = dest.replace(lfutil.shortname, '')
501 if not opts['force'] and os.path.exists(destlfile):
506 if not opts['force'] and os.path.exists(destlfile):
502 raise IOError('',
507 raise IOError('',
503 _('destination largefile already exists'))
508 _('destination largefile already exists'))
504 copiedfiles.append((src, dest))
509 copiedfiles.append((src, dest))
505 origcopyfile(src, dest)
510 origcopyfile(src, dest)
506
511
507 util.copyfile = overridecopyfile
512 util.copyfile = overridecopyfile
508 result += orig(ui, repo, listpats, opts, rename)
513 result += orig(ui, repo, listpats, opts, rename)
509 finally:
514 finally:
510 util.copyfile = origcopyfile
515 util.copyfile = origcopyfile
511
516
512 lfdirstate = lfutil.openlfdirstate(ui, repo)
517 lfdirstate = lfutil.openlfdirstate(ui, repo)
513 for (src, dest) in copiedfiles:
518 for (src, dest) in copiedfiles:
514 if (lfutil.shortname in src and
519 if (lfutil.shortname in src and
515 dest.startswith(repo.wjoin(lfutil.shortname))):
520 dest.startswith(repo.wjoin(lfutil.shortname))):
516 srclfile = src.replace(repo.wjoin(lfutil.standin('')), '')
521 srclfile = src.replace(repo.wjoin(lfutil.standin('')), '')
517 destlfile = dest.replace(repo.wjoin(lfutil.standin('')), '')
522 destlfile = dest.replace(repo.wjoin(lfutil.standin('')), '')
518 destlfiledir = os.path.dirname(repo.wjoin(destlfile)) or '.'
523 destlfiledir = os.path.dirname(repo.wjoin(destlfile)) or '.'
519 if not os.path.isdir(destlfiledir):
524 if not os.path.isdir(destlfiledir):
520 os.makedirs(destlfiledir)
525 os.makedirs(destlfiledir)
521 if rename:
526 if rename:
522 os.rename(repo.wjoin(srclfile), repo.wjoin(destlfile))
527 os.rename(repo.wjoin(srclfile), repo.wjoin(destlfile))
523 lfdirstate.remove(srclfile)
528 lfdirstate.remove(srclfile)
524 else:
529 else:
525 util.copyfile(repo.wjoin(srclfile),
530 util.copyfile(repo.wjoin(srclfile),
526 repo.wjoin(destlfile))
531 repo.wjoin(destlfile))
527
532
528 lfdirstate.add(destlfile)
533 lfdirstate.add(destlfile)
529 lfdirstate.write()
534 lfdirstate.write()
530 except util.Abort, e:
535 except util.Abort, e:
531 if str(e) != _('no files to copy'):
536 if str(e) != _('no files to copy'):
532 raise e
537 raise e
533 else:
538 else:
534 nolfiles = True
539 nolfiles = True
535 finally:
540 finally:
536 restorematchfn()
541 restorematchfn()
537 wlock.release()
542 wlock.release()
538
543
539 if nolfiles and nonormalfiles:
544 if nolfiles and nonormalfiles:
540 raise util.Abort(_('no files to copy'))
545 raise util.Abort(_('no files to copy'))
541
546
542 return result
547 return result
543
548
544 # When the user calls revert, we have to be careful to not revert any
549 # When the user calls revert, we have to be careful to not revert any
545 # changes to other largefiles accidentally. This means we have to keep
550 # changes to other largefiles accidentally. This means we have to keep
546 # track of the largefiles that are being reverted so we only pull down
551 # track of the largefiles that are being reverted so we only pull down
547 # the necessary largefiles.
552 # the necessary largefiles.
548 #
553 #
549 # Standins are only updated (to match the hash of largefiles) before
554 # Standins are only updated (to match the hash of largefiles) before
550 # commits. Update the standins then run the original revert, changing
555 # commits. Update the standins then run the original revert, changing
551 # the matcher to hit standins instead of largefiles. Based on the
556 # the matcher to hit standins instead of largefiles. Based on the
552 # resulting standins update the largefiles. Then return the standins
557 # resulting standins update the largefiles. Then return the standins
553 # to their proper state
558 # to their proper state
554 def overriderevert(orig, ui, repo, *pats, **opts):
559 def overriderevert(orig, ui, repo, *pats, **opts):
555 # Because we put the standins in a bad state (by updating them)
560 # Because we put the standins in a bad state (by updating them)
556 # and then return them to a correct state we need to lock to
561 # and then return them to a correct state we need to lock to
557 # prevent others from changing them in their incorrect state.
562 # prevent others from changing them in their incorrect state.
558 wlock = repo.wlock()
563 wlock = repo.wlock()
559 try:
564 try:
560 lfdirstate = lfutil.openlfdirstate(ui, repo)
565 lfdirstate = lfutil.openlfdirstate(ui, repo)
561 (modified, added, removed, missing, unknown, ignored, clean) = \
566 (modified, added, removed, missing, unknown, ignored, clean) = \
562 lfutil.lfdirstatestatus(lfdirstate, repo, repo['.'].rev())
567 lfutil.lfdirstatestatus(lfdirstate, repo, repo['.'].rev())
563 for lfile in modified:
568 for lfile in modified:
564 lfutil.updatestandin(repo, lfutil.standin(lfile))
569 lfutil.updatestandin(repo, lfutil.standin(lfile))
565 for lfile in missing:
570 for lfile in missing:
566 if (os.path.exists(repo.wjoin(lfutil.standin(lfile)))):
571 if (os.path.exists(repo.wjoin(lfutil.standin(lfile)))):
567 os.unlink(repo.wjoin(lfutil.standin(lfile)))
572 os.unlink(repo.wjoin(lfutil.standin(lfile)))
568
573
569 try:
574 try:
570 ctx = scmutil.revsingle(repo, opts.get('rev'))
575 ctx = scmutil.revsingle(repo, opts.get('rev'))
571 oldmatch = None # for the closure
576 oldmatch = None # for the closure
572 def overridematch(ctx, pats=[], opts={}, globbed=False,
577 def overridematch(ctx, pats=[], opts={}, globbed=False,
573 default='relpath'):
578 default='relpath'):
574 match = oldmatch(ctx, pats, opts, globbed, default)
579 match = oldmatch(ctx, pats, opts, globbed, default)
575 m = copy.copy(match)
580 m = copy.copy(match)
576 def tostandin(f):
581 def tostandin(f):
577 if lfutil.standin(f) in ctx:
582 if lfutil.standin(f) in ctx:
578 return lfutil.standin(f)
583 return lfutil.standin(f)
579 elif lfutil.standin(f) in repo[None]:
584 elif lfutil.standin(f) in repo[None]:
580 return None
585 return None
581 return f
586 return f
582 m._files = [tostandin(f) for f in m._files]
587 m._files = [tostandin(f) for f in m._files]
583 m._files = [f for f in m._files if f is not None]
588 m._files = [f for f in m._files if f is not None]
584 m._fmap = set(m._files)
589 m._fmap = set(m._files)
585 origmatchfn = m.matchfn
590 origmatchfn = m.matchfn
586 def matchfn(f):
591 def matchfn(f):
587 if lfutil.isstandin(f):
592 if lfutil.isstandin(f):
588 # We need to keep track of what largefiles are being
593 # We need to keep track of what largefiles are being
589 # matched so we know which ones to update later --
594 # matched so we know which ones to update later --
590 # otherwise we accidentally revert changes to other
595 # otherwise we accidentally revert changes to other
591 # largefiles. This is repo-specific, so duckpunch the
596 # largefiles. This is repo-specific, so duckpunch the
592 # repo object to keep the list of largefiles for us
597 # repo object to keep the list of largefiles for us
593 # later.
598 # later.
594 if origmatchfn(lfutil.splitstandin(f)) and \
599 if origmatchfn(lfutil.splitstandin(f)) and \
595 (f in repo[None] or f in ctx):
600 (f in repo[None] or f in ctx):
596 lfileslist = getattr(repo, '_lfilestoupdate', [])
601 lfileslist = getattr(repo, '_lfilestoupdate', [])
597 lfileslist.append(lfutil.splitstandin(f))
602 lfileslist.append(lfutil.splitstandin(f))
598 repo._lfilestoupdate = lfileslist
603 repo._lfilestoupdate = lfileslist
599 return True
604 return True
600 else:
605 else:
601 return False
606 return False
602 return origmatchfn(f)
607 return origmatchfn(f)
603 m.matchfn = matchfn
608 m.matchfn = matchfn
604 return m
609 return m
605 oldmatch = installmatchfn(overridematch)
610 oldmatch = installmatchfn(overridematch)
606 scmutil.match
611 scmutil.match
607 matches = overridematch(repo[None], pats, opts)
612 matches = overridematch(repo[None], pats, opts)
608 orig(ui, repo, *pats, **opts)
613 orig(ui, repo, *pats, **opts)
609 finally:
614 finally:
610 restorematchfn()
615 restorematchfn()
611 lfileslist = getattr(repo, '_lfilestoupdate', [])
616 lfileslist = getattr(repo, '_lfilestoupdate', [])
612 lfcommands.updatelfiles(ui, repo, filelist=lfileslist,
617 lfcommands.updatelfiles(ui, repo, filelist=lfileslist,
613 printmessage=False)
618 printmessage=False)
614
619
615 # empty out the largefiles list so we start fresh next time
620 # empty out the largefiles list so we start fresh next time
616 repo._lfilestoupdate = []
621 repo._lfilestoupdate = []
617 for lfile in modified:
622 for lfile in modified:
618 if lfile in lfileslist:
623 if lfile in lfileslist:
619 if os.path.exists(repo.wjoin(lfutil.standin(lfile))) and lfile\
624 if os.path.exists(repo.wjoin(lfutil.standin(lfile))) and lfile\
620 in repo['.']:
625 in repo['.']:
621 lfutil.writestandin(repo, lfutil.standin(lfile),
626 lfutil.writestandin(repo, lfutil.standin(lfile),
622 repo['.'][lfile].data().strip(),
627 repo['.'][lfile].data().strip(),
623 'x' in repo['.'][lfile].flags())
628 'x' in repo['.'][lfile].flags())
624 lfdirstate = lfutil.openlfdirstate(ui, repo)
629 lfdirstate = lfutil.openlfdirstate(ui, repo)
625 for lfile in added:
630 for lfile in added:
626 standin = lfutil.standin(lfile)
631 standin = lfutil.standin(lfile)
627 if standin not in ctx and (standin in matches or opts.get('all')):
632 if standin not in ctx and (standin in matches or opts.get('all')):
628 if lfile in lfdirstate:
633 if lfile in lfdirstate:
629 lfdirstate.drop(lfile)
634 lfdirstate.drop(lfile)
630 util.unlinkpath(repo.wjoin(standin))
635 util.unlinkpath(repo.wjoin(standin))
631 lfdirstate.write()
636 lfdirstate.write()
632 finally:
637 finally:
633 wlock.release()
638 wlock.release()
634
639
635 def hgupdate(orig, repo, node):
640 def hgupdate(orig, repo, node):
636 # Only call updatelfiles the standins that have changed to save time
641 # Only call updatelfiles the standins that have changed to save time
637 oldstandins = lfutil.getstandinsstate(repo)
642 oldstandins = lfutil.getstandinsstate(repo)
638 result = orig(repo, node)
643 result = orig(repo, node)
639 newstandins = lfutil.getstandinsstate(repo)
644 newstandins = lfutil.getstandinsstate(repo)
640 filelist = lfutil.getlfilestoupdate(oldstandins, newstandins)
645 filelist = lfutil.getlfilestoupdate(oldstandins, newstandins)
641 lfcommands.updatelfiles(repo.ui, repo, filelist=filelist, printmessage=True)
646 lfcommands.updatelfiles(repo.ui, repo, filelist=filelist, printmessage=True)
642 return result
647 return result
643
648
644 def hgclean(orig, repo, node, show_stats=True):
649 def hgclean(orig, repo, node, show_stats=True):
645 result = orig(repo, node, show_stats)
650 result = orig(repo, node, show_stats)
646 lfcommands.updatelfiles(repo.ui, repo)
651 lfcommands.updatelfiles(repo.ui, repo)
647 return result
652 return result
648
653
649 def hgmerge(orig, repo, node, force=None, remind=True):
654 def hgmerge(orig, repo, node, force=None, remind=True):
650 # Mark the repo as being in the middle of a merge, so that
655 # Mark the repo as being in the middle of a merge, so that
651 # updatelfiles() will know that it needs to trust the standins in
656 # updatelfiles() will know that it needs to trust the standins in
652 # the working copy, not in the standins in the current node
657 # the working copy, not in the standins in the current node
653 repo._ismerging = True
658 repo._ismerging = True
654 try:
659 try:
655 result = orig(repo, node, force, remind)
660 result = orig(repo, node, force, remind)
656 lfcommands.updatelfiles(repo.ui, repo)
661 lfcommands.updatelfiles(repo.ui, repo)
657 finally:
662 finally:
658 repo._ismerging = False
663 repo._ismerging = False
659 return result
664 return result
660
665
661 # When we rebase a repository with remotely changed largefiles, we need to
666 # When we rebase a repository with remotely changed largefiles, we need to
662 # take some extra care so that the largefiles are correctly updated in the
667 # take some extra care so that the largefiles are correctly updated in the
663 # working copy
668 # working copy
664 def overridepull(orig, ui, repo, source=None, **opts):
669 def overridepull(orig, ui, repo, source=None, **opts):
665 revsprepull = len(repo)
670 revsprepull = len(repo)
666 if opts.get('rebase', False):
671 if opts.get('rebase', False):
667 repo._isrebasing = True
672 repo._isrebasing = True
668 try:
673 try:
669 if opts.get('update'):
674 if opts.get('update'):
670 del opts['update']
675 del opts['update']
671 ui.debug('--update and --rebase are not compatible, ignoring '
676 ui.debug('--update and --rebase are not compatible, ignoring '
672 'the update flag\n')
677 'the update flag\n')
673 del opts['rebase']
678 del opts['rebase']
674 cmdutil.bailifchanged(repo)
679 cmdutil.bailifchanged(repo)
675 origpostincoming = commands.postincoming
680 origpostincoming = commands.postincoming
676 def _dummy(*args, **kwargs):
681 def _dummy(*args, **kwargs):
677 pass
682 pass
678 commands.postincoming = _dummy
683 commands.postincoming = _dummy
679 repo.lfpullsource = source
684 repo.lfpullsource = source
680 if not source:
685 if not source:
681 source = 'default'
686 source = 'default'
682 try:
687 try:
683 result = commands.pull(ui, repo, source, **opts)
688 result = commands.pull(ui, repo, source, **opts)
684 finally:
689 finally:
685 commands.postincoming = origpostincoming
690 commands.postincoming = origpostincoming
686 revspostpull = len(repo)
691 revspostpull = len(repo)
687 if revspostpull > revsprepull:
692 if revspostpull > revsprepull:
688 result = result or rebase.rebase(ui, repo)
693 result = result or rebase.rebase(ui, repo)
689 finally:
694 finally:
690 repo._isrebasing = False
695 repo._isrebasing = False
691 else:
696 else:
692 repo.lfpullsource = source
697 repo.lfpullsource = source
693 if not source:
698 if not source:
694 source = 'default'
699 source = 'default'
695 oldheads = lfutil.getcurrentheads(repo)
700 oldheads = lfutil.getcurrentheads(repo)
696 result = orig(ui, repo, source, **opts)
701 result = orig(ui, repo, source, **opts)
697 # If we do not have the new largefiles for any new heads we pulled, we
702 # If we do not have the new largefiles for any new heads we pulled, we
698 # will run into a problem later if we try to merge or rebase with one of
703 # will run into a problem later if we try to merge or rebase with one of
699 # these heads, so cache the largefiles now direclty into the system
704 # these heads, so cache the largefiles now direclty into the system
700 # cache.
705 # cache.
701 ui.status(_("caching new largefiles\n"))
706 ui.status(_("caching new largefiles\n"))
702 numcached = 0
707 numcached = 0
703 heads = lfutil.getcurrentheads(repo)
708 heads = lfutil.getcurrentheads(repo)
704 newheads = set(heads).difference(set(oldheads))
709 newheads = set(heads).difference(set(oldheads))
705 for head in newheads:
710 for head in newheads:
706 (cached, missing) = lfcommands.cachelfiles(ui, repo, head)
711 (cached, missing) = lfcommands.cachelfiles(ui, repo, head)
707 numcached += len(cached)
712 numcached += len(cached)
708 ui.status(_("%d largefiles cached\n") % numcached)
713 ui.status(_("%d largefiles cached\n") % numcached)
709 if opts.get('all_largefiles'):
714 if opts.get('all_largefiles'):
710 revspostpull = len(repo)
715 revspostpull = len(repo)
711 revs = []
716 revs = []
712 for rev in xrange(revsprepull + 1, revspostpull):
717 for rev in xrange(revsprepull + 1, revspostpull):
713 revs.append(repo[rev].rev())
718 revs.append(repo[rev].rev())
714 lfcommands.downloadlfiles(ui, repo, revs)
719 lfcommands.downloadlfiles(ui, repo, revs)
715 return result
720 return result
716
721
717 def overrideclone(orig, ui, source, dest=None, **opts):
722 def overrideclone(orig, ui, source, dest=None, **opts):
718 if dest is None:
723 if dest is None:
719 dest = hg.defaultdest(source)
724 dest = hg.defaultdest(source)
720 if opts.get('all_largefiles') and not hg.islocal(dest):
725 if opts.get('all_largefiles') and not hg.islocal(dest):
721 raise util.Abort(_(
726 raise util.Abort(_(
722 '--all-largefiles is incompatible with non-local destination %s' %
727 '--all-largefiles is incompatible with non-local destination %s' %
723 dest))
728 dest))
724 result = hg.clone(ui, opts, source, dest,
729 result = hg.clone(ui, opts, source, dest,
725 pull=opts.get('pull'),
730 pull=opts.get('pull'),
726 stream=opts.get('uncompressed'),
731 stream=opts.get('uncompressed'),
727 rev=opts.get('rev'),
732 rev=opts.get('rev'),
728 update=True, # required for successful walkchangerevs
733 update=True, # required for successful walkchangerevs
729 branch=opts.get('branch'))
734 branch=opts.get('branch'))
730 if result is None:
735 if result is None:
731 return True
736 return True
732 if opts.get('all_largefiles'):
737 if opts.get('all_largefiles'):
733 sourcerepo, destrepo = result
738 sourcerepo, destrepo = result
734 success, missing = lfcommands.downloadlfiles(ui, destrepo.local(), None)
739 success, missing = lfcommands.downloadlfiles(ui, destrepo.local(), None)
735 return missing != 0
740 return missing != 0
736 return result is None
741 return result is None
737
742
738 def overriderebase(orig, ui, repo, **opts):
743 def overriderebase(orig, ui, repo, **opts):
739 repo._isrebasing = True
744 repo._isrebasing = True
740 try:
745 try:
741 orig(ui, repo, **opts)
746 orig(ui, repo, **opts)
742 finally:
747 finally:
743 repo._isrebasing = False
748 repo._isrebasing = False
744
749
745 def overridearchive(orig, repo, dest, node, kind, decode=True, matchfn=None,
750 def overridearchive(orig, repo, dest, node, kind, decode=True, matchfn=None,
746 prefix=None, mtime=None, subrepos=None):
751 prefix=None, mtime=None, subrepos=None):
747 # No need to lock because we are only reading history and
752 # No need to lock because we are only reading history and
748 # largefile caches, neither of which are modified.
753 # largefile caches, neither of which are modified.
749 lfcommands.cachelfiles(repo.ui, repo, node)
754 lfcommands.cachelfiles(repo.ui, repo, node)
750
755
751 if kind not in archival.archivers:
756 if kind not in archival.archivers:
752 raise util.Abort(_("unknown archive type '%s'") % kind)
757 raise util.Abort(_("unknown archive type '%s'") % kind)
753
758
754 ctx = repo[node]
759 ctx = repo[node]
755
760
756 if kind == 'files':
761 if kind == 'files':
757 if prefix:
762 if prefix:
758 raise util.Abort(
763 raise util.Abort(
759 _('cannot give prefix when archiving to files'))
764 _('cannot give prefix when archiving to files'))
760 else:
765 else:
761 prefix = archival.tidyprefix(dest, kind, prefix)
766 prefix = archival.tidyprefix(dest, kind, prefix)
762
767
763 def write(name, mode, islink, getdata):
768 def write(name, mode, islink, getdata):
764 if matchfn and not matchfn(name):
769 if matchfn and not matchfn(name):
765 return
770 return
766 data = getdata()
771 data = getdata()
767 if decode:
772 if decode:
768 data = repo.wwritedata(name, data)
773 data = repo.wwritedata(name, data)
769 archiver.addfile(prefix + name, mode, islink, data)
774 archiver.addfile(prefix + name, mode, islink, data)
770
775
771 archiver = archival.archivers[kind](dest, mtime or ctx.date()[0])
776 archiver = archival.archivers[kind](dest, mtime or ctx.date()[0])
772
777
773 if repo.ui.configbool("ui", "archivemeta", True):
778 if repo.ui.configbool("ui", "archivemeta", True):
774 def metadata():
779 def metadata():
775 base = 'repo: %s\nnode: %s\nbranch: %s\n' % (
780 base = 'repo: %s\nnode: %s\nbranch: %s\n' % (
776 hex(repo.changelog.node(0)), hex(node), ctx.branch())
781 hex(repo.changelog.node(0)), hex(node), ctx.branch())
777
782
778 tags = ''.join('tag: %s\n' % t for t in ctx.tags()
783 tags = ''.join('tag: %s\n' % t for t in ctx.tags()
779 if repo.tagtype(t) == 'global')
784 if repo.tagtype(t) == 'global')
780 if not tags:
785 if not tags:
781 repo.ui.pushbuffer()
786 repo.ui.pushbuffer()
782 opts = {'template': '{latesttag}\n{latesttagdistance}',
787 opts = {'template': '{latesttag}\n{latesttagdistance}',
783 'style': '', 'patch': None, 'git': None}
788 'style': '', 'patch': None, 'git': None}
784 cmdutil.show_changeset(repo.ui, repo, opts).show(ctx)
789 cmdutil.show_changeset(repo.ui, repo, opts).show(ctx)
785 ltags, dist = repo.ui.popbuffer().split('\n')
790 ltags, dist = repo.ui.popbuffer().split('\n')
786 tags = ''.join('latesttag: %s\n' % t for t in ltags.split(':'))
791 tags = ''.join('latesttag: %s\n' % t for t in ltags.split(':'))
787 tags += 'latesttagdistance: %s\n' % dist
792 tags += 'latesttagdistance: %s\n' % dist
788
793
789 return base + tags
794 return base + tags
790
795
791 write('.hg_archival.txt', 0644, False, metadata)
796 write('.hg_archival.txt', 0644, False, metadata)
792
797
793 for f in ctx:
798 for f in ctx:
794 ff = ctx.flags(f)
799 ff = ctx.flags(f)
795 getdata = ctx[f].data
800 getdata = ctx[f].data
796 if lfutil.isstandin(f):
801 if lfutil.isstandin(f):
797 path = lfutil.findfile(repo, getdata().strip())
802 path = lfutil.findfile(repo, getdata().strip())
798 if path is None:
803 if path is None:
799 raise util.Abort(
804 raise util.Abort(
800 _('largefile %s not found in repo store or system cache')
805 _('largefile %s not found in repo store or system cache')
801 % lfutil.splitstandin(f))
806 % lfutil.splitstandin(f))
802 f = lfutil.splitstandin(f)
807 f = lfutil.splitstandin(f)
803
808
804 def getdatafn():
809 def getdatafn():
805 fd = None
810 fd = None
806 try:
811 try:
807 fd = open(path, 'rb')
812 fd = open(path, 'rb')
808 return fd.read()
813 return fd.read()
809 finally:
814 finally:
810 if fd:
815 if fd:
811 fd.close()
816 fd.close()
812
817
813 getdata = getdatafn
818 getdata = getdatafn
814 write(f, 'x' in ff and 0755 or 0644, 'l' in ff, getdata)
819 write(f, 'x' in ff and 0755 or 0644, 'l' in ff, getdata)
815
820
816 if subrepos:
821 if subrepos:
817 for subpath in ctx.substate:
822 for subpath in ctx.substate:
818 sub = ctx.sub(subpath)
823 sub = ctx.sub(subpath)
819 submatch = match_.narrowmatcher(subpath, matchfn)
824 submatch = match_.narrowmatcher(subpath, matchfn)
820 sub.archive(repo.ui, archiver, prefix, submatch)
825 sub.archive(repo.ui, archiver, prefix, submatch)
821
826
822 archiver.done()
827 archiver.done()
823
828
824 def hgsubrepoarchive(orig, repo, ui, archiver, prefix, match=None):
829 def hgsubrepoarchive(orig, repo, ui, archiver, prefix, match=None):
825 rev = repo._state[1]
830 rev = repo._state[1]
826 ctx = repo._repo[rev]
831 ctx = repo._repo[rev]
827
832
828 lfcommands.cachelfiles(ui, repo._repo, ctx.node())
833 lfcommands.cachelfiles(ui, repo._repo, ctx.node())
829
834
830 def write(name, mode, islink, getdata):
835 def write(name, mode, islink, getdata):
831 # At this point, the standin has been replaced with the largefile name,
836 # At this point, the standin has been replaced with the largefile name,
832 # so the normal matcher works here without the lfutil variants.
837 # so the normal matcher works here without the lfutil variants.
833 if match and not match(f):
838 if match and not match(f):
834 return
839 return
835 data = getdata()
840 data = getdata()
836
841
837 archiver.addfile(prefix + repo._path + '/' + name, mode, islink, data)
842 archiver.addfile(prefix + repo._path + '/' + name, mode, islink, data)
838
843
839 for f in ctx:
844 for f in ctx:
840 ff = ctx.flags(f)
845 ff = ctx.flags(f)
841 getdata = ctx[f].data
846 getdata = ctx[f].data
842 if lfutil.isstandin(f):
847 if lfutil.isstandin(f):
843 path = lfutil.findfile(repo._repo, getdata().strip())
848 path = lfutil.findfile(repo._repo, getdata().strip())
844 if path is None:
849 if path is None:
845 raise util.Abort(
850 raise util.Abort(
846 _('largefile %s not found in repo store or system cache')
851 _('largefile %s not found in repo store or system cache')
847 % lfutil.splitstandin(f))
852 % lfutil.splitstandin(f))
848 f = lfutil.splitstandin(f)
853 f = lfutil.splitstandin(f)
849
854
850 def getdatafn():
855 def getdatafn():
851 fd = None
856 fd = None
852 try:
857 try:
853 fd = open(os.path.join(prefix, path), 'rb')
858 fd = open(os.path.join(prefix, path), 'rb')
854 return fd.read()
859 return fd.read()
855 finally:
860 finally:
856 if fd:
861 if fd:
857 fd.close()
862 fd.close()
858
863
859 getdata = getdatafn
864 getdata = getdatafn
860
865
861 write(f, 'x' in ff and 0755 or 0644, 'l' in ff, getdata)
866 write(f, 'x' in ff and 0755 or 0644, 'l' in ff, getdata)
862
867
863 for subpath in ctx.substate:
868 for subpath in ctx.substate:
864 sub = ctx.sub(subpath)
869 sub = ctx.sub(subpath)
865 submatch = match_.narrowmatcher(subpath, match)
870 submatch = match_.narrowmatcher(subpath, match)
866 sub.archive(ui, archiver, os.path.join(prefix, repo._path) + '/',
871 sub.archive(ui, archiver, os.path.join(prefix, repo._path) + '/',
867 submatch)
872 submatch)
868
873
869 # If a largefile is modified, the change is not reflected in its
874 # If a largefile is modified, the change is not reflected in its
870 # standin until a commit. cmdutil.bailifchanged() raises an exception
875 # standin until a commit. cmdutil.bailifchanged() raises an exception
871 # if the repo has uncommitted changes. Wrap it to also check if
876 # if the repo has uncommitted changes. Wrap it to also check if
872 # largefiles were changed. This is used by bisect and backout.
877 # largefiles were changed. This is used by bisect and backout.
873 def overridebailifchanged(orig, repo):
878 def overridebailifchanged(orig, repo):
874 orig(repo)
879 orig(repo)
875 repo.lfstatus = True
880 repo.lfstatus = True
876 modified, added, removed, deleted = repo.status()[:4]
881 modified, added, removed, deleted = repo.status()[:4]
877 repo.lfstatus = False
882 repo.lfstatus = False
878 if modified or added or removed or deleted:
883 if modified or added or removed or deleted:
879 raise util.Abort(_('outstanding uncommitted changes'))
884 raise util.Abort(_('outstanding uncommitted changes'))
880
885
881 # Fetch doesn't use cmdutil.bailifchanged so override it to add the check
886 # Fetch doesn't use cmdutil.bailifchanged so override it to add the check
882 def overridefetch(orig, ui, repo, *pats, **opts):
887 def overridefetch(orig, ui, repo, *pats, **opts):
883 repo.lfstatus = True
888 repo.lfstatus = True
884 modified, added, removed, deleted = repo.status()[:4]
889 modified, added, removed, deleted = repo.status()[:4]
885 repo.lfstatus = False
890 repo.lfstatus = False
886 if modified or added or removed or deleted:
891 if modified or added or removed or deleted:
887 raise util.Abort(_('outstanding uncommitted changes'))
892 raise util.Abort(_('outstanding uncommitted changes'))
888 return orig(ui, repo, *pats, **opts)
893 return orig(ui, repo, *pats, **opts)
889
894
890 def overrideforget(orig, ui, repo, *pats, **opts):
895 def overrideforget(orig, ui, repo, *pats, **opts):
891 installnormalfilesmatchfn(repo[None].manifest())
896 installnormalfilesmatchfn(repo[None].manifest())
892 orig(ui, repo, *pats, **opts)
897 orig(ui, repo, *pats, **opts)
893 restorematchfn()
898 restorematchfn()
894 m = scmutil.match(repo[None], pats, opts)
899 m = scmutil.match(repo[None], pats, opts)
895
900
896 try:
901 try:
897 repo.lfstatus = True
902 repo.lfstatus = True
898 s = repo.status(match=m, clean=True)
903 s = repo.status(match=m, clean=True)
899 finally:
904 finally:
900 repo.lfstatus = False
905 repo.lfstatus = False
901 forget = sorted(s[0] + s[1] + s[3] + s[6])
906 forget = sorted(s[0] + s[1] + s[3] + s[6])
902 forget = [f for f in forget if lfutil.standin(f) in repo[None].manifest()]
907 forget = [f for f in forget if lfutil.standin(f) in repo[None].manifest()]
903
908
904 for f in forget:
909 for f in forget:
905 if lfutil.standin(f) not in repo.dirstate and not \
910 if lfutil.standin(f) not in repo.dirstate and not \
906 os.path.isdir(m.rel(lfutil.standin(f))):
911 os.path.isdir(m.rel(lfutil.standin(f))):
907 ui.warn(_('not removing %s: file is already untracked\n')
912 ui.warn(_('not removing %s: file is already untracked\n')
908 % m.rel(f))
913 % m.rel(f))
909
914
910 for f in forget:
915 for f in forget:
911 if ui.verbose or not m.exact(f):
916 if ui.verbose or not m.exact(f):
912 ui.status(_('removing %s\n') % m.rel(f))
917 ui.status(_('removing %s\n') % m.rel(f))
913
918
914 # Need to lock because standin files are deleted then removed from the
919 # Need to lock because standin files are deleted then removed from the
915 # repository and we could race inbetween.
920 # repository and we could race inbetween.
916 wlock = repo.wlock()
921 wlock = repo.wlock()
917 try:
922 try:
918 lfdirstate = lfutil.openlfdirstate(ui, repo)
923 lfdirstate = lfutil.openlfdirstate(ui, repo)
919 for f in forget:
924 for f in forget:
920 if lfdirstate[f] == 'a':
925 if lfdirstate[f] == 'a':
921 lfdirstate.drop(f)
926 lfdirstate.drop(f)
922 else:
927 else:
923 lfdirstate.remove(f)
928 lfdirstate.remove(f)
924 lfdirstate.write()
929 lfdirstate.write()
925 lfutil.reporemove(repo, [lfutil.standin(f) for f in forget],
930 lfutil.reporemove(repo, [lfutil.standin(f) for f in forget],
926 unlink=True)
931 unlink=True)
927 finally:
932 finally:
928 wlock.release()
933 wlock.release()
929
934
930 def getoutgoinglfiles(ui, repo, dest=None, **opts):
935 def getoutgoinglfiles(ui, repo, dest=None, **opts):
931 dest = ui.expandpath(dest or 'default-push', dest or 'default')
936 dest = ui.expandpath(dest or 'default-push', dest or 'default')
932 dest, branches = hg.parseurl(dest, opts.get('branch'))
937 dest, branches = hg.parseurl(dest, opts.get('branch'))
933 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
938 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
934 if revs:
939 if revs:
935 revs = [repo.lookup(rev) for rev in scmutil.revrange(repo, revs)]
940 revs = [repo.lookup(rev) for rev in scmutil.revrange(repo, revs)]
936
941
937 try:
942 try:
938 remote = hg.peer(repo, opts, dest)
943 remote = hg.peer(repo, opts, dest)
939 except error.RepoError:
944 except error.RepoError:
940 return None
945 return None
941 o = lfutil.findoutgoing(repo, remote, False)
946 o = lfutil.findoutgoing(repo, remote, False)
942 if not o:
947 if not o:
943 return None
948 return None
944 o = repo.changelog.nodesbetween(o, revs)[0]
949 o = repo.changelog.nodesbetween(o, revs)[0]
945 if opts.get('newest_first'):
950 if opts.get('newest_first'):
946 o.reverse()
951 o.reverse()
947
952
948 toupload = set()
953 toupload = set()
949 for n in o:
954 for n in o:
950 parents = [p for p in repo.changelog.parents(n) if p != node.nullid]
955 parents = [p for p in repo.changelog.parents(n) if p != node.nullid]
951 ctx = repo[n]
956 ctx = repo[n]
952 files = set(ctx.files())
957 files = set(ctx.files())
953 if len(parents) == 2:
958 if len(parents) == 2:
954 mc = ctx.manifest()
959 mc = ctx.manifest()
955 mp1 = ctx.parents()[0].manifest()
960 mp1 = ctx.parents()[0].manifest()
956 mp2 = ctx.parents()[1].manifest()
961 mp2 = ctx.parents()[1].manifest()
957 for f in mp1:
962 for f in mp1:
958 if f not in mc:
963 if f not in mc:
959 files.add(f)
964 files.add(f)
960 for f in mp2:
965 for f in mp2:
961 if f not in mc:
966 if f not in mc:
962 files.add(f)
967 files.add(f)
963 for f in mc:
968 for f in mc:
964 if mc[f] != mp1.get(f, None) or mc[f] != mp2.get(f, None):
969 if mc[f] != mp1.get(f, None) or mc[f] != mp2.get(f, None):
965 files.add(f)
970 files.add(f)
966 toupload = toupload.union(
971 toupload = toupload.union(
967 set([f for f in files if lfutil.isstandin(f) and f in ctx]))
972 set([f for f in files if lfutil.isstandin(f) and f in ctx]))
968 return toupload
973 return toupload
969
974
970 def overrideoutgoing(orig, ui, repo, dest=None, **opts):
975 def overrideoutgoing(orig, ui, repo, dest=None, **opts):
971 result = orig(ui, repo, dest, **opts)
976 result = orig(ui, repo, dest, **opts)
972
977
973 if opts.pop('large', None):
978 if opts.pop('large', None):
974 toupload = getoutgoinglfiles(ui, repo, dest, **opts)
979 toupload = getoutgoinglfiles(ui, repo, dest, **opts)
975 if toupload is None:
980 if toupload is None:
976 ui.status(_('largefiles: No remote repo\n'))
981 ui.status(_('largefiles: No remote repo\n'))
977 else:
982 else:
978 ui.status(_('largefiles to upload:\n'))
983 ui.status(_('largefiles to upload:\n'))
979 for file in toupload:
984 for file in toupload:
980 ui.status(lfutil.splitstandin(file) + '\n')
985 ui.status(lfutil.splitstandin(file) + '\n')
981 ui.status('\n')
986 ui.status('\n')
982
987
983 return result
988 return result
984
989
985 def overridesummary(orig, ui, repo, *pats, **opts):
990 def overridesummary(orig, ui, repo, *pats, **opts):
986 try:
991 try:
987 repo.lfstatus = True
992 repo.lfstatus = True
988 orig(ui, repo, *pats, **opts)
993 orig(ui, repo, *pats, **opts)
989 finally:
994 finally:
990 repo.lfstatus = False
995 repo.lfstatus = False
991
996
992 if opts.pop('large', None):
997 if opts.pop('large', None):
993 toupload = getoutgoinglfiles(ui, repo, None, **opts)
998 toupload = getoutgoinglfiles(ui, repo, None, **opts)
994 if toupload is None:
999 if toupload is None:
995 ui.status(_('largefiles: No remote repo\n'))
1000 ui.status(_('largefiles: No remote repo\n'))
996 else:
1001 else:
997 ui.status(_('largefiles: %d to upload\n') % len(toupload))
1002 ui.status(_('largefiles: %d to upload\n') % len(toupload))
998
1003
999 def overrideaddremove(orig, ui, repo, *pats, **opts):
1004 def overrideaddremove(orig, ui, repo, *pats, **opts):
1000 if not lfutil.islfilesrepo(repo):
1005 if not lfutil.islfilesrepo(repo):
1001 return orig(ui, repo, *pats, **opts)
1006 return orig(ui, repo, *pats, **opts)
1002 # Get the list of missing largefiles so we can remove them
1007 # Get the list of missing largefiles so we can remove them
1003 lfdirstate = lfutil.openlfdirstate(ui, repo)
1008 lfdirstate = lfutil.openlfdirstate(ui, repo)
1004 s = lfdirstate.status(match_.always(repo.root, repo.getcwd()), [], False,
1009 s = lfdirstate.status(match_.always(repo.root, repo.getcwd()), [], False,
1005 False, False)
1010 False, False)
1006 (unsure, modified, added, removed, missing, unknown, ignored, clean) = s
1011 (unsure, modified, added, removed, missing, unknown, ignored, clean) = s
1007
1012
1008 # Call into the normal remove code, but the removing of the standin, we want
1013 # Call into the normal remove code, but the removing of the standin, we want
1009 # to have handled by original addremove. Monkey patching here makes sure
1014 # to have handled by original addremove. Monkey patching here makes sure
1010 # we don't remove the standin in the largefiles code, preventing a very
1015 # we don't remove the standin in the largefiles code, preventing a very
1011 # confused state later.
1016 # confused state later.
1012 if missing:
1017 if missing:
1013 m = [repo.wjoin(f) for f in missing]
1018 m = [repo.wjoin(f) for f in missing]
1014 repo._isaddremove = True
1019 repo._isaddremove = True
1015 removelargefiles(ui, repo, *m, **opts)
1020 removelargefiles(ui, repo, *m, **opts)
1016 repo._isaddremove = False
1021 repo._isaddremove = False
1017 # Call into the normal add code, and any files that *should* be added as
1022 # Call into the normal add code, and any files that *should* be added as
1018 # largefiles will be
1023 # largefiles will be
1019 addlargefiles(ui, repo, *pats, **opts)
1024 addlargefiles(ui, repo, *pats, **opts)
1020 # Now that we've handled largefiles, hand off to the original addremove
1025 # Now that we've handled largefiles, hand off to the original addremove
1021 # function to take care of the rest. Make sure it doesn't do anything with
1026 # function to take care of the rest. Make sure it doesn't do anything with
1022 # largefiles by installing a matcher that will ignore them.
1027 # largefiles by installing a matcher that will ignore them.
1023 installnormalfilesmatchfn(repo[None].manifest())
1028 installnormalfilesmatchfn(repo[None].manifest())
1024 result = orig(ui, repo, *pats, **opts)
1029 result = orig(ui, repo, *pats, **opts)
1025 restorematchfn()
1030 restorematchfn()
1026 return result
1031 return result
1027
1032
1028 # Calling purge with --all will cause the largefiles to be deleted.
1033 # Calling purge with --all will cause the largefiles to be deleted.
1029 # Override repo.status to prevent this from happening.
1034 # Override repo.status to prevent this from happening.
1030 def overridepurge(orig, ui, repo, *dirs, **opts):
1035 def overridepurge(orig, ui, repo, *dirs, **opts):
1031 oldstatus = repo.status
1036 oldstatus = repo.status
1032 def overridestatus(node1='.', node2=None, match=None, ignored=False,
1037 def overridestatus(node1='.', node2=None, match=None, ignored=False,
1033 clean=False, unknown=False, listsubrepos=False):
1038 clean=False, unknown=False, listsubrepos=False):
1034 r = oldstatus(node1, node2, match, ignored, clean, unknown,
1039 r = oldstatus(node1, node2, match, ignored, clean, unknown,
1035 listsubrepos)
1040 listsubrepos)
1036 lfdirstate = lfutil.openlfdirstate(ui, repo)
1041 lfdirstate = lfutil.openlfdirstate(ui, repo)
1037 modified, added, removed, deleted, unknown, ignored, clean = r
1042 modified, added, removed, deleted, unknown, ignored, clean = r
1038 unknown = [f for f in unknown if lfdirstate[f] == '?']
1043 unknown = [f for f in unknown if lfdirstate[f] == '?']
1039 ignored = [f for f in ignored if lfdirstate[f] == '?']
1044 ignored = [f for f in ignored if lfdirstate[f] == '?']
1040 return modified, added, removed, deleted, unknown, ignored, clean
1045 return modified, added, removed, deleted, unknown, ignored, clean
1041 repo.status = overridestatus
1046 repo.status = overridestatus
1042 orig(ui, repo, *dirs, **opts)
1047 orig(ui, repo, *dirs, **opts)
1043 repo.status = oldstatus
1048 repo.status = oldstatus
1044
1049
1045 def overriderollback(orig, ui, repo, **opts):
1050 def overriderollback(orig, ui, repo, **opts):
1046 result = orig(ui, repo, **opts)
1051 result = orig(ui, repo, **opts)
1047 merge.update(repo, node=None, branchmerge=False, force=True,
1052 merge.update(repo, node=None, branchmerge=False, force=True,
1048 partial=lfutil.isstandin)
1053 partial=lfutil.isstandin)
1049 wlock = repo.wlock()
1054 wlock = repo.wlock()
1050 try:
1055 try:
1051 lfdirstate = lfutil.openlfdirstate(ui, repo)
1056 lfdirstate = lfutil.openlfdirstate(ui, repo)
1052 lfiles = lfutil.listlfiles(repo)
1057 lfiles = lfutil.listlfiles(repo)
1053 oldlfiles = lfutil.listlfiles(repo, repo[None].parents()[0].rev())
1058 oldlfiles = lfutil.listlfiles(repo, repo[None].parents()[0].rev())
1054 for file in lfiles:
1059 for file in lfiles:
1055 if file in oldlfiles:
1060 if file in oldlfiles:
1056 lfdirstate.normallookup(file)
1061 lfdirstate.normallookup(file)
1057 else:
1062 else:
1058 lfdirstate.add(file)
1063 lfdirstate.add(file)
1059 lfdirstate.write()
1064 lfdirstate.write()
1060 finally:
1065 finally:
1061 wlock.release()
1066 wlock.release()
1062 return result
1067 return result
1063
1068
1064 def overridetransplant(orig, ui, repo, *revs, **opts):
1069 def overridetransplant(orig, ui, repo, *revs, **opts):
1065 try:
1070 try:
1066 oldstandins = lfutil.getstandinsstate(repo)
1071 oldstandins = lfutil.getstandinsstate(repo)
1067 repo._istransplanting = True
1072 repo._istransplanting = True
1068 result = orig(ui, repo, *revs, **opts)
1073 result = orig(ui, repo, *revs, **opts)
1069 newstandins = lfutil.getstandinsstate(repo)
1074 newstandins = lfutil.getstandinsstate(repo)
1070 filelist = lfutil.getlfilestoupdate(oldstandins, newstandins)
1075 filelist = lfutil.getlfilestoupdate(oldstandins, newstandins)
1071 lfcommands.updatelfiles(repo.ui, repo, filelist=filelist,
1076 lfcommands.updatelfiles(repo.ui, repo, filelist=filelist,
1072 printmessage=True)
1077 printmessage=True)
1073 finally:
1078 finally:
1074 repo._istransplanting = False
1079 repo._istransplanting = False
1075 return result
1080 return result
1076
1081
1077 def overridecat(orig, ui, repo, file1, *pats, **opts):
1082 def overridecat(orig, ui, repo, file1, *pats, **opts):
1078 ctx = scmutil.revsingle(repo, opts.get('rev'))
1083 ctx = scmutil.revsingle(repo, opts.get('rev'))
1079 if not lfutil.standin(file1) in ctx:
1084 if not lfutil.standin(file1) in ctx:
1080 result = orig(ui, repo, file1, *pats, **opts)
1085 result = orig(ui, repo, file1, *pats, **opts)
1081 return result
1086 return result
1082 return lfcommands.catlfile(repo, file1, ctx.rev(), opts.get('output'))
1087 return lfcommands.catlfile(repo, file1, ctx.rev(), opts.get('output'))
@@ -1,1476 +1,1491
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, testing that status correctly shows largefiles and that summary output
20 files, testing that status correctly shows largefiles and that summary output
21 is correct.
21 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 $ echo normal11 > normal1
38 $ echo normal11 > normal1
39 $ echo normal22 > sub/normal2
39 $ echo normal22 > sub/normal2
40 $ echo large11 > large1
40 $ echo large11 > large1
41 $ echo large22 > sub/large2
41 $ echo large22 > sub/large2
42 $ hg commit -m "edit files"
42 $ hg commit -m "edit files"
43 Invoking status precommit hook
43 Invoking status precommit hook
44 M large1
44 M large1
45 M normal1
45 M normal1
46 M sub/large2
46 M sub/large2
47 M sub/normal2
47 M sub/normal2
48 $ hg sum --large
48 $ hg sum --large
49 parent: 1:ce8896473775 tip
49 parent: 1:ce8896473775 tip
50 edit files
50 edit files
51 branch: default
51 branch: default
52 commit: (clean)
52 commit: (clean)
53 update: (current)
53 update: (current)
54 largefiles: No remote repo
54 largefiles: No remote repo
55
55
56 Commit preserved largefile contents.
56 Commit preserved largefile contents.
57
57
58 $ cat normal1
58 $ cat normal1
59 normal11
59 normal11
60 $ cat large1
60 $ cat large1
61 large11
61 large11
62 $ cat sub/normal2
62 $ cat sub/normal2
63 normal22
63 normal22
64 $ cat sub/large2
64 $ cat sub/large2
65 large22
65 large22
66
66
67 Test status, subdir and unknown files
67 Test status, subdir and unknown files
68
68
69 $ echo unknown > sub/unknown
69 $ echo unknown > sub/unknown
70 $ hg st --all
70 $ hg st --all
71 ? sub/unknown
71 ? sub/unknown
72 C large1
72 C large1
73 C normal1
73 C normal1
74 C sub/large2
74 C sub/large2
75 C sub/normal2
75 C sub/normal2
76 $ hg st --all sub
76 $ hg st --all sub
77 ? sub/unknown
77 ? sub/unknown
78 C sub/large2
78 C sub/large2
79 C sub/normal2
79 C sub/normal2
80 $ rm sub/unknown
80 $ rm sub/unknown
81
81
82 Test exit codes for remove warning cases (modified and still exiting)
83
84 $ hg remove -A large1
85 not removing large1: file still exists (use forget to undo)
86 [1]
87 $ echo 'modified' > large1
88 $ hg remove large1
89 not removing large1: file is modified (use forget to undo)
90 [1]
91 $ hg up -Cq
92
82 Remove both largefiles and normal files.
93 Remove both largefiles and normal files.
83
94
84 $ hg remove normal1 large1
95 $ hg remove normal1 large1
85 $ hg status large1
96 $ hg status large1
86 R large1
97 R large1
87 $ hg commit -m "remove files"
98 $ hg commit -m "remove files"
88 Invoking status precommit hook
99 Invoking status precommit hook
89 R large1
100 R large1
90 R normal1
101 R normal1
91 $ ls
102 $ ls
92 sub
103 sub
93 $ echo "testlargefile" > large1-test
104 $ echo "testlargefile" > large1-test
94 $ hg add --large large1-test
105 $ hg add --large large1-test
95 $ hg st
106 $ hg st
96 A large1-test
107 A large1-test
97 $ hg rm large1-test
108 $ hg rm large1-test
98 not removing large1-test: file has been marked for add (use forget to undo)
109 not removing large1-test: file has been marked for add (use forget to undo)
110 [1]
99 $ hg st
111 $ hg st
100 A large1-test
112 A large1-test
101 $ hg forget large1-test
113 $ hg forget large1-test
102 $ hg st
114 $ hg st
103 ? large1-test
115 ? large1-test
116 $ hg remove large1-test
117 not removing large1-test: file is untracked
118 [1]
104 $ rm large1-test
119 $ rm large1-test
105
120
106 Copy both largefiles and normal files (testing that status output is correct).
121 Copy both largefiles and normal files (testing that status output is correct).
107
122
108 $ hg cp sub/normal2 normal1
123 $ hg cp sub/normal2 normal1
109 $ hg cp sub/large2 large1
124 $ hg cp sub/large2 large1
110 $ hg commit -m "copy files"
125 $ hg commit -m "copy files"
111 Invoking status precommit hook
126 Invoking status precommit hook
112 A large1
127 A large1
113 A normal1
128 A normal1
114 $ cat normal1
129 $ cat normal1
115 normal22
130 normal22
116 $ cat large1
131 $ cat large1
117 large22
132 large22
118
133
119 Test moving largefiles and verify that normal files are also unaffected.
134 Test moving largefiles and verify that normal files are also unaffected.
120
135
121 $ hg mv normal1 normal3
136 $ hg mv normal1 normal3
122 $ hg mv large1 large3
137 $ hg mv large1 large3
123 $ hg mv sub/normal2 sub/normal4
138 $ hg mv sub/normal2 sub/normal4
124 $ hg mv sub/large2 sub/large4
139 $ hg mv sub/large2 sub/large4
125 $ hg commit -m "move files"
140 $ hg commit -m "move files"
126 Invoking status precommit hook
141 Invoking status precommit hook
127 A large3
142 A large3
128 A normal3
143 A normal3
129 A sub/large4
144 A sub/large4
130 A sub/normal4
145 A sub/normal4
131 R large1
146 R large1
132 R normal1
147 R normal1
133 R sub/large2
148 R sub/large2
134 R sub/normal2
149 R sub/normal2
135 $ cat normal3
150 $ cat normal3
136 normal22
151 normal22
137 $ cat large3
152 $ cat large3
138 large22
153 large22
139 $ cat sub/normal4
154 $ cat sub/normal4
140 normal22
155 normal22
141 $ cat sub/large4
156 $ cat sub/large4
142 large22
157 large22
143
158
144 Test copies and moves from a directory other than root (issue3516)
159 Test copies and moves from a directory other than root (issue3516)
145
160
146 $ cd ..
161 $ cd ..
147 $ hg init lf_cpmv
162 $ hg init lf_cpmv
148 $ cd lf_cpmv
163 $ cd lf_cpmv
149 $ mkdir dira
164 $ mkdir dira
150 $ mkdir dira/dirb
165 $ mkdir dira/dirb
151 $ touch dira/dirb/largefile
166 $ touch dira/dirb/largefile
152 $ hg add --large dira/dirb/largefile
167 $ hg add --large dira/dirb/largefile
153 $ hg commit -m "added"
168 $ hg commit -m "added"
154 Invoking status precommit hook
169 Invoking status precommit hook
155 A dira/dirb/largefile
170 A dira/dirb/largefile
156 $ cd dira
171 $ cd dira
157 $ hg cp dirb/largefile foo/largefile
172 $ hg cp dirb/largefile foo/largefile
158 $ hg ci -m "deep copy"
173 $ hg ci -m "deep copy"
159 Invoking status precommit hook
174 Invoking status precommit hook
160 A dira/foo/largefile
175 A dira/foo/largefile
161 $ find . | sort
176 $ find . | sort
162 .
177 .
163 ./dirb
178 ./dirb
164 ./dirb/largefile
179 ./dirb/largefile
165 ./foo
180 ./foo
166 ./foo/largefile
181 ./foo/largefile
167 $ hg mv foo/largefile baz/largefile
182 $ hg mv foo/largefile baz/largefile
168 $ hg ci -m "moved"
183 $ hg ci -m "moved"
169 Invoking status precommit hook
184 Invoking status precommit hook
170 A dira/baz/largefile
185 A dira/baz/largefile
171 R dira/foo/largefile
186 R dira/foo/largefile
172 $ find . | sort
187 $ find . | sort
173 .
188 .
174 ./baz
189 ./baz
175 ./baz/largefile
190 ./baz/largefile
176 ./dirb
191 ./dirb
177 ./dirb/largefile
192 ./dirb/largefile
178 ./foo
193 ./foo
179 $ cd ../../a
194 $ cd ../../a
180
195
181 #if hgweb
196 #if hgweb
182 Test display of largefiles in hgweb
197 Test display of largefiles in hgweb
183
198
184 $ hg serve -d -p $HGPORT --pid-file ../hg.pid
199 $ hg serve -d -p $HGPORT --pid-file ../hg.pid
185 $ cat ../hg.pid >> $DAEMON_PIDS
200 $ cat ../hg.pid >> $DAEMON_PIDS
186 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT 'file/tip/?style=raw'
201 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT 'file/tip/?style=raw'
187 200 Script output follows
202 200 Script output follows
188
203
189
204
190 drwxr-xr-x sub
205 drwxr-xr-x sub
191 -rw-r--r-- 41 large3
206 -rw-r--r-- 41 large3
192 -rw-r--r-- 9 normal3
207 -rw-r--r-- 9 normal3
193
208
194
209
195 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT 'file/tip/sub/?style=raw'
210 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT 'file/tip/sub/?style=raw'
196 200 Script output follows
211 200 Script output follows
197
212
198
213
199 -rw-r--r-- 41 large4
214 -rw-r--r-- 41 large4
200 -rw-r--r-- 9 normal4
215 -rw-r--r-- 9 normal4
201
216
202
217
203 $ "$TESTDIR/killdaemons.py"
218 $ "$TESTDIR/killdaemons.py"
204 #endif
219 #endif
205
220
206 Test archiving the various revisions. These hit corner cases known with
221 Test archiving the various revisions. These hit corner cases known with
207 archiving.
222 archiving.
208
223
209 $ hg archive -r 0 ../archive0
224 $ hg archive -r 0 ../archive0
210 $ hg archive -r 1 ../archive1
225 $ hg archive -r 1 ../archive1
211 $ hg archive -r 2 ../archive2
226 $ hg archive -r 2 ../archive2
212 $ hg archive -r 3 ../archive3
227 $ hg archive -r 3 ../archive3
213 $ hg archive -r 4 ../archive4
228 $ hg archive -r 4 ../archive4
214 $ cd ../archive0
229 $ cd ../archive0
215 $ cat normal1
230 $ cat normal1
216 normal1
231 normal1
217 $ cat large1
232 $ cat large1
218 large1
233 large1
219 $ cat sub/normal2
234 $ cat sub/normal2
220 normal2
235 normal2
221 $ cat sub/large2
236 $ cat sub/large2
222 large2
237 large2
223 $ cd ../archive1
238 $ cd ../archive1
224 $ cat normal1
239 $ cat normal1
225 normal11
240 normal11
226 $ cat large1
241 $ cat large1
227 large11
242 large11
228 $ cat sub/normal2
243 $ cat sub/normal2
229 normal22
244 normal22
230 $ cat sub/large2
245 $ cat sub/large2
231 large22
246 large22
232 $ cd ../archive2
247 $ cd ../archive2
233 $ ls
248 $ ls
234 sub
249 sub
235 $ cat sub/normal2
250 $ cat sub/normal2
236 normal22
251 normal22
237 $ cat sub/large2
252 $ cat sub/large2
238 large22
253 large22
239 $ cd ../archive3
254 $ cd ../archive3
240 $ cat normal1
255 $ cat normal1
241 normal22
256 normal22
242 $ cat large1
257 $ cat large1
243 large22
258 large22
244 $ cat sub/normal2
259 $ cat sub/normal2
245 normal22
260 normal22
246 $ cat sub/large2
261 $ cat sub/large2
247 large22
262 large22
248 $ cd ../archive4
263 $ cd ../archive4
249 $ cat normal3
264 $ cat normal3
250 normal22
265 normal22
251 $ cat large3
266 $ cat large3
252 large22
267 large22
253 $ cat sub/normal4
268 $ cat sub/normal4
254 normal22
269 normal22
255 $ cat sub/large4
270 $ cat sub/large4
256 large22
271 large22
257
272
258 Commit corner case: specify files to commit.
273 Commit corner case: specify files to commit.
259
274
260 $ cd ../a
275 $ cd ../a
261 $ echo normal3 > normal3
276 $ echo normal3 > normal3
262 $ echo large3 > large3
277 $ echo large3 > large3
263 $ echo normal4 > sub/normal4
278 $ echo normal4 > sub/normal4
264 $ echo large4 > sub/large4
279 $ echo large4 > sub/large4
265 $ hg commit normal3 large3 sub/normal4 sub/large4 -m "edit files again"
280 $ hg commit normal3 large3 sub/normal4 sub/large4 -m "edit files again"
266 Invoking status precommit hook
281 Invoking status precommit hook
267 M large3
282 M large3
268 M normal3
283 M normal3
269 M sub/large4
284 M sub/large4
270 M sub/normal4
285 M sub/normal4
271 $ cat normal3
286 $ cat normal3
272 normal3
287 normal3
273 $ cat large3
288 $ cat large3
274 large3
289 large3
275 $ cat sub/normal4
290 $ cat sub/normal4
276 normal4
291 normal4
277 $ cat sub/large4
292 $ cat sub/large4
278 large4
293 large4
279
294
280 One more commit corner case: commit from a subdirectory.
295 One more commit corner case: commit from a subdirectory.
281
296
282 $ cd ../a
297 $ cd ../a
283 $ echo normal33 > normal3
298 $ echo normal33 > normal3
284 $ echo large33 > large3
299 $ echo large33 > large3
285 $ echo normal44 > sub/normal4
300 $ echo normal44 > sub/normal4
286 $ echo large44 > sub/large4
301 $ echo large44 > sub/large4
287 $ cd sub
302 $ cd sub
288 $ hg commit -m "edit files yet again"
303 $ hg commit -m "edit files yet again"
289 Invoking status precommit hook
304 Invoking status precommit hook
290 M large3
305 M large3
291 M normal3
306 M normal3
292 M sub/large4
307 M sub/large4
293 M sub/normal4
308 M sub/normal4
294 $ cat ../normal3
309 $ cat ../normal3
295 normal33
310 normal33
296 $ cat ../large3
311 $ cat ../large3
297 large33
312 large33
298 $ cat normal4
313 $ cat normal4
299 normal44
314 normal44
300 $ cat large4
315 $ cat large4
301 large44
316 large44
302
317
303 Committing standins is not allowed.
318 Committing standins is not allowed.
304
319
305 $ cd ..
320 $ cd ..
306 $ echo large3 > large3
321 $ echo large3 > large3
307 $ hg commit .hglf/large3 -m "try to commit standin"
322 $ hg commit .hglf/large3 -m "try to commit standin"
308 abort: file ".hglf/large3" is a largefile standin
323 abort: file ".hglf/large3" is a largefile standin
309 (commit the largefile itself instead)
324 (commit the largefile itself instead)
310 [255]
325 [255]
311
326
312 Corner cases for adding largefiles.
327 Corner cases for adding largefiles.
313
328
314 $ echo large5 > large5
329 $ echo large5 > large5
315 $ hg add --large large5
330 $ hg add --large large5
316 $ hg add --large large5
331 $ hg add --large large5
317 large5 already a largefile
332 large5 already a largefile
318 $ mkdir sub2
333 $ mkdir sub2
319 $ echo large6 > sub2/large6
334 $ echo large6 > sub2/large6
320 $ echo large7 > sub2/large7
335 $ echo large7 > sub2/large7
321 $ hg add --large sub2
336 $ hg add --large sub2
322 adding sub2/large6 as a largefile (glob)
337 adding sub2/large6 as a largefile (glob)
323 adding sub2/large7 as a largefile (glob)
338 adding sub2/large7 as a largefile (glob)
324 $ hg st
339 $ hg st
325 M large3
340 M large3
326 A large5
341 A large5
327 A sub2/large6
342 A sub2/large6
328 A sub2/large7
343 A sub2/large7
329
344
330 Test "hg status" with combination of 'file pattern' and 'directory
345 Test "hg status" with combination of 'file pattern' and 'directory
331 pattern' for largefiles:
346 pattern' for largefiles:
332
347
333 $ hg status sub2/large6 sub2
348 $ hg status sub2/large6 sub2
334 A sub2/large6
349 A sub2/large6
335 A sub2/large7
350 A sub2/large7
336
351
337 Config settings (pattern **.dat, minsize 2 MB) are respected.
352 Config settings (pattern **.dat, minsize 2 MB) are respected.
338
353
339 $ echo testdata > test.dat
354 $ echo testdata > test.dat
340 $ dd bs=1k count=2k if=/dev/zero of=reallylarge > /dev/null 2> /dev/null
355 $ dd bs=1k count=2k if=/dev/zero of=reallylarge > /dev/null 2> /dev/null
341 $ hg add
356 $ hg add
342 adding reallylarge as a largefile
357 adding reallylarge as a largefile
343 adding test.dat as a largefile
358 adding test.dat as a largefile
344
359
345 Test that minsize and --lfsize handle float values;
360 Test that minsize and --lfsize handle float values;
346 also tests that --lfsize overrides largefiles.minsize.
361 also tests that --lfsize overrides largefiles.minsize.
347 (0.250 MB = 256 kB = 262144 B)
362 (0.250 MB = 256 kB = 262144 B)
348
363
349 $ dd if=/dev/zero of=ratherlarge bs=1024 count=256 > /dev/null 2> /dev/null
364 $ dd if=/dev/zero of=ratherlarge bs=1024 count=256 > /dev/null 2> /dev/null
350 $ dd if=/dev/zero of=medium bs=1024 count=128 > /dev/null 2> /dev/null
365 $ dd if=/dev/zero of=medium bs=1024 count=128 > /dev/null 2> /dev/null
351 $ hg --config largefiles.minsize=.25 add
366 $ hg --config largefiles.minsize=.25 add
352 adding ratherlarge as a largefile
367 adding ratherlarge as a largefile
353 adding medium
368 adding medium
354 $ hg forget medium
369 $ hg forget medium
355 $ hg --config largefiles.minsize=.25 add --lfsize=.125
370 $ hg --config largefiles.minsize=.25 add --lfsize=.125
356 adding medium as a largefile
371 adding medium as a largefile
357 $ dd if=/dev/zero of=notlarge bs=1024 count=127 > /dev/null 2> /dev/null
372 $ dd if=/dev/zero of=notlarge bs=1024 count=127 > /dev/null 2> /dev/null
358 $ hg --config largefiles.minsize=.25 add --lfsize=.125
373 $ hg --config largefiles.minsize=.25 add --lfsize=.125
359 adding notlarge
374 adding notlarge
360 $ hg forget notlarge
375 $ hg forget notlarge
361
376
362 Test forget on largefiles.
377 Test forget on largefiles.
363
378
364 $ hg forget large3 large5 test.dat reallylarge ratherlarge medium
379 $ hg forget large3 large5 test.dat reallylarge ratherlarge medium
365 $ hg commit -m "add/edit more largefiles"
380 $ hg commit -m "add/edit more largefiles"
366 Invoking status precommit hook
381 Invoking status precommit hook
367 A sub2/large6
382 A sub2/large6
368 A sub2/large7
383 A sub2/large7
369 R large3
384 R large3
370 ? large5
385 ? large5
371 ? medium
386 ? medium
372 ? notlarge
387 ? notlarge
373 ? ratherlarge
388 ? ratherlarge
374 ? reallylarge
389 ? reallylarge
375 ? test.dat
390 ? test.dat
376 $ hg st
391 $ hg st
377 ? large3
392 ? large3
378 ? large5
393 ? large5
379 ? medium
394 ? medium
380 ? notlarge
395 ? notlarge
381 ? ratherlarge
396 ? ratherlarge
382 ? reallylarge
397 ? reallylarge
383 ? test.dat
398 ? test.dat
384
399
385 Purge with largefiles: verify that largefiles are still in the working
400 Purge with largefiles: verify that largefiles are still in the working
386 dir after a purge.
401 dir after a purge.
387
402
388 $ hg purge --all
403 $ hg purge --all
389 $ cat sub/large4
404 $ cat sub/large4
390 large44
405 large44
391 $ cat sub2/large6
406 $ cat sub2/large6
392 large6
407 large6
393 $ cat sub2/large7
408 $ cat sub2/large7
394 large7
409 large7
395
410
396 Test addremove: verify that files that should be added as largfiles are added as
411 Test addremove: verify that files that should be added as largfiles are added as
397 such and that already-existing largfiles are not added as normal files by
412 such and that already-existing largfiles are not added as normal files by
398 accident.
413 accident.
399
414
400 $ rm normal3
415 $ rm normal3
401 $ rm sub/large4
416 $ rm sub/large4
402 $ echo "testing addremove with patterns" > testaddremove.dat
417 $ echo "testing addremove with patterns" > testaddremove.dat
403 $ echo "normaladdremove" > normaladdremove
418 $ echo "normaladdremove" > normaladdremove
404 $ hg addremove
419 $ hg addremove
405 removing sub/large4
420 removing sub/large4
406 adding testaddremove.dat as a largefile
421 adding testaddremove.dat as a largefile
407 removing normal3
422 removing normal3
408 adding normaladdremove
423 adding normaladdremove
409
424
410 Test addremove with -R
425 Test addremove with -R
411
426
412 $ hg up -C
427 $ hg up -C
413 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
428 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
414 getting changed largefiles
429 getting changed largefiles
415 1 largefiles updated, 0 removed
430 1 largefiles updated, 0 removed
416 $ rm normal3
431 $ rm normal3
417 $ rm sub/large4
432 $ rm sub/large4
418 $ echo "testing addremove with patterns" > testaddremove.dat
433 $ echo "testing addremove with patterns" > testaddremove.dat
419 $ echo "normaladdremove" > normaladdremove
434 $ echo "normaladdremove" > normaladdremove
420 $ cd ..
435 $ cd ..
421 $ hg -R a addremove
436 $ hg -R a addremove
422 removing sub/large4
437 removing sub/large4
423 adding a/testaddremove.dat as a largefile (glob)
438 adding a/testaddremove.dat as a largefile (glob)
424 removing normal3
439 removing normal3
425 adding normaladdremove
440 adding normaladdremove
426 $ cd a
441 $ cd a
427
442
428 Test 3364
443 Test 3364
429 $ hg clone . ../addrm
444 $ hg clone . ../addrm
430 updating to branch default
445 updating to branch default
431 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
446 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
432 getting changed largefiles
447 getting changed largefiles
433 3 largefiles updated, 0 removed
448 3 largefiles updated, 0 removed
434 $ cd ../addrm
449 $ cd ../addrm
435 $ cat >> .hg/hgrc <<EOF
450 $ cat >> .hg/hgrc <<EOF
436 > [hooks]
451 > [hooks]
437 > post-commit.stat=sh -c "echo \\"Invoking status postcommit hook\\"; hg status -A"
452 > post-commit.stat=sh -c "echo \\"Invoking status postcommit hook\\"; hg status -A"
438 > EOF
453 > EOF
439 $ touch foo
454 $ touch foo
440 $ hg add --large foo
455 $ hg add --large foo
441 $ hg ci -m "add foo"
456 $ hg ci -m "add foo"
442 Invoking status precommit hook
457 Invoking status precommit hook
443 A foo
458 A foo
444 Invoking status postcommit hook
459 Invoking status postcommit hook
445 C foo
460 C foo
446 C normal3
461 C normal3
447 C sub/large4
462 C sub/large4
448 C sub/normal4
463 C sub/normal4
449 C sub2/large6
464 C sub2/large6
450 C sub2/large7
465 C sub2/large7
451 $ rm foo
466 $ rm foo
452 $ hg st
467 $ hg st
453 ! foo
468 ! foo
454 hmm.. no precommit invoked, but there is a postcommit??
469 hmm.. no precommit invoked, but there is a postcommit??
455 $ hg ci -m "will not checkin"
470 $ hg ci -m "will not checkin"
456 nothing changed
471 nothing changed
457 Invoking status postcommit hook
472 Invoking status postcommit hook
458 ! foo
473 ! foo
459 C normal3
474 C normal3
460 C sub/large4
475 C sub/large4
461 C sub/normal4
476 C sub/normal4
462 C sub2/large6
477 C sub2/large6
463 C sub2/large7
478 C sub2/large7
464 [1]
479 [1]
465 $ hg addremove
480 $ hg addremove
466 removing foo
481 removing foo
467 $ hg st
482 $ hg st
468 R foo
483 R foo
469 $ hg ci -m "used to say nothing changed"
484 $ hg ci -m "used to say nothing changed"
470 Invoking status precommit hook
485 Invoking status precommit hook
471 R foo
486 R foo
472 Invoking status postcommit hook
487 Invoking status postcommit hook
473 C normal3
488 C normal3
474 C sub/large4
489 C sub/large4
475 C sub/normal4
490 C sub/normal4
476 C sub2/large6
491 C sub2/large6
477 C sub2/large7
492 C sub2/large7
478 $ hg st
493 $ hg st
479
494
480 Test 3507 (both normal files and largefiles were a problem)
495 Test 3507 (both normal files and largefiles were a problem)
481
496
482 $ touch normal
497 $ touch normal
483 $ touch large
498 $ touch large
484 $ hg add normal
499 $ hg add normal
485 $ hg add --large large
500 $ hg add --large large
486 $ hg ci -m "added"
501 $ hg ci -m "added"
487 Invoking status precommit hook
502 Invoking status precommit hook
488 A large
503 A large
489 A normal
504 A normal
490 Invoking status postcommit hook
505 Invoking status postcommit hook
491 C large
506 C large
492 C normal
507 C normal
493 C normal3
508 C normal3
494 C sub/large4
509 C sub/large4
495 C sub/normal4
510 C sub/normal4
496 C sub2/large6
511 C sub2/large6
497 C sub2/large7
512 C sub2/large7
498 $ hg remove normal
513 $ hg remove normal
499 $ hg addremove --traceback
514 $ hg addremove --traceback
500 $ hg ci -m "addremoved normal"
515 $ hg ci -m "addremoved normal"
501 Invoking status precommit hook
516 Invoking status precommit hook
502 R normal
517 R normal
503 Invoking status postcommit hook
518 Invoking status postcommit hook
504 C large
519 C large
505 C normal3
520 C normal3
506 C sub/large4
521 C sub/large4
507 C sub/normal4
522 C sub/normal4
508 C sub2/large6
523 C sub2/large6
509 C sub2/large7
524 C sub2/large7
510 $ hg up -C '.^'
525 $ hg up -C '.^'
511 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
526 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
512 getting changed largefiles
527 getting changed largefiles
513 0 largefiles updated, 0 removed
528 0 largefiles updated, 0 removed
514 $ hg remove large
529 $ hg remove large
515 $ hg addremove --traceback
530 $ hg addremove --traceback
516 $ hg ci -m "removed large"
531 $ hg ci -m "removed large"
517 Invoking status precommit hook
532 Invoking status precommit hook
518 R large
533 R large
519 created new head
534 created new head
520 Invoking status postcommit hook
535 Invoking status postcommit hook
521 C normal
536 C normal
522 C normal3
537 C normal3
523 C sub/large4
538 C sub/large4
524 C sub/normal4
539 C sub/normal4
525 C sub2/large6
540 C sub2/large6
526 C sub2/large7
541 C sub2/large7
527
542
528 Test that a standin can't be added as a large file
543 Test that a standin can't be added as a large file
529
544
530 $ touch large
545 $ touch large
531 $ hg add --large large
546 $ hg add --large large
532 $ hg ci -m "add"
547 $ hg ci -m "add"
533 Invoking status precommit hook
548 Invoking status precommit hook
534 A large
549 A large
535 Invoking status postcommit hook
550 Invoking status postcommit hook
536 C large
551 C large
537 C normal
552 C normal
538 C normal3
553 C normal3
539 C sub/large4
554 C sub/large4
540 C sub/normal4
555 C sub/normal4
541 C sub2/large6
556 C sub2/large6
542 C sub2/large7
557 C sub2/large7
543 $ hg remove large
558 $ hg remove large
544 $ touch large
559 $ touch large
545 $ hg addremove --config largefiles.patterns=**large --traceback
560 $ hg addremove --config largefiles.patterns=**large --traceback
546 adding large as a largefile
561 adding large as a largefile
547
562
548 Test that outgoing --large works (with revsets too)
563 Test that outgoing --large works (with revsets too)
549 $ hg outgoing --rev '.^' --large
564 $ hg outgoing --rev '.^' --large
550 comparing with $TESTTMP/a (glob)
565 comparing with $TESTTMP/a (glob)
551 searching for changes
566 searching for changes
552 changeset: 8:c02fd3b77ec4
567 changeset: 8:c02fd3b77ec4
553 user: test
568 user: test
554 date: Thu Jan 01 00:00:00 1970 +0000
569 date: Thu Jan 01 00:00:00 1970 +0000
555 summary: add foo
570 summary: add foo
556
571
557 changeset: 9:289dd08c9bbb
572 changeset: 9:289dd08c9bbb
558 user: test
573 user: test
559 date: Thu Jan 01 00:00:00 1970 +0000
574 date: Thu Jan 01 00:00:00 1970 +0000
560 summary: used to say nothing changed
575 summary: used to say nothing changed
561
576
562 changeset: 10:34f23ac6ac12
577 changeset: 10:34f23ac6ac12
563 user: test
578 user: test
564 date: Thu Jan 01 00:00:00 1970 +0000
579 date: Thu Jan 01 00:00:00 1970 +0000
565 summary: added
580 summary: added
566
581
567 changeset: 12:710c1b2f523c
582 changeset: 12:710c1b2f523c
568 parent: 10:34f23ac6ac12
583 parent: 10:34f23ac6ac12
569 user: test
584 user: test
570 date: Thu Jan 01 00:00:00 1970 +0000
585 date: Thu Jan 01 00:00:00 1970 +0000
571 summary: removed large
586 summary: removed large
572
587
573 searching for changes
588 searching for changes
574 largefiles to upload:
589 largefiles to upload:
575 large
590 large
576 foo
591 foo
577
592
578 $ cd ../a
593 $ cd ../a
579
594
580 Clone a largefiles repo.
595 Clone a largefiles repo.
581
596
582 $ hg clone . ../b
597 $ hg clone . ../b
583 updating to branch default
598 updating to branch default
584 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
599 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
585 getting changed largefiles
600 getting changed largefiles
586 3 largefiles updated, 0 removed
601 3 largefiles updated, 0 removed
587 $ cd ../b
602 $ cd ../b
588 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
603 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
589 7:daea875e9014 add/edit more largefiles
604 7:daea875e9014 add/edit more largefiles
590 6:4355d653f84f edit files yet again
605 6:4355d653f84f edit files yet again
591 5:9d5af5072dbd edit files again
606 5:9d5af5072dbd edit files again
592 4:74c02385b94c move files
607 4:74c02385b94c move files
593 3:9e8fbc4bce62 copy files
608 3:9e8fbc4bce62 copy files
594 2:51a0ae4d5864 remove files
609 2:51a0ae4d5864 remove files
595 1:ce8896473775 edit files
610 1:ce8896473775 edit files
596 0:30d30fe6a5be add files
611 0:30d30fe6a5be add files
597 $ cat normal3
612 $ cat normal3
598 normal33
613 normal33
599 $ cat sub/normal4
614 $ cat sub/normal4
600 normal44
615 normal44
601 $ cat sub/large4
616 $ cat sub/large4
602 large44
617 large44
603 $ cat sub2/large6
618 $ cat sub2/large6
604 large6
619 large6
605 $ cat sub2/large7
620 $ cat sub2/large7
606 large7
621 large7
607 $ cd ..
622 $ cd ..
608 $ hg clone a -r 3 c
623 $ hg clone a -r 3 c
609 adding changesets
624 adding changesets
610 adding manifests
625 adding manifests
611 adding file changes
626 adding file changes
612 added 4 changesets with 10 changes to 4 files
627 added 4 changesets with 10 changes to 4 files
613 updating to branch default
628 updating to branch default
614 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
629 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
615 getting changed largefiles
630 getting changed largefiles
616 2 largefiles updated, 0 removed
631 2 largefiles updated, 0 removed
617 $ cd c
632 $ cd c
618 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
633 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
619 3:9e8fbc4bce62 copy files
634 3:9e8fbc4bce62 copy files
620 2:51a0ae4d5864 remove files
635 2:51a0ae4d5864 remove files
621 1:ce8896473775 edit files
636 1:ce8896473775 edit files
622 0:30d30fe6a5be add files
637 0:30d30fe6a5be add files
623 $ cat normal1
638 $ cat normal1
624 normal22
639 normal22
625 $ cat large1
640 $ cat large1
626 large22
641 large22
627 $ cat sub/normal2
642 $ cat sub/normal2
628 normal22
643 normal22
629 $ cat sub/large2
644 $ cat sub/large2
630 large22
645 large22
631
646
632 Old revisions of a clone have correct largefiles content (this also
647 Old revisions of a clone have correct largefiles content (this also
633 tests update).
648 tests update).
634
649
635 $ hg update -r 1
650 $ hg update -r 1
636 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
651 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
637 getting changed largefiles
652 getting changed largefiles
638 1 largefiles updated, 0 removed
653 1 largefiles updated, 0 removed
639 $ cat large1
654 $ cat large1
640 large11
655 large11
641 $ cat sub/large2
656 $ cat sub/large2
642 large22
657 large22
643 $ cd ..
658 $ cd ..
644
659
645 Test cloning with --all-largefiles flag
660 Test cloning with --all-largefiles flag
646
661
647 $ rm "${USERCACHE}"/*
662 $ rm "${USERCACHE}"/*
648 $ hg clone --all-largefiles a a-backup
663 $ hg clone --all-largefiles a a-backup
649 updating to branch default
664 updating to branch default
650 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
665 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
651 getting changed largefiles
666 getting changed largefiles
652 3 largefiles updated, 0 removed
667 3 largefiles updated, 0 removed
653 8 additional largefiles cached
668 8 additional largefiles cached
654
669
655 $ hg clone --all-largefiles a ssh://localhost/a
670 $ hg clone --all-largefiles a ssh://localhost/a
656 abort: --all-largefiles is incompatible with non-local destination ssh://localhost/a
671 abort: --all-largefiles is incompatible with non-local destination ssh://localhost/a
657 [255]
672 [255]
658
673
659 Test pulling with --all-largefiles flag
674 Test pulling with --all-largefiles flag
660
675
661 $ rm -Rf a-backup
676 $ rm -Rf a-backup
662 $ hg clone -r 1 a a-backup
677 $ hg clone -r 1 a a-backup
663 adding changesets
678 adding changesets
664 adding manifests
679 adding manifests
665 adding file changes
680 adding file changes
666 added 2 changesets with 8 changes to 4 files
681 added 2 changesets with 8 changes to 4 files
667 updating to branch default
682 updating to branch default
668 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
683 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
669 getting changed largefiles
684 getting changed largefiles
670 2 largefiles updated, 0 removed
685 2 largefiles updated, 0 removed
671 $ rm "${USERCACHE}"/*
686 $ rm "${USERCACHE}"/*
672 $ cd a-backup
687 $ cd a-backup
673 $ hg pull --all-largefiles
688 $ hg pull --all-largefiles
674 pulling from $TESTTMP/a (glob)
689 pulling from $TESTTMP/a (glob)
675 searching for changes
690 searching for changes
676 adding changesets
691 adding changesets
677 adding manifests
692 adding manifests
678 adding file changes
693 adding file changes
679 added 6 changesets with 16 changes to 8 files
694 added 6 changesets with 16 changes to 8 files
680 (run 'hg update' to get a working copy)
695 (run 'hg update' to get a working copy)
681 caching new largefiles
696 caching new largefiles
682 3 largefiles cached
697 3 largefiles cached
683 3 additional largefiles cached
698 3 additional largefiles cached
684 $ cd ..
699 $ cd ..
685
700
686 Rebasing between two repositories does not revert largefiles to old
701 Rebasing between two repositories does not revert largefiles to old
687 revisions (this was a very bad bug that took a lot of work to fix).
702 revisions (this was a very bad bug that took a lot of work to fix).
688
703
689 $ hg clone a d
704 $ hg clone a d
690 updating to branch default
705 updating to branch default
691 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
706 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
692 getting changed largefiles
707 getting changed largefiles
693 3 largefiles updated, 0 removed
708 3 largefiles updated, 0 removed
694 $ cd b
709 $ cd b
695 $ echo large4-modified > sub/large4
710 $ echo large4-modified > sub/large4
696 $ echo normal3-modified > normal3
711 $ echo normal3-modified > normal3
697 $ hg commit -m "modify normal file and largefile in repo b"
712 $ hg commit -m "modify normal file and largefile in repo b"
698 Invoking status precommit hook
713 Invoking status precommit hook
699 M normal3
714 M normal3
700 M sub/large4
715 M sub/large4
701 $ cd ../d
716 $ cd ../d
702 $ echo large6-modified > sub2/large6
717 $ echo large6-modified > sub2/large6
703 $ echo normal4-modified > sub/normal4
718 $ echo normal4-modified > sub/normal4
704 $ hg commit -m "modify normal file largefile in repo d"
719 $ hg commit -m "modify normal file largefile in repo d"
705 Invoking status precommit hook
720 Invoking status precommit hook
706 M sub/normal4
721 M sub/normal4
707 M sub2/large6
722 M sub2/large6
708 $ cd ..
723 $ cd ..
709 $ hg clone d e
724 $ hg clone d e
710 updating to branch default
725 updating to branch default
711 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
726 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
712 getting changed largefiles
727 getting changed largefiles
713 3 largefiles updated, 0 removed
728 3 largefiles updated, 0 removed
714 $ cd d
729 $ cd d
715 $ hg pull --rebase ../b
730 $ hg pull --rebase ../b
716 pulling from ../b
731 pulling from ../b
717 searching for changes
732 searching for changes
718 adding changesets
733 adding changesets
719 adding manifests
734 adding manifests
720 adding file changes
735 adding file changes
721 added 1 changesets with 2 changes to 2 files (+1 heads)
736 added 1 changesets with 2 changes to 2 files (+1 heads)
722 Invoking status precommit hook
737 Invoking status precommit hook
723 M sub/normal4
738 M sub/normal4
724 M sub2/large6
739 M sub2/large6
725 saved backup bundle to $TESTTMP/d/.hg/strip-backup/f574fb32bb45-backup.hg (glob)
740 saved backup bundle to $TESTTMP/d/.hg/strip-backup/f574fb32bb45-backup.hg (glob)
726 nothing to rebase
741 nothing to rebase
727 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
742 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
728 9:598410d3eb9a modify normal file largefile in repo d
743 9:598410d3eb9a modify normal file largefile in repo d
729 8:a381d2c8c80e modify normal file and largefile in repo b
744 8:a381d2c8c80e modify normal file and largefile in repo b
730 7:daea875e9014 add/edit more largefiles
745 7:daea875e9014 add/edit more largefiles
731 6:4355d653f84f edit files yet again
746 6:4355d653f84f edit files yet again
732 5:9d5af5072dbd edit files again
747 5:9d5af5072dbd edit files again
733 4:74c02385b94c move files
748 4:74c02385b94c move files
734 3:9e8fbc4bce62 copy files
749 3:9e8fbc4bce62 copy files
735 2:51a0ae4d5864 remove files
750 2:51a0ae4d5864 remove files
736 1:ce8896473775 edit files
751 1:ce8896473775 edit files
737 0:30d30fe6a5be add files
752 0:30d30fe6a5be add files
738 $ cat normal3
753 $ cat normal3
739 normal3-modified
754 normal3-modified
740 $ cat sub/normal4
755 $ cat sub/normal4
741 normal4-modified
756 normal4-modified
742 $ cat sub/large4
757 $ cat sub/large4
743 large4-modified
758 large4-modified
744 $ cat sub2/large6
759 $ cat sub2/large6
745 large6-modified
760 large6-modified
746 $ cat sub2/large7
761 $ cat sub2/large7
747 large7
762 large7
748 $ cd ../e
763 $ cd ../e
749 $ hg pull ../b
764 $ hg pull ../b
750 pulling from ../b
765 pulling from ../b
751 searching for changes
766 searching for changes
752 adding changesets
767 adding changesets
753 adding manifests
768 adding manifests
754 adding file changes
769 adding file changes
755 added 1 changesets with 2 changes to 2 files (+1 heads)
770 added 1 changesets with 2 changes to 2 files (+1 heads)
756 (run 'hg heads' to see heads, 'hg merge' to merge)
771 (run 'hg heads' to see heads, 'hg merge' to merge)
757 caching new largefiles
772 caching new largefiles
758 0 largefiles cached
773 0 largefiles cached
759 $ hg rebase
774 $ hg rebase
760 Invoking status precommit hook
775 Invoking status precommit hook
761 M sub/normal4
776 M sub/normal4
762 M sub2/large6
777 M sub2/large6
763 saved backup bundle to $TESTTMP/e/.hg/strip-backup/f574fb32bb45-backup.hg (glob)
778 saved backup bundle to $TESTTMP/e/.hg/strip-backup/f574fb32bb45-backup.hg (glob)
764 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
779 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
765 9:598410d3eb9a modify normal file largefile in repo d
780 9:598410d3eb9a modify normal file largefile in repo d
766 8:a381d2c8c80e modify normal file and largefile in repo b
781 8:a381d2c8c80e modify normal file and largefile in repo b
767 7:daea875e9014 add/edit more largefiles
782 7:daea875e9014 add/edit more largefiles
768 6:4355d653f84f edit files yet again
783 6:4355d653f84f edit files yet again
769 5:9d5af5072dbd edit files again
784 5:9d5af5072dbd edit files again
770 4:74c02385b94c move files
785 4:74c02385b94c move files
771 3:9e8fbc4bce62 copy files
786 3:9e8fbc4bce62 copy files
772 2:51a0ae4d5864 remove files
787 2:51a0ae4d5864 remove files
773 1:ce8896473775 edit files
788 1:ce8896473775 edit files
774 0:30d30fe6a5be add files
789 0:30d30fe6a5be add files
775 $ cat normal3
790 $ cat normal3
776 normal3-modified
791 normal3-modified
777 $ cat sub/normal4
792 $ cat sub/normal4
778 normal4-modified
793 normal4-modified
779 $ cat sub/large4
794 $ cat sub/large4
780 large4-modified
795 large4-modified
781 $ cat sub2/large6
796 $ cat sub2/large6
782 large6-modified
797 large6-modified
783 $ cat sub2/large7
798 $ cat sub2/large7
784 large7
799 large7
785
800
786 Rollback on largefiles.
801 Rollback on largefiles.
787
802
788 $ echo large4-modified-again > sub/large4
803 $ echo large4-modified-again > sub/large4
789 $ hg commit -m "Modify large4 again"
804 $ hg commit -m "Modify large4 again"
790 Invoking status precommit hook
805 Invoking status precommit hook
791 M sub/large4
806 M sub/large4
792 $ hg rollback
807 $ hg rollback
793 repository tip rolled back to revision 9 (undo commit)
808 repository tip rolled back to revision 9 (undo commit)
794 working directory now based on revision 9
809 working directory now based on revision 9
795 $ hg st
810 $ hg st
796 M sub/large4
811 M sub/large4
797 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
812 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
798 9:598410d3eb9a modify normal file largefile in repo d
813 9:598410d3eb9a modify normal file largefile in repo d
799 8:a381d2c8c80e modify normal file and largefile in repo b
814 8:a381d2c8c80e modify normal file and largefile in repo b
800 7:daea875e9014 add/edit more largefiles
815 7:daea875e9014 add/edit more largefiles
801 6:4355d653f84f edit files yet again
816 6:4355d653f84f edit files yet again
802 5:9d5af5072dbd edit files again
817 5:9d5af5072dbd edit files again
803 4:74c02385b94c move files
818 4:74c02385b94c move files
804 3:9e8fbc4bce62 copy files
819 3:9e8fbc4bce62 copy files
805 2:51a0ae4d5864 remove files
820 2:51a0ae4d5864 remove files
806 1:ce8896473775 edit files
821 1:ce8896473775 edit files
807 0:30d30fe6a5be add files
822 0:30d30fe6a5be add files
808 $ cat sub/large4
823 $ cat sub/large4
809 large4-modified-again
824 large4-modified-again
810
825
811 "update --check" refuses to update with uncommitted changes.
826 "update --check" refuses to update with uncommitted changes.
812 $ hg update --check 8
827 $ hg update --check 8
813 abort: uncommitted local changes
828 abort: uncommitted local changes
814 [255]
829 [255]
815
830
816 "update --clean" leaves correct largefiles in working copy.
831 "update --clean" leaves correct largefiles in working copy.
817
832
818 $ hg update --clean
833 $ hg update --clean
819 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
834 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
820 getting changed largefiles
835 getting changed largefiles
821 1 largefiles updated, 0 removed
836 1 largefiles updated, 0 removed
822 $ cat normal3
837 $ cat normal3
823 normal3-modified
838 normal3-modified
824 $ cat sub/normal4
839 $ cat sub/normal4
825 normal4-modified
840 normal4-modified
826 $ cat sub/large4
841 $ cat sub/large4
827 large4-modified
842 large4-modified
828 $ cat sub2/large6
843 $ cat sub2/large6
829 large6-modified
844 large6-modified
830 $ cat sub2/large7
845 $ cat sub2/large7
831 large7
846 large7
832
847
833 Now "update check" is happy.
848 Now "update check" is happy.
834 $ hg update --check 8
849 $ hg update --check 8
835 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
850 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
836 getting changed largefiles
851 getting changed largefiles
837 1 largefiles updated, 0 removed
852 1 largefiles updated, 0 removed
838 $ hg update --check
853 $ hg update --check
839 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
854 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
840 getting changed largefiles
855 getting changed largefiles
841 1 largefiles updated, 0 removed
856 1 largefiles updated, 0 removed
842
857
843 Test removing empty largefiles directories on update
858 Test removing empty largefiles directories on update
844 $ test -d sub2 && echo "sub2 exists"
859 $ test -d sub2 && echo "sub2 exists"
845 sub2 exists
860 sub2 exists
846 $ hg update -q null
861 $ hg update -q null
847 $ test -d sub2 && echo "error: sub2 should not exist anymore"
862 $ test -d sub2 && echo "error: sub2 should not exist anymore"
848 [1]
863 [1]
849 $ hg update -q
864 $ hg update -q
850
865
851 Test hg remove removes empty largefiles directories
866 Test hg remove removes empty largefiles directories
852 $ test -d sub2 && echo "sub2 exists"
867 $ test -d sub2 && echo "sub2 exists"
853 sub2 exists
868 sub2 exists
854 $ hg remove sub2/*
869 $ hg remove sub2/*
855 $ test -d sub2 && echo "error: sub2 should not exist anymore"
870 $ test -d sub2 && echo "error: sub2 should not exist anymore"
856 [1]
871 [1]
857 $ hg revert sub2/large6 sub2/large7
872 $ hg revert sub2/large6 sub2/large7
858
873
859 "revert" works on largefiles (and normal files too).
874 "revert" works on largefiles (and normal files too).
860 $ echo hack3 >> normal3
875 $ echo hack3 >> normal3
861 $ echo hack4 >> sub/normal4
876 $ echo hack4 >> sub/normal4
862 $ echo hack4 >> sub/large4
877 $ echo hack4 >> sub/large4
863 $ rm sub2/large6
878 $ rm sub2/large6
864 $ hg revert sub2/large6
879 $ hg revert sub2/large6
865 $ hg rm sub2/large6
880 $ hg rm sub2/large6
866 $ echo new >> sub2/large8
881 $ echo new >> sub2/large8
867 $ hg add --large sub2/large8
882 $ hg add --large sub2/large8
868 # XXX we don't really want to report that we're reverting the standin;
883 # XXX we don't really want to report that we're reverting the standin;
869 # that's just an implementation detail. But I don't see an obvious fix. ;-(
884 # that's just an implementation detail. But I don't see an obvious fix. ;-(
870 $ hg revert sub
885 $ hg revert sub
871 reverting .hglf/sub/large4 (glob)
886 reverting .hglf/sub/large4 (glob)
872 reverting sub/normal4 (glob)
887 reverting sub/normal4 (glob)
873 $ hg status
888 $ hg status
874 M normal3
889 M normal3
875 A sub2/large8
890 A sub2/large8
876 R sub2/large6
891 R sub2/large6
877 ? sub/large4.orig
892 ? sub/large4.orig
878 ? sub/normal4.orig
893 ? sub/normal4.orig
879 $ cat sub/normal4
894 $ cat sub/normal4
880 normal4-modified
895 normal4-modified
881 $ cat sub/large4
896 $ cat sub/large4
882 large4-modified
897 large4-modified
883 $ hg revert -a --no-backup
898 $ hg revert -a --no-backup
884 undeleting .hglf/sub2/large6 (glob)
899 undeleting .hglf/sub2/large6 (glob)
885 forgetting .hglf/sub2/large8 (glob)
900 forgetting .hglf/sub2/large8 (glob)
886 reverting normal3
901 reverting normal3
887 $ hg status
902 $ hg status
888 ? sub/large4.orig
903 ? sub/large4.orig
889 ? sub/normal4.orig
904 ? sub/normal4.orig
890 ? sub2/large8
905 ? sub2/large8
891 $ cat normal3
906 $ cat normal3
892 normal3-modified
907 normal3-modified
893 $ cat sub2/large6
908 $ cat sub2/large6
894 large6-modified
909 large6-modified
895 $ rm sub/*.orig sub2/large8
910 $ rm sub/*.orig sub2/large8
896
911
897 revert some files to an older revision
912 revert some files to an older revision
898 $ hg revert --no-backup -r 8 sub2
913 $ hg revert --no-backup -r 8 sub2
899 reverting .hglf/sub2/large6 (glob)
914 reverting .hglf/sub2/large6 (glob)
900 $ cat sub2/large6
915 $ cat sub2/large6
901 large6
916 large6
902 $ hg revert --no-backup -C -r '.^' sub2
917 $ hg revert --no-backup -C -r '.^' sub2
903 reverting .hglf/sub2/large6 (glob)
918 reverting .hglf/sub2/large6 (glob)
904 $ hg revert --no-backup sub2
919 $ hg revert --no-backup sub2
905 reverting .hglf/sub2/large6 (glob)
920 reverting .hglf/sub2/large6 (glob)
906 $ hg status
921 $ hg status
907
922
908 "verify --large" actually verifies largefiles
923 "verify --large" actually verifies largefiles
909
924
910 $ hg verify --large
925 $ hg verify --large
911 checking changesets
926 checking changesets
912 checking manifests
927 checking manifests
913 crosschecking files in changesets and manifests
928 crosschecking files in changesets and manifests
914 checking files
929 checking files
915 10 files, 10 changesets, 28 total revisions
930 10 files, 10 changesets, 28 total revisions
916 searching 1 changesets for largefiles
931 searching 1 changesets for largefiles
917 verified existence of 3 revisions of 3 largefiles
932 verified existence of 3 revisions of 3 largefiles
918
933
919 Merging does not revert to old versions of largefiles and also check
934 Merging does not revert to old versions of largefiles and also check
920 that merging after having pulled from a non-default remote works
935 that merging after having pulled from a non-default remote works
921 correctly.
936 correctly.
922
937
923 $ cd ..
938 $ cd ..
924 $ hg clone -r 7 e temp
939 $ hg clone -r 7 e temp
925 adding changesets
940 adding changesets
926 adding manifests
941 adding manifests
927 adding file changes
942 adding file changes
928 added 8 changesets with 24 changes to 10 files
943 added 8 changesets with 24 changes to 10 files
929 updating to branch default
944 updating to branch default
930 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
945 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
931 getting changed largefiles
946 getting changed largefiles
932 3 largefiles updated, 0 removed
947 3 largefiles updated, 0 removed
933 $ hg clone temp f
948 $ hg clone temp f
934 updating to branch default
949 updating to branch default
935 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
950 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
936 getting changed largefiles
951 getting changed largefiles
937 3 largefiles updated, 0 removed
952 3 largefiles updated, 0 removed
938 # Delete the largefiles in the largefiles system cache so that we have an
953 # Delete the largefiles in the largefiles system cache so that we have an
939 # opportunity to test that caching after a pull works.
954 # opportunity to test that caching after a pull works.
940 $ rm "${USERCACHE}"/*
955 $ rm "${USERCACHE}"/*
941 $ cd f
956 $ cd f
942 $ echo "large4-merge-test" > sub/large4
957 $ echo "large4-merge-test" > sub/large4
943 $ hg commit -m "Modify large4 to test merge"
958 $ hg commit -m "Modify large4 to test merge"
944 Invoking status precommit hook
959 Invoking status precommit hook
945 M sub/large4
960 M sub/large4
946 $ hg pull ../e
961 $ hg pull ../e
947 pulling from ../e
962 pulling from ../e
948 searching for changes
963 searching for changes
949 adding changesets
964 adding changesets
950 adding manifests
965 adding manifests
951 adding file changes
966 adding file changes
952 added 2 changesets with 4 changes to 4 files (+1 heads)
967 added 2 changesets with 4 changes to 4 files (+1 heads)
953 (run 'hg heads' to see heads, 'hg merge' to merge)
968 (run 'hg heads' to see heads, 'hg merge' to merge)
954 caching new largefiles
969 caching new largefiles
955 2 largefiles cached
970 2 largefiles cached
956 $ hg merge
971 $ hg merge
957 merging sub/large4
972 merging sub/large4
958 largefile sub/large4 has a merge conflict
973 largefile sub/large4 has a merge conflict
959 keep (l)ocal or take (o)ther? l
974 keep (l)ocal or take (o)ther? l
960 3 files updated, 1 files merged, 0 files removed, 0 files unresolved
975 3 files updated, 1 files merged, 0 files removed, 0 files unresolved
961 (branch merge, don't forget to commit)
976 (branch merge, don't forget to commit)
962 getting changed largefiles
977 getting changed largefiles
963 1 largefiles updated, 0 removed
978 1 largefiles updated, 0 removed
964 $ hg commit -m "Merge repos e and f"
979 $ hg commit -m "Merge repos e and f"
965 Invoking status precommit hook
980 Invoking status precommit hook
966 M normal3
981 M normal3
967 M sub/normal4
982 M sub/normal4
968 M sub2/large6
983 M sub2/large6
969 $ cat normal3
984 $ cat normal3
970 normal3-modified
985 normal3-modified
971 $ cat sub/normal4
986 $ cat sub/normal4
972 normal4-modified
987 normal4-modified
973 $ cat sub/large4
988 $ cat sub/large4
974 large4-merge-test
989 large4-merge-test
975 $ cat sub2/large6
990 $ cat sub2/large6
976 large6-modified
991 large6-modified
977 $ cat sub2/large7
992 $ cat sub2/large7
978 large7
993 large7
979
994
980 Test status after merging with a branch that introduces a new largefile:
995 Test status after merging with a branch that introduces a new largefile:
981
996
982 $ echo large > large
997 $ echo large > large
983 $ hg add --large large
998 $ hg add --large large
984 $ hg commit -m 'add largefile'
999 $ hg commit -m 'add largefile'
985 Invoking status precommit hook
1000 Invoking status precommit hook
986 A large
1001 A large
987 $ hg update -q ".^"
1002 $ hg update -q ".^"
988 $ echo change >> normal3
1003 $ echo change >> normal3
989 $ hg commit -m 'some change'
1004 $ hg commit -m 'some change'
990 Invoking status precommit hook
1005 Invoking status precommit hook
991 M normal3
1006 M normal3
992 created new head
1007 created new head
993 $ hg merge
1008 $ hg merge
994 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1009 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
995 (branch merge, don't forget to commit)
1010 (branch merge, don't forget to commit)
996 getting changed largefiles
1011 getting changed largefiles
997 1 largefiles updated, 0 removed
1012 1 largefiles updated, 0 removed
998 $ hg status
1013 $ hg status
999 M large
1014 M large
1000
1015
1001 Test that a normal file and a largefile with the same name and path cannot
1016 Test that a normal file and a largefile with the same name and path cannot
1002 coexist.
1017 coexist.
1003
1018
1004 $ rm sub2/large7
1019 $ rm sub2/large7
1005 $ echo "largeasnormal" > sub2/large7
1020 $ echo "largeasnormal" > sub2/large7
1006 $ hg add sub2/large7
1021 $ hg add sub2/large7
1007 sub2/large7 already a largefile
1022 sub2/large7 already a largefile
1008
1023
1009 Test that transplanting a largefile change works correctly.
1024 Test that transplanting a largefile change works correctly.
1010
1025
1011 $ cd ..
1026 $ cd ..
1012 $ hg clone -r 8 d g
1027 $ hg clone -r 8 d g
1013 adding changesets
1028 adding changesets
1014 adding manifests
1029 adding manifests
1015 adding file changes
1030 adding file changes
1016 added 9 changesets with 26 changes to 10 files
1031 added 9 changesets with 26 changes to 10 files
1017 updating to branch default
1032 updating to branch default
1018 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1033 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1019 getting changed largefiles
1034 getting changed largefiles
1020 3 largefiles updated, 0 removed
1035 3 largefiles updated, 0 removed
1021 $ cd g
1036 $ cd g
1022 $ hg transplant -s ../d 598410d3eb9a
1037 $ hg transplant -s ../d 598410d3eb9a
1023 searching for changes
1038 searching for changes
1024 searching for changes
1039 searching for changes
1025 adding changesets
1040 adding changesets
1026 adding manifests
1041 adding manifests
1027 adding file changes
1042 adding file changes
1028 added 1 changesets with 2 changes to 2 files
1043 added 1 changesets with 2 changes to 2 files
1029 getting changed largefiles
1044 getting changed largefiles
1030 1 largefiles updated, 0 removed
1045 1 largefiles updated, 0 removed
1031 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
1046 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
1032 9:598410d3eb9a modify normal file largefile in repo d
1047 9:598410d3eb9a modify normal file largefile in repo d
1033 8:a381d2c8c80e modify normal file and largefile in repo b
1048 8:a381d2c8c80e modify normal file and largefile in repo b
1034 7:daea875e9014 add/edit more largefiles
1049 7:daea875e9014 add/edit more largefiles
1035 6:4355d653f84f edit files yet again
1050 6:4355d653f84f edit files yet again
1036 5:9d5af5072dbd edit files again
1051 5:9d5af5072dbd edit files again
1037 4:74c02385b94c move files
1052 4:74c02385b94c move files
1038 3:9e8fbc4bce62 copy files
1053 3:9e8fbc4bce62 copy files
1039 2:51a0ae4d5864 remove files
1054 2:51a0ae4d5864 remove files
1040 1:ce8896473775 edit files
1055 1:ce8896473775 edit files
1041 0:30d30fe6a5be add files
1056 0:30d30fe6a5be add files
1042 $ cat normal3
1057 $ cat normal3
1043 normal3-modified
1058 normal3-modified
1044 $ cat sub/normal4
1059 $ cat sub/normal4
1045 normal4-modified
1060 normal4-modified
1046 $ cat sub/large4
1061 $ cat sub/large4
1047 large4-modified
1062 large4-modified
1048 $ cat sub2/large6
1063 $ cat sub2/large6
1049 large6-modified
1064 large6-modified
1050 $ cat sub2/large7
1065 $ cat sub2/large7
1051 large7
1066 large7
1052
1067
1053 Cat a largefile
1068 Cat a largefile
1054 $ hg cat normal3
1069 $ hg cat normal3
1055 normal3-modified
1070 normal3-modified
1056 $ hg cat sub/large4
1071 $ hg cat sub/large4
1057 large4-modified
1072 large4-modified
1058 $ rm "${USERCACHE}"/*
1073 $ rm "${USERCACHE}"/*
1059 $ hg cat -r a381d2c8c80e -o cat.out sub/large4
1074 $ hg cat -r a381d2c8c80e -o cat.out sub/large4
1060 $ cat cat.out
1075 $ cat cat.out
1061 large4-modified
1076 large4-modified
1062 $ rm cat.out
1077 $ rm cat.out
1063 $ hg cat -r a381d2c8c80e normal3
1078 $ hg cat -r a381d2c8c80e normal3
1064 normal3-modified
1079 normal3-modified
1065 $ hg cat -r '.^' normal3
1080 $ hg cat -r '.^' normal3
1066 normal3-modified
1081 normal3-modified
1067 $ hg cat -r '.^' sub/large4
1082 $ hg cat -r '.^' sub/large4
1068 large4-modified
1083 large4-modified
1069
1084
1070 Test that renaming a largefile results in correct output for status
1085 Test that renaming a largefile results in correct output for status
1071
1086
1072 $ hg rename sub/large4 large4-renamed
1087 $ hg rename sub/large4 large4-renamed
1073 $ hg commit -m "test rename output"
1088 $ hg commit -m "test rename output"
1074 Invoking status precommit hook
1089 Invoking status precommit hook
1075 A large4-renamed
1090 A large4-renamed
1076 R sub/large4
1091 R sub/large4
1077 $ cat large4-renamed
1092 $ cat large4-renamed
1078 large4-modified
1093 large4-modified
1079 $ cd sub2
1094 $ cd sub2
1080 $ hg rename large6 large6-renamed
1095 $ hg rename large6 large6-renamed
1081 $ hg st
1096 $ hg st
1082 A sub2/large6-renamed
1097 A sub2/large6-renamed
1083 R sub2/large6
1098 R sub2/large6
1084 $ cd ..
1099 $ cd ..
1085
1100
1086 Test --normal flag
1101 Test --normal flag
1087
1102
1088 $ dd if=/dev/zero bs=2k count=11k > new-largefile 2> /dev/null
1103 $ dd if=/dev/zero bs=2k count=11k > new-largefile 2> /dev/null
1089 $ hg add --normal --large new-largefile
1104 $ hg add --normal --large new-largefile
1090 abort: --normal cannot be used with --large
1105 abort: --normal cannot be used with --large
1091 [255]
1106 [255]
1092 $ hg add --normal new-largefile
1107 $ hg add --normal new-largefile
1093 new-largefile: up to 69 MB of RAM may be required to manage this file
1108 new-largefile: up to 69 MB of RAM may be required to manage this file
1094 (use 'hg revert new-largefile' to cancel the pending addition)
1109 (use 'hg revert new-largefile' to cancel the pending addition)
1095 $ cd ..
1110 $ cd ..
1096
1111
1097 #if serve
1112 #if serve
1098 vanilla clients not locked out from largefiles servers on vanilla repos
1113 vanilla clients not locked out from largefiles servers on vanilla repos
1099 $ mkdir r1
1114 $ mkdir r1
1100 $ cd r1
1115 $ cd r1
1101 $ hg init
1116 $ hg init
1102 $ echo c1 > f1
1117 $ echo c1 > f1
1103 $ hg add f1
1118 $ hg add f1
1104 $ hg commit -m "m1"
1119 $ hg commit -m "m1"
1105 Invoking status precommit hook
1120 Invoking status precommit hook
1106 A f1
1121 A f1
1107 $ cd ..
1122 $ cd ..
1108 $ hg serve -R r1 -d -p $HGPORT --pid-file hg.pid
1123 $ hg serve -R r1 -d -p $HGPORT --pid-file hg.pid
1109 $ cat hg.pid >> $DAEMON_PIDS
1124 $ cat hg.pid >> $DAEMON_PIDS
1110 $ hg --config extensions.largefiles=! clone http://localhost:$HGPORT r2
1125 $ hg --config extensions.largefiles=! clone http://localhost:$HGPORT r2
1111 requesting all changes
1126 requesting all changes
1112 adding changesets
1127 adding changesets
1113 adding manifests
1128 adding manifests
1114 adding file changes
1129 adding file changes
1115 added 1 changesets with 1 changes to 1 files
1130 added 1 changesets with 1 changes to 1 files
1116 updating to branch default
1131 updating to branch default
1117 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1132 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1118
1133
1119 largefiles clients still work with vanilla servers
1134 largefiles clients still work with vanilla servers
1120 $ hg --config extensions.largefiles=! serve -R r1 -d -p $HGPORT1 --pid-file hg.pid
1135 $ hg --config extensions.largefiles=! serve -R r1 -d -p $HGPORT1 --pid-file hg.pid
1121 $ cat hg.pid >> $DAEMON_PIDS
1136 $ cat hg.pid >> $DAEMON_PIDS
1122 $ hg clone http://localhost:$HGPORT1 r3
1137 $ hg clone http://localhost:$HGPORT1 r3
1123 requesting all changes
1138 requesting all changes
1124 adding changesets
1139 adding changesets
1125 adding manifests
1140 adding manifests
1126 adding file changes
1141 adding file changes
1127 added 1 changesets with 1 changes to 1 files
1142 added 1 changesets with 1 changes to 1 files
1128 updating to branch default
1143 updating to branch default
1129 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1144 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1130 #endif
1145 #endif
1131
1146
1132
1147
1133 vanilla clients locked out from largefiles http repos
1148 vanilla clients locked out from largefiles http repos
1134 $ mkdir r4
1149 $ mkdir r4
1135 $ cd r4
1150 $ cd r4
1136 $ hg init
1151 $ hg init
1137 $ echo c1 > f1
1152 $ echo c1 > f1
1138 $ hg add --large f1
1153 $ hg add --large f1
1139 $ hg commit -m "m1"
1154 $ hg commit -m "m1"
1140 Invoking status precommit hook
1155 Invoking status precommit hook
1141 A f1
1156 A f1
1142 $ cd ..
1157 $ cd ..
1143
1158
1144 largefiles can be pushed locally (issue3583)
1159 largefiles can be pushed locally (issue3583)
1145 $ hg init dest
1160 $ hg init dest
1146 $ cd r4
1161 $ cd r4
1147 $ hg outgoing ../dest
1162 $ hg outgoing ../dest
1148 comparing with ../dest
1163 comparing with ../dest
1149 searching for changes
1164 searching for changes
1150 changeset: 0:639881c12b4c
1165 changeset: 0:639881c12b4c
1151 tag: tip
1166 tag: tip
1152 user: test
1167 user: test
1153 date: Thu Jan 01 00:00:00 1970 +0000
1168 date: Thu Jan 01 00:00:00 1970 +0000
1154 summary: m1
1169 summary: m1
1155
1170
1156 $ hg push ../dest
1171 $ hg push ../dest
1157 pushing to ../dest
1172 pushing to ../dest
1158 searching for changes
1173 searching for changes
1159 searching for changes
1174 searching for changes
1160 adding changesets
1175 adding changesets
1161 adding manifests
1176 adding manifests
1162 adding file changes
1177 adding file changes
1163 added 1 changesets with 1 changes to 1 files
1178 added 1 changesets with 1 changes to 1 files
1164
1179
1165 exit code with nothing outgoing (issue3611)
1180 exit code with nothing outgoing (issue3611)
1166 $ hg outgoing ../dest
1181 $ hg outgoing ../dest
1167 comparing with ../dest
1182 comparing with ../dest
1168 searching for changes
1183 searching for changes
1169 no changes found
1184 no changes found
1170 [1]
1185 [1]
1171 $ cd ..
1186 $ cd ..
1172
1187
1173 #if serve
1188 #if serve
1174 $ hg serve -R r4 -d -p $HGPORT2 --pid-file hg.pid
1189 $ hg serve -R r4 -d -p $HGPORT2 --pid-file hg.pid
1175 $ cat hg.pid >> $DAEMON_PIDS
1190 $ cat hg.pid >> $DAEMON_PIDS
1176 $ hg --config extensions.largefiles=! clone http://localhost:$HGPORT2 r5
1191 $ hg --config extensions.largefiles=! clone http://localhost:$HGPORT2 r5
1177 abort: remote error:
1192 abort: remote error:
1178
1193
1179 This repository uses the largefiles extension.
1194 This repository uses the largefiles extension.
1180
1195
1181 Please enable it in your Mercurial config file.
1196 Please enable it in your Mercurial config file.
1182 [255]
1197 [255]
1183
1198
1184 used all HGPORTs, kill all daemons
1199 used all HGPORTs, kill all daemons
1185 $ "$TESTDIR/killdaemons.py"
1200 $ "$TESTDIR/killdaemons.py"
1186 #endif
1201 #endif
1187
1202
1188 vanilla clients locked out from largefiles ssh repos
1203 vanilla clients locked out from largefiles ssh repos
1189 $ hg --config extensions.largefiles=! clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/r4 r5
1204 $ hg --config extensions.largefiles=! clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/r4 r5
1190 abort: remote error:
1205 abort: remote error:
1191
1206
1192 This repository uses the largefiles extension.
1207 This repository uses the largefiles extension.
1193
1208
1194 Please enable it in your Mercurial config file.
1209 Please enable it in your Mercurial config file.
1195 [255]
1210 [255]
1196
1211
1197 #if serve
1212 #if serve
1198
1213
1199 largefiles clients refuse to push largefiles repos to vanilla servers
1214 largefiles clients refuse to push largefiles repos to vanilla servers
1200 $ mkdir r6
1215 $ mkdir r6
1201 $ cd r6
1216 $ cd r6
1202 $ hg init
1217 $ hg init
1203 $ echo c1 > f1
1218 $ echo c1 > f1
1204 $ hg add f1
1219 $ hg add f1
1205 $ hg commit -m "m1"
1220 $ hg commit -m "m1"
1206 Invoking status precommit hook
1221 Invoking status precommit hook
1207 A f1
1222 A f1
1208 $ cat >> .hg/hgrc <<!
1223 $ cat >> .hg/hgrc <<!
1209 > [web]
1224 > [web]
1210 > push_ssl = false
1225 > push_ssl = false
1211 > allow_push = *
1226 > allow_push = *
1212 > !
1227 > !
1213 $ cd ..
1228 $ cd ..
1214 $ hg clone r6 r7
1229 $ hg clone r6 r7
1215 updating to branch default
1230 updating to branch default
1216 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1231 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1217 $ cd r7
1232 $ cd r7
1218 $ echo c2 > f2
1233 $ echo c2 > f2
1219 $ hg add --large f2
1234 $ hg add --large f2
1220 $ hg commit -m "m2"
1235 $ hg commit -m "m2"
1221 Invoking status precommit hook
1236 Invoking status precommit hook
1222 A f2
1237 A f2
1223 $ hg --config extensions.largefiles=! -R ../r6 serve -d -p $HGPORT --pid-file ../hg.pid
1238 $ hg --config extensions.largefiles=! -R ../r6 serve -d -p $HGPORT --pid-file ../hg.pid
1224 $ cat ../hg.pid >> $DAEMON_PIDS
1239 $ cat ../hg.pid >> $DAEMON_PIDS
1225 $ hg push http://localhost:$HGPORT
1240 $ hg push http://localhost:$HGPORT
1226 pushing to http://localhost:$HGPORT/
1241 pushing to http://localhost:$HGPORT/
1227 searching for changes
1242 searching for changes
1228 abort: http://localhost:$HGPORT/ does not appear to be a largefile store
1243 abort: http://localhost:$HGPORT/ does not appear to be a largefile store
1229 [255]
1244 [255]
1230 $ cd ..
1245 $ cd ..
1231
1246
1232 putlfile errors are shown (issue3123)
1247 putlfile errors are shown (issue3123)
1233 Corrupt the cached largefile in r7 and in the usercache (required for testing on vfat)
1248 Corrupt the cached largefile in r7 and in the usercache (required for testing on vfat)
1234 $ echo corruption > "$TESTTMP/r7/.hg/largefiles/4cdac4d8b084d0b599525cf732437fb337d422a8"
1249 $ echo corruption > "$TESTTMP/r7/.hg/largefiles/4cdac4d8b084d0b599525cf732437fb337d422a8"
1235 $ echo corruption > "$USERCACHE/4cdac4d8b084d0b599525cf732437fb337d422a8"
1250 $ echo corruption > "$USERCACHE/4cdac4d8b084d0b599525cf732437fb337d422a8"
1236 $ hg init empty
1251 $ hg init empty
1237 $ hg serve -R empty -d -p $HGPORT1 --pid-file hg.pid \
1252 $ hg serve -R empty -d -p $HGPORT1 --pid-file hg.pid \
1238 > --config 'web.allow_push=*' --config web.push_ssl=False
1253 > --config 'web.allow_push=*' --config web.push_ssl=False
1239 $ cat hg.pid >> $DAEMON_PIDS
1254 $ cat hg.pid >> $DAEMON_PIDS
1240 $ hg push -R r7 http://localhost:$HGPORT1
1255 $ hg push -R r7 http://localhost:$HGPORT1
1241 pushing to http://localhost:$HGPORT1/
1256 pushing to http://localhost:$HGPORT1/
1242 searching for changes
1257 searching for changes
1243 remote: largefiles: failed to put 4cdac4d8b084d0b599525cf732437fb337d422a8 into store: largefile contents do not match hash
1258 remote: largefiles: failed to put 4cdac4d8b084d0b599525cf732437fb337d422a8 into store: largefile contents do not match hash
1244 abort: remotestore: could not put $TESTTMP/r7/.hg/largefiles/4cdac4d8b084d0b599525cf732437fb337d422a8 to remote store http://localhost:$HGPORT1/ (glob)
1259 abort: remotestore: could not put $TESTTMP/r7/.hg/largefiles/4cdac4d8b084d0b599525cf732437fb337d422a8 to remote store http://localhost:$HGPORT1/ (glob)
1245 [255]
1260 [255]
1246 $ rm -rf empty
1261 $ rm -rf empty
1247
1262
1248 Push a largefiles repository to a served empty repository
1263 Push a largefiles repository to a served empty repository
1249 $ hg init r8
1264 $ hg init r8
1250 $ echo c3 > r8/f1
1265 $ echo c3 > r8/f1
1251 $ hg add --large r8/f1 -R r8
1266 $ hg add --large r8/f1 -R r8
1252 $ hg commit -m "m1" -R r8
1267 $ hg commit -m "m1" -R r8
1253 Invoking status precommit hook
1268 Invoking status precommit hook
1254 A f1
1269 A f1
1255 $ hg init empty
1270 $ hg init empty
1256 $ hg serve -R empty -d -p $HGPORT2 --pid-file hg.pid \
1271 $ hg serve -R empty -d -p $HGPORT2 --pid-file hg.pid \
1257 > --config 'web.allow_push=*' --config web.push_ssl=False
1272 > --config 'web.allow_push=*' --config web.push_ssl=False
1258 $ cat hg.pid >> $DAEMON_PIDS
1273 $ cat hg.pid >> $DAEMON_PIDS
1259 $ rm "${USERCACHE}"/*
1274 $ rm "${USERCACHE}"/*
1260 $ hg push -R r8 http://localhost:$HGPORT2
1275 $ hg push -R r8 http://localhost:$HGPORT2
1261 pushing to http://localhost:$HGPORT2/
1276 pushing to http://localhost:$HGPORT2/
1262 searching for changes
1277 searching for changes
1263 searching for changes
1278 searching for changes
1264 remote: adding changesets
1279 remote: adding changesets
1265 remote: adding manifests
1280 remote: adding manifests
1266 remote: adding file changes
1281 remote: adding file changes
1267 remote: added 1 changesets with 1 changes to 1 files
1282 remote: added 1 changesets with 1 changes to 1 files
1268 $ rm -rf empty
1283 $ rm -rf empty
1269
1284
1270 used all HGPORTs, kill all daemons
1285 used all HGPORTs, kill all daemons
1271 $ "$TESTDIR/killdaemons.py"
1286 $ "$TESTDIR/killdaemons.py"
1272
1287
1273 #endif
1288 #endif
1274
1289
1275
1290
1276 #if unix-permissions
1291 #if unix-permissions
1277
1292
1278 Clone a local repository owned by another user
1293 Clone a local repository owned by another user
1279 We have to simulate that here by setting $HOME and removing write permissions
1294 We have to simulate that here by setting $HOME and removing write permissions
1280 $ ORIGHOME="$HOME"
1295 $ ORIGHOME="$HOME"
1281 $ mkdir alice
1296 $ mkdir alice
1282 $ HOME="`pwd`/alice"
1297 $ HOME="`pwd`/alice"
1283 $ cd alice
1298 $ cd alice
1284 $ hg init pubrepo
1299 $ hg init pubrepo
1285 $ cd pubrepo
1300 $ cd pubrepo
1286 $ dd if=/dev/zero bs=1k count=11k > a-large-file 2> /dev/null
1301 $ dd if=/dev/zero bs=1k count=11k > a-large-file 2> /dev/null
1287 $ hg add --large a-large-file
1302 $ hg add --large a-large-file
1288 $ hg commit -m "Add a large file"
1303 $ hg commit -m "Add a large file"
1289 Invoking status precommit hook
1304 Invoking status precommit hook
1290 A a-large-file
1305 A a-large-file
1291 $ cd ..
1306 $ cd ..
1292 $ chmod -R a-w pubrepo
1307 $ chmod -R a-w pubrepo
1293 $ cd ..
1308 $ cd ..
1294 $ mkdir bob
1309 $ mkdir bob
1295 $ HOME="`pwd`/bob"
1310 $ HOME="`pwd`/bob"
1296 $ cd bob
1311 $ cd bob
1297 $ hg clone --pull ../alice/pubrepo pubrepo
1312 $ hg clone --pull ../alice/pubrepo pubrepo
1298 requesting all changes
1313 requesting all changes
1299 adding changesets
1314 adding changesets
1300 adding manifests
1315 adding manifests
1301 adding file changes
1316 adding file changes
1302 added 1 changesets with 1 changes to 1 files
1317 added 1 changesets with 1 changes to 1 files
1303 updating to branch default
1318 updating to branch default
1304 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1319 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1305 getting changed largefiles
1320 getting changed largefiles
1306 1 largefiles updated, 0 removed
1321 1 largefiles updated, 0 removed
1307 $ cd ..
1322 $ cd ..
1308 $ chmod -R u+w alice/pubrepo
1323 $ chmod -R u+w alice/pubrepo
1309 $ HOME="$ORIGHOME"
1324 $ HOME="$ORIGHOME"
1310
1325
1311 #endif
1326 #endif
1312
1327
1313 #if symlink
1328 #if symlink
1314
1329
1315 Symlink to a large largefile should behave the same as a symlink to a normal file
1330 Symlink to a large largefile should behave the same as a symlink to a normal file
1316 $ hg init largesymlink
1331 $ hg init largesymlink
1317 $ cd largesymlink
1332 $ cd largesymlink
1318 $ dd if=/dev/zero bs=1k count=10k of=largefile 2>/dev/null
1333 $ dd if=/dev/zero bs=1k count=10k of=largefile 2>/dev/null
1319 $ hg add --large largefile
1334 $ hg add --large largefile
1320 $ hg commit -m "commit a large file"
1335 $ hg commit -m "commit a large file"
1321 Invoking status precommit hook
1336 Invoking status precommit hook
1322 A largefile
1337 A largefile
1323 $ ln -s largefile largelink
1338 $ ln -s largefile largelink
1324 $ hg add largelink
1339 $ hg add largelink
1325 $ hg commit -m "commit a large symlink"
1340 $ hg commit -m "commit a large symlink"
1326 Invoking status precommit hook
1341 Invoking status precommit hook
1327 A largelink
1342 A largelink
1328 $ rm -f largelink
1343 $ rm -f largelink
1329 $ hg up >/dev/null
1344 $ hg up >/dev/null
1330 $ test -f largelink
1345 $ test -f largelink
1331 [1]
1346 [1]
1332 $ test -L largelink
1347 $ test -L largelink
1333 [1]
1348 [1]
1334 $ rm -f largelink # make next part of the test independent of the previous
1349 $ rm -f largelink # make next part of the test independent of the previous
1335 $ hg up -C >/dev/null
1350 $ hg up -C >/dev/null
1336 $ test -f largelink
1351 $ test -f largelink
1337 $ test -L largelink
1352 $ test -L largelink
1338 $ cd ..
1353 $ cd ..
1339
1354
1340 #endif
1355 #endif
1341
1356
1342 test for pattern matching on 'hg status':
1357 test for pattern matching on 'hg status':
1343 to boost performance, largefiles checks whether specified patterns are
1358 to boost performance, largefiles checks whether specified patterns are
1344 related to largefiles in working directory (NOT to STANDIN) or not.
1359 related to largefiles in working directory (NOT to STANDIN) or not.
1345
1360
1346 $ hg init statusmatch
1361 $ hg init statusmatch
1347 $ cd statusmatch
1362 $ cd statusmatch
1348
1363
1349 $ mkdir -p a/b/c/d
1364 $ mkdir -p a/b/c/d
1350 $ echo normal > a/b/c/d/e.normal.txt
1365 $ echo normal > a/b/c/d/e.normal.txt
1351 $ hg add a/b/c/d/e.normal.txt
1366 $ hg add a/b/c/d/e.normal.txt
1352 $ echo large > a/b/c/d/e.large.txt
1367 $ echo large > a/b/c/d/e.large.txt
1353 $ hg add --large a/b/c/d/e.large.txt
1368 $ hg add --large a/b/c/d/e.large.txt
1354 $ mkdir -p a/b/c/x
1369 $ mkdir -p a/b/c/x
1355 $ echo normal > a/b/c/x/y.normal.txt
1370 $ echo normal > a/b/c/x/y.normal.txt
1356 $ hg add a/b/c/x/y.normal.txt
1371 $ hg add a/b/c/x/y.normal.txt
1357 $ hg commit -m 'add files'
1372 $ hg commit -m 'add files'
1358 Invoking status precommit hook
1373 Invoking status precommit hook
1359 A a/b/c/d/e.large.txt
1374 A a/b/c/d/e.large.txt
1360 A a/b/c/d/e.normal.txt
1375 A a/b/c/d/e.normal.txt
1361 A a/b/c/x/y.normal.txt
1376 A a/b/c/x/y.normal.txt
1362
1377
1363 (1) no pattern: no performance boost
1378 (1) no pattern: no performance boost
1364 $ hg status -A
1379 $ hg status -A
1365 C a/b/c/d/e.large.txt
1380 C a/b/c/d/e.large.txt
1366 C a/b/c/d/e.normal.txt
1381 C a/b/c/d/e.normal.txt
1367 C a/b/c/x/y.normal.txt
1382 C a/b/c/x/y.normal.txt
1368
1383
1369 (2) pattern not related to largefiles: performance boost
1384 (2) pattern not related to largefiles: performance boost
1370 $ hg status -A a/b/c/x
1385 $ hg status -A a/b/c/x
1371 C a/b/c/x/y.normal.txt
1386 C a/b/c/x/y.normal.txt
1372
1387
1373 (3) pattern related to largefiles: no performance boost
1388 (3) pattern related to largefiles: no performance boost
1374 $ hg status -A a/b/c/d
1389 $ hg status -A a/b/c/d
1375 C a/b/c/d/e.large.txt
1390 C a/b/c/d/e.large.txt
1376 C a/b/c/d/e.normal.txt
1391 C a/b/c/d/e.normal.txt
1377
1392
1378 (4) pattern related to STANDIN (not to largefiles): performance boost
1393 (4) pattern related to STANDIN (not to largefiles): performance boost
1379 $ hg status -A .hglf/a
1394 $ hg status -A .hglf/a
1380 C .hglf/a/b/c/d/e.large.txt
1395 C .hglf/a/b/c/d/e.large.txt
1381
1396
1382 (5) mixed case: no performance boost
1397 (5) mixed case: no performance boost
1383 $ hg status -A a/b/c/x a/b/c/d
1398 $ hg status -A a/b/c/x a/b/c/d
1384 C a/b/c/d/e.large.txt
1399 C a/b/c/d/e.large.txt
1385 C a/b/c/d/e.normal.txt
1400 C a/b/c/d/e.normal.txt
1386 C a/b/c/x/y.normal.txt
1401 C a/b/c/x/y.normal.txt
1387
1402
1388 verify that largefiles doesn't break filesets
1403 verify that largefiles doesn't break filesets
1389
1404
1390 $ hg log --rev . --exclude "set:binary()"
1405 $ hg log --rev . --exclude "set:binary()"
1391 changeset: 0:41bd42f10efa
1406 changeset: 0:41bd42f10efa
1392 tag: tip
1407 tag: tip
1393 user: test
1408 user: test
1394 date: Thu Jan 01 00:00:00 1970 +0000
1409 date: Thu Jan 01 00:00:00 1970 +0000
1395 summary: add files
1410 summary: add files
1396
1411
1397 verify that large files in subrepos handled properly
1412 verify that large files in subrepos handled properly
1398 $ hg init subrepo
1413 $ hg init subrepo
1399 $ echo "subrepo = subrepo" > .hgsub
1414 $ echo "subrepo = subrepo" > .hgsub
1400 $ hg add .hgsub
1415 $ hg add .hgsub
1401 $ hg ci -m "add subrepo"
1416 $ hg ci -m "add subrepo"
1402 Invoking status precommit hook
1417 Invoking status precommit hook
1403 A .hgsub
1418 A .hgsub
1404 ? .hgsubstate
1419 ? .hgsubstate
1405 $ echo "rev 1" > subrepo/large.txt
1420 $ echo "rev 1" > subrepo/large.txt
1406 $ hg -R subrepo add --large subrepo/large.txt
1421 $ hg -R subrepo add --large subrepo/large.txt
1407 $ hg sum
1422 $ hg sum
1408 parent: 1:8ee150ea2e9c tip
1423 parent: 1:8ee150ea2e9c tip
1409 add subrepo
1424 add subrepo
1410 branch: default
1425 branch: default
1411 commit: 1 subrepos
1426 commit: 1 subrepos
1412 update: (current)
1427 update: (current)
1413 $ hg st
1428 $ hg st
1414 $ hg st -S
1429 $ hg st -S
1415 A subrepo/large.txt
1430 A subrepo/large.txt
1416 $ hg ci -S -m "commit top repo"
1431 $ hg ci -S -m "commit top repo"
1417 committing subrepository subrepo
1432 committing subrepository subrepo
1418 Invoking status precommit hook
1433 Invoking status precommit hook
1419 A large.txt
1434 A large.txt
1420 Invoking status precommit hook
1435 Invoking status precommit hook
1421 M .hgsubstate
1436 M .hgsubstate
1422 # No differences
1437 # No differences
1423 $ hg st -S
1438 $ hg st -S
1424 $ hg sum
1439 $ hg sum
1425 parent: 2:ce4cd0c527a6 tip
1440 parent: 2:ce4cd0c527a6 tip
1426 commit top repo
1441 commit top repo
1427 branch: default
1442 branch: default
1428 commit: (clean)
1443 commit: (clean)
1429 update: (current)
1444 update: (current)
1430 $ echo "rev 2" > subrepo/large.txt
1445 $ echo "rev 2" > subrepo/large.txt
1431 $ hg st -S
1446 $ hg st -S
1432 M subrepo/large.txt
1447 M subrepo/large.txt
1433 $ hg sum
1448 $ hg sum
1434 parent: 2:ce4cd0c527a6 tip
1449 parent: 2:ce4cd0c527a6 tip
1435 commit top repo
1450 commit top repo
1436 branch: default
1451 branch: default
1437 commit: 1 subrepos
1452 commit: 1 subrepos
1438 update: (current)
1453 update: (current)
1439 $ hg ci -m "this commit should fail without -S"
1454 $ hg ci -m "this commit should fail without -S"
1440 abort: uncommitted changes in subrepo subrepo
1455 abort: uncommitted changes in subrepo subrepo
1441 (use --subrepos for recursive commit)
1456 (use --subrepos for recursive commit)
1442 [255]
1457 [255]
1443
1458
1444 Add a normal file to the subrepo, then test archiving
1459 Add a normal file to the subrepo, then test archiving
1445
1460
1446 $ echo 'normal file' > subrepo/normal.txt
1461 $ echo 'normal file' > subrepo/normal.txt
1447 $ hg -R subrepo add subrepo/normal.txt
1462 $ hg -R subrepo add subrepo/normal.txt
1448
1463
1449 Lock in subrepo, otherwise the change isn't archived
1464 Lock in subrepo, otherwise the change isn't archived
1450
1465
1451 $ hg ci -S -m "add normal file to top level"
1466 $ hg ci -S -m "add normal file to top level"
1452 committing subrepository subrepo
1467 committing subrepository subrepo
1453 Invoking status precommit hook
1468 Invoking status precommit hook
1454 M large.txt
1469 M large.txt
1455 A normal.txt
1470 A normal.txt
1456 Invoking status precommit hook
1471 Invoking status precommit hook
1457 M .hgsubstate
1472 M .hgsubstate
1458 $ hg archive -S lf_subrepo_archive
1473 $ hg archive -S lf_subrepo_archive
1459 $ find lf_subrepo_archive | sort
1474 $ find lf_subrepo_archive | sort
1460 lf_subrepo_archive
1475 lf_subrepo_archive
1461 lf_subrepo_archive/.hg_archival.txt
1476 lf_subrepo_archive/.hg_archival.txt
1462 lf_subrepo_archive/.hgsub
1477 lf_subrepo_archive/.hgsub
1463 lf_subrepo_archive/.hgsubstate
1478 lf_subrepo_archive/.hgsubstate
1464 lf_subrepo_archive/a
1479 lf_subrepo_archive/a
1465 lf_subrepo_archive/a/b
1480 lf_subrepo_archive/a/b
1466 lf_subrepo_archive/a/b/c
1481 lf_subrepo_archive/a/b/c
1467 lf_subrepo_archive/a/b/c/d
1482 lf_subrepo_archive/a/b/c/d
1468 lf_subrepo_archive/a/b/c/d/e.large.txt
1483 lf_subrepo_archive/a/b/c/d/e.large.txt
1469 lf_subrepo_archive/a/b/c/d/e.normal.txt
1484 lf_subrepo_archive/a/b/c/d/e.normal.txt
1470 lf_subrepo_archive/a/b/c/x
1485 lf_subrepo_archive/a/b/c/x
1471 lf_subrepo_archive/a/b/c/x/y.normal.txt
1486 lf_subrepo_archive/a/b/c/x/y.normal.txt
1472 lf_subrepo_archive/subrepo
1487 lf_subrepo_archive/subrepo
1473 lf_subrepo_archive/subrepo/large.txt
1488 lf_subrepo_archive/subrepo/large.txt
1474 lf_subrepo_archive/subrepo/normal.txt
1489 lf_subrepo_archive/subrepo/normal.txt
1475
1490
1476 $ cd ..
1491 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now