##// END OF EJS Templates
largefiles: suppress unexpected warning of 'hg status' for removed files...
FUJIWARA Katsunori -
r16281:d8cc6711 stable
parent child Browse files
Show More
@@ -1,458 +1,458 b''
1 # Copyright 2009-2010 Gregory P. Ward
1 # Copyright 2009-2010 Gregory P. Ward
2 # Copyright 2009-2010 Intelerad Medical Systems Incorporated
2 # Copyright 2009-2010 Intelerad Medical Systems Incorporated
3 # Copyright 2010-2011 Fog Creek Software
3 # Copyright 2010-2011 Fog Creek Software
4 # Copyright 2010-2011 Unity Technologies
4 # Copyright 2010-2011 Unity Technologies
5 #
5 #
6 # This software may be used and distributed according to the terms of the
6 # This software may be used and distributed according to the terms of the
7 # GNU General Public License version 2 or any later version.
7 # GNU General Public License version 2 or any later version.
8
8
9 '''setup for largefiles repositories: reposetup'''
9 '''setup for largefiles repositories: reposetup'''
10 import copy
10 import copy
11 import types
11 import types
12 import os
12 import os
13
13
14 from mercurial import context, error, manifest, match as match_, util
14 from mercurial import context, error, manifest, match as match_, util
15 from mercurial import node as node_
15 from mercurial import node as node_
16 from mercurial.i18n import _
16 from mercurial.i18n import _
17
17
18 import lfcommands
18 import lfcommands
19 import proto
19 import proto
20 import lfutil
20 import lfutil
21
21
22 def reposetup(ui, repo):
22 def reposetup(ui, repo):
23 # wire repositories should be given new wireproto functions but not the
23 # wire repositories should be given new wireproto functions but not the
24 # other largefiles modifications
24 # other largefiles modifications
25 if not repo.local():
25 if not repo.local():
26 return proto.wirereposetup(ui, repo)
26 return proto.wirereposetup(ui, repo)
27
27
28 for name in ('status', 'commitctx', 'commit', 'push'):
28 for name in ('status', 'commitctx', 'commit', 'push'):
29 method = getattr(repo, name)
29 method = getattr(repo, name)
30 if (isinstance(method, types.FunctionType) and
30 if (isinstance(method, types.FunctionType) and
31 method.func_name == 'wrap'):
31 method.func_name == 'wrap'):
32 ui.warn(_('largefiles: repo method %r appears to have already been'
32 ui.warn(_('largefiles: repo method %r appears to have already been'
33 ' wrapped by another extension: '
33 ' wrapped by another extension: '
34 'largefiles may behave incorrectly\n')
34 'largefiles may behave incorrectly\n')
35 % name)
35 % name)
36
36
37 class lfiles_repo(repo.__class__):
37 class lfiles_repo(repo.__class__):
38 lfstatus = False
38 lfstatus = False
39 def status_nolfiles(self, *args, **kwargs):
39 def status_nolfiles(self, *args, **kwargs):
40 return super(lfiles_repo, self).status(*args, **kwargs)
40 return super(lfiles_repo, self).status(*args, **kwargs)
41
41
42 # When lfstatus is set, return a context that gives the names
42 # When lfstatus is set, return a context that gives the names
43 # of largefiles instead of their corresponding standins and
43 # of largefiles instead of their corresponding standins and
44 # identifies the largefiles as always binary, regardless of
44 # identifies the largefiles as always binary, regardless of
45 # their actual contents.
45 # their actual contents.
46 def __getitem__(self, changeid):
46 def __getitem__(self, changeid):
47 ctx = super(lfiles_repo, self).__getitem__(changeid)
47 ctx = super(lfiles_repo, self).__getitem__(changeid)
48 if self.lfstatus:
48 if self.lfstatus:
49 class lfiles_manifestdict(manifest.manifestdict):
49 class lfiles_manifestdict(manifest.manifestdict):
50 def __contains__(self, filename):
50 def __contains__(self, filename):
51 if super(lfiles_manifestdict,
51 if super(lfiles_manifestdict,
52 self).__contains__(filename):
52 self).__contains__(filename):
53 return True
53 return True
54 return super(lfiles_manifestdict,
54 return super(lfiles_manifestdict,
55 self).__contains__(lfutil.standin(filename))
55 self).__contains__(lfutil.standin(filename))
56 class lfiles_ctx(ctx.__class__):
56 class lfiles_ctx(ctx.__class__):
57 def files(self):
57 def files(self):
58 filenames = super(lfiles_ctx, self).files()
58 filenames = super(lfiles_ctx, self).files()
59 return [lfutil.splitstandin(f) or f for f in filenames]
59 return [lfutil.splitstandin(f) or f for f in filenames]
60 def manifest(self):
60 def manifest(self):
61 man1 = super(lfiles_ctx, self).manifest()
61 man1 = super(lfiles_ctx, self).manifest()
62 man1.__class__ = lfiles_manifestdict
62 man1.__class__ = lfiles_manifestdict
63 return man1
63 return man1
64 def filectx(self, path, fileid=None, filelog=None):
64 def filectx(self, path, fileid=None, filelog=None):
65 try:
65 try:
66 if filelog is not None:
66 if filelog is not None:
67 result = super(lfiles_ctx, self).filectx(
67 result = super(lfiles_ctx, self).filectx(
68 path, fileid, filelog)
68 path, fileid, filelog)
69 else:
69 else:
70 result = super(lfiles_ctx, self).filectx(
70 result = super(lfiles_ctx, self).filectx(
71 path, fileid)
71 path, fileid)
72 except error.LookupError:
72 except error.LookupError:
73 # Adding a null character will cause Mercurial to
73 # Adding a null character will cause Mercurial to
74 # identify this as a binary file.
74 # identify this as a binary file.
75 if filelog is not None:
75 if filelog is not None:
76 result = super(lfiles_ctx, self).filectx(
76 result = super(lfiles_ctx, self).filectx(
77 lfutil.standin(path), fileid, filelog)
77 lfutil.standin(path), fileid, filelog)
78 else:
78 else:
79 result = super(lfiles_ctx, self).filectx(
79 result = super(lfiles_ctx, self).filectx(
80 lfutil.standin(path), fileid)
80 lfutil.standin(path), fileid)
81 olddata = result.data
81 olddata = result.data
82 result.data = lambda: olddata() + '\0'
82 result.data = lambda: olddata() + '\0'
83 return result
83 return result
84 ctx.__class__ = lfiles_ctx
84 ctx.__class__ = lfiles_ctx
85 return ctx
85 return ctx
86
86
87 # Figure out the status of big files and insert them into the
87 # Figure out the status of big files and insert them into the
88 # appropriate list in the result. Also removes standin files
88 # appropriate list in the result. Also removes standin files
89 # from the listing. Revert to the original status if
89 # from the listing. Revert to the original status if
90 # self.lfstatus is False.
90 # self.lfstatus is False.
91 def status(self, node1='.', node2=None, match=None, ignored=False,
91 def status(self, node1='.', node2=None, match=None, ignored=False,
92 clean=False, unknown=False, listsubrepos=False):
92 clean=False, unknown=False, listsubrepos=False):
93 listignored, listclean, listunknown = ignored, clean, unknown
93 listignored, listclean, listunknown = ignored, clean, unknown
94 if not self.lfstatus:
94 if not self.lfstatus:
95 return super(lfiles_repo, self).status(node1, node2, match,
95 return super(lfiles_repo, self).status(node1, node2, match,
96 listignored, listclean, listunknown, listsubrepos)
96 listignored, listclean, listunknown, listsubrepos)
97 else:
97 else:
98 # some calls in this function rely on the old version of status
98 # some calls in this function rely on the old version of status
99 self.lfstatus = False
99 self.lfstatus = False
100 if isinstance(node1, context.changectx):
100 if isinstance(node1, context.changectx):
101 ctx1 = node1
101 ctx1 = node1
102 else:
102 else:
103 ctx1 = repo[node1]
103 ctx1 = repo[node1]
104 if isinstance(node2, context.changectx):
104 if isinstance(node2, context.changectx):
105 ctx2 = node2
105 ctx2 = node2
106 else:
106 else:
107 ctx2 = repo[node2]
107 ctx2 = repo[node2]
108 working = ctx2.rev() is None
108 working = ctx2.rev() is None
109 parentworking = working and ctx1 == self['.']
109 parentworking = working and ctx1 == self['.']
110
110
111 def inctx(file, ctx):
111 def inctx(file, ctx):
112 try:
112 try:
113 if ctx.rev() is None:
113 if ctx.rev() is None:
114 return file in ctx.manifest()
114 return file in ctx.manifest()
115 ctx[file]
115 ctx[file]
116 return True
116 return True
117 except KeyError:
117 except KeyError:
118 return False
118 return False
119
119
120 if match is None:
120 if match is None:
121 match = match_.always(self.root, self.getcwd())
121 match = match_.always(self.root, self.getcwd())
122
122
123 # First check if there were files specified on the
123 # First check if there were files specified on the
124 # command line. If there were, and none of them were
124 # command line. If there were, and none of them were
125 # largefiles, we should just bail here and let super
125 # largefiles, we should just bail here and let super
126 # handle it -- thus gaining a big performance boost.
126 # handle it -- thus gaining a big performance boost.
127 lfdirstate = lfutil.openlfdirstate(ui, self)
127 lfdirstate = lfutil.openlfdirstate(ui, self)
128 if match.files() and not match.anypats():
128 if match.files() and not match.anypats():
129 for f in lfdirstate:
129 for f in lfdirstate:
130 if match(f):
130 if match(f):
131 break
131 break
132 else:
132 else:
133 return super(lfiles_repo, self).status(node1, node2,
133 return super(lfiles_repo, self).status(node1, node2,
134 match, listignored, listclean,
134 match, listignored, listclean,
135 listunknown, listsubrepos)
135 listunknown, listsubrepos)
136
136
137 # Create a copy of match that matches standins instead
137 # Create a copy of match that matches standins instead
138 # of largefiles.
138 # of largefiles.
139 def tostandin(file):
139 def tostandin(file):
140 if inctx(lfutil.standin(file), ctx2):
140 if working and lfutil.standin(file) in repo.dirstate:
141 return lfutil.standin(file)
141 return lfutil.standin(file)
142 return file
142 return file
143
143
144 # Create a function that we can use to override what is
144 # Create a function that we can use to override what is
145 # normally the ignore matcher. We've already checked
145 # normally the ignore matcher. We've already checked
146 # for ignored files on the first dirstate walk, and
146 # for ignored files on the first dirstate walk, and
147 # unecessarily re-checking here causes a huge performance
147 # unecessarily re-checking here causes a huge performance
148 # hit because lfdirstate only knows about largefiles
148 # hit because lfdirstate only knows about largefiles
149 def _ignoreoverride(self):
149 def _ignoreoverride(self):
150 return False
150 return False
151
151
152 m = copy.copy(match)
152 m = copy.copy(match)
153 m._files = [tostandin(f) for f in m._files]
153 m._files = [tostandin(f) for f in m._files]
154
154
155 # Get ignored files here even if we weren't asked for them; we
155 # Get ignored files here even if we weren't asked for them; we
156 # must use the result here for filtering later
156 # must use the result here for filtering later
157 result = super(lfiles_repo, self).status(node1, node2, m,
157 result = super(lfiles_repo, self).status(node1, node2, m,
158 True, clean, unknown, listsubrepos)
158 True, clean, unknown, listsubrepos)
159 if working:
159 if working:
160 try:
160 try:
161 # Any non-largefiles that were explicitly listed must be
161 # Any non-largefiles that were explicitly listed must be
162 # taken out or lfdirstate.status will report an error.
162 # taken out or lfdirstate.status will report an error.
163 # The status of these files was already computed using
163 # The status of these files was already computed using
164 # super's status.
164 # super's status.
165 # Override lfdirstate's ignore matcher to not do
165 # Override lfdirstate's ignore matcher to not do
166 # anything
166 # anything
167 orig_ignore = lfdirstate._ignore
167 orig_ignore = lfdirstate._ignore
168 lfdirstate._ignore = _ignoreoverride
168 lfdirstate._ignore = _ignoreoverride
169
169
170 match._files = [f for f in match._files if f in
170 match._files = [f for f in match._files if f in
171 lfdirstate]
171 lfdirstate]
172 # Don't waste time getting the ignored and unknown
172 # Don't waste time getting the ignored and unknown
173 # files again; we already have them
173 # files again; we already have them
174 s = lfdirstate.status(match, [], False,
174 s = lfdirstate.status(match, [], False,
175 listclean, False)
175 listclean, False)
176 (unsure, modified, added, removed, missing, unknown,
176 (unsure, modified, added, removed, missing, unknown,
177 ignored, clean) = s
177 ignored, clean) = s
178 # Replace the list of ignored and unknown files with
178 # Replace the list of ignored and unknown files with
179 # the previously caclulated lists, and strip out the
179 # the previously caclulated lists, and strip out the
180 # largefiles
180 # largefiles
181 lfiles = set(lfdirstate._map)
181 lfiles = set(lfdirstate._map)
182 ignored = set(result[5]).difference(lfiles)
182 ignored = set(result[5]).difference(lfiles)
183 unknown = set(result[4]).difference(lfiles)
183 unknown = set(result[4]).difference(lfiles)
184 if parentworking:
184 if parentworking:
185 for lfile in unsure:
185 for lfile in unsure:
186 standin = lfutil.standin(lfile)
186 standin = lfutil.standin(lfile)
187 if standin not in ctx1:
187 if standin not in ctx1:
188 # from second parent
188 # from second parent
189 modified.append(lfile)
189 modified.append(lfile)
190 elif ctx1[standin].data().strip() \
190 elif ctx1[standin].data().strip() \
191 != lfutil.hashfile(self.wjoin(lfile)):
191 != lfutil.hashfile(self.wjoin(lfile)):
192 modified.append(lfile)
192 modified.append(lfile)
193 else:
193 else:
194 clean.append(lfile)
194 clean.append(lfile)
195 lfdirstate.normal(lfile)
195 lfdirstate.normal(lfile)
196 else:
196 else:
197 tocheck = unsure + modified + added + clean
197 tocheck = unsure + modified + added + clean
198 modified, added, clean = [], [], []
198 modified, added, clean = [], [], []
199
199
200 for lfile in tocheck:
200 for lfile in tocheck:
201 standin = lfutil.standin(lfile)
201 standin = lfutil.standin(lfile)
202 if inctx(standin, ctx1):
202 if inctx(standin, ctx1):
203 if ctx1[standin].data().strip() != \
203 if ctx1[standin].data().strip() != \
204 lfutil.hashfile(self.wjoin(lfile)):
204 lfutil.hashfile(self.wjoin(lfile)):
205 modified.append(lfile)
205 modified.append(lfile)
206 else:
206 else:
207 clean.append(lfile)
207 clean.append(lfile)
208 else:
208 else:
209 added.append(lfile)
209 added.append(lfile)
210 finally:
210 finally:
211 # Replace the original ignore function
211 # Replace the original ignore function
212 lfdirstate._ignore = orig_ignore
212 lfdirstate._ignore = orig_ignore
213
213
214 for standin in ctx1.manifest():
214 for standin in ctx1.manifest():
215 if not lfutil.isstandin(standin):
215 if not lfutil.isstandin(standin):
216 continue
216 continue
217 lfile = lfutil.splitstandin(standin)
217 lfile = lfutil.splitstandin(standin)
218 if not match(lfile):
218 if not match(lfile):
219 continue
219 continue
220 if lfile not in lfdirstate:
220 if lfile not in lfdirstate:
221 removed.append(lfile)
221 removed.append(lfile)
222
222
223 # Filter result lists
223 # Filter result lists
224 result = list(result)
224 result = list(result)
225
225
226 # Largefiles are not really removed when they're
226 # Largefiles are not really removed when they're
227 # still in the normal dirstate. Likewise, normal
227 # still in the normal dirstate. Likewise, normal
228 # files are not really removed if it's still in
228 # files are not really removed if it's still in
229 # lfdirstate. This happens in merges where files
229 # lfdirstate. This happens in merges where files
230 # change type.
230 # change type.
231 removed = [f for f in removed if f not in repo.dirstate]
231 removed = [f for f in removed if f not in repo.dirstate]
232 result[2] = [f for f in result[2] if f not in lfdirstate]
232 result[2] = [f for f in result[2] if f not in lfdirstate]
233
233
234 # Unknown files
234 # Unknown files
235 unknown = set(unknown).difference(ignored)
235 unknown = set(unknown).difference(ignored)
236 result[4] = [f for f in unknown
236 result[4] = [f for f in unknown
237 if (repo.dirstate[f] == '?' and
237 if (repo.dirstate[f] == '?' and
238 not lfutil.isstandin(f))]
238 not lfutil.isstandin(f))]
239 # Ignored files were calculated earlier by the dirstate,
239 # Ignored files were calculated earlier by the dirstate,
240 # and we already stripped out the largefiles from the list
240 # and we already stripped out the largefiles from the list
241 result[5] = ignored
241 result[5] = ignored
242 # combine normal files and largefiles
242 # combine normal files and largefiles
243 normals = [[fn for fn in filelist
243 normals = [[fn for fn in filelist
244 if not lfutil.isstandin(fn)]
244 if not lfutil.isstandin(fn)]
245 for filelist in result]
245 for filelist in result]
246 lfiles = (modified, added, removed, missing, [], [], clean)
246 lfiles = (modified, added, removed, missing, [], [], clean)
247 result = [sorted(list1 + list2)
247 result = [sorted(list1 + list2)
248 for (list1, list2) in zip(normals, lfiles)]
248 for (list1, list2) in zip(normals, lfiles)]
249 else:
249 else:
250 def toname(f):
250 def toname(f):
251 if lfutil.isstandin(f):
251 if lfutil.isstandin(f):
252 return lfutil.splitstandin(f)
252 return lfutil.splitstandin(f)
253 return f
253 return f
254 result = [[toname(f) for f in items] for items in result]
254 result = [[toname(f) for f in items] for items in result]
255
255
256 if not listunknown:
256 if not listunknown:
257 result[4] = []
257 result[4] = []
258 if not listignored:
258 if not listignored:
259 result[5] = []
259 result[5] = []
260 if not listclean:
260 if not listclean:
261 result[6] = []
261 result[6] = []
262 self.lfstatus = True
262 self.lfstatus = True
263 return result
263 return result
264
264
265 # As part of committing, copy all of the largefiles into the
265 # As part of committing, copy all of the largefiles into the
266 # cache.
266 # cache.
267 def commitctx(self, *args, **kwargs):
267 def commitctx(self, *args, **kwargs):
268 node = super(lfiles_repo, self).commitctx(*args, **kwargs)
268 node = super(lfiles_repo, self).commitctx(*args, **kwargs)
269 lfutil.copyalltostore(self, node)
269 lfutil.copyalltostore(self, node)
270 return node
270 return node
271
271
272 # Before commit, largefile standins have not had their
272 # Before commit, largefile standins have not had their
273 # contents updated to reflect the hash of their largefile.
273 # contents updated to reflect the hash of their largefile.
274 # Do that here.
274 # Do that here.
275 def commit(self, text="", user=None, date=None, match=None,
275 def commit(self, text="", user=None, date=None, match=None,
276 force=False, editor=False, extra={}):
276 force=False, editor=False, extra={}):
277 orig = super(lfiles_repo, self).commit
277 orig = super(lfiles_repo, self).commit
278
278
279 wlock = repo.wlock()
279 wlock = repo.wlock()
280 try:
280 try:
281 # Case 0: Rebase or Transplant
281 # Case 0: Rebase or Transplant
282 # We have to take the time to pull down the new largefiles now.
282 # We have to take the time to pull down the new largefiles now.
283 # Otherwise, any largefiles that were modified in the
283 # Otherwise, any largefiles that were modified in the
284 # destination changesets get overwritten, either by the rebase
284 # destination changesets get overwritten, either by the rebase
285 # or in the first commit after the rebase or transplant.
285 # or in the first commit after the rebase or transplant.
286 # updatelfiles will update the dirstate to mark any pulled
286 # updatelfiles will update the dirstate to mark any pulled
287 # largefiles as modified
287 # largefiles as modified
288 if getattr(repo, "_isrebasing", False) or \
288 if getattr(repo, "_isrebasing", False) or \
289 getattr(repo, "_istransplanting", False):
289 getattr(repo, "_istransplanting", False):
290 lfcommands.updatelfiles(repo.ui, repo, filelist=None,
290 lfcommands.updatelfiles(repo.ui, repo, filelist=None,
291 printmessage=False)
291 printmessage=False)
292 result = orig(text=text, user=user, date=date, match=match,
292 result = orig(text=text, user=user, date=date, match=match,
293 force=force, editor=editor, extra=extra)
293 force=force, editor=editor, extra=extra)
294 return result
294 return result
295 # Case 1: user calls commit with no specific files or
295 # Case 1: user calls commit with no specific files or
296 # include/exclude patterns: refresh and commit all files that
296 # include/exclude patterns: refresh and commit all files that
297 # are "dirty".
297 # are "dirty".
298 if ((match is None) or
298 if ((match is None) or
299 (not match.anypats() and not match.files())):
299 (not match.anypats() and not match.files())):
300 # Spend a bit of time here to get a list of files we know
300 # Spend a bit of time here to get a list of files we know
301 # are modified so we can compare only against those.
301 # are modified so we can compare only against those.
302 # It can cost a lot of time (several seconds)
302 # It can cost a lot of time (several seconds)
303 # otherwise to update all standins if the largefiles are
303 # otherwise to update all standins if the largefiles are
304 # large.
304 # large.
305 lfdirstate = lfutil.openlfdirstate(ui, self)
305 lfdirstate = lfutil.openlfdirstate(ui, self)
306 dirtymatch = match_.always(repo.root, repo.getcwd())
306 dirtymatch = match_.always(repo.root, repo.getcwd())
307 s = lfdirstate.status(dirtymatch, [], False, False, False)
307 s = lfdirstate.status(dirtymatch, [], False, False, False)
308 modifiedfiles = []
308 modifiedfiles = []
309 for i in s:
309 for i in s:
310 modifiedfiles.extend(i)
310 modifiedfiles.extend(i)
311 lfiles = lfutil.listlfiles(self)
311 lfiles = lfutil.listlfiles(self)
312 # this only loops through largefiles that exist (not
312 # this only loops through largefiles that exist (not
313 # removed/renamed)
313 # removed/renamed)
314 for lfile in lfiles:
314 for lfile in lfiles:
315 if lfile in modifiedfiles:
315 if lfile in modifiedfiles:
316 if os.path.exists(self.wjoin(lfutil.standin(lfile))):
316 if os.path.exists(self.wjoin(lfutil.standin(lfile))):
317 # this handles the case where a rebase is being
317 # this handles the case where a rebase is being
318 # performed and the working copy is not updated
318 # performed and the working copy is not updated
319 # yet.
319 # yet.
320 if os.path.exists(self.wjoin(lfile)):
320 if os.path.exists(self.wjoin(lfile)):
321 lfutil.updatestandin(self,
321 lfutil.updatestandin(self,
322 lfutil.standin(lfile))
322 lfutil.standin(lfile))
323 lfdirstate.normal(lfile)
323 lfdirstate.normal(lfile)
324 for lfile in lfdirstate:
324 for lfile in lfdirstate:
325 if lfile in modifiedfiles:
325 if lfile in modifiedfiles:
326 if not os.path.exists(
326 if not os.path.exists(
327 repo.wjoin(lfutil.standin(lfile))):
327 repo.wjoin(lfutil.standin(lfile))):
328 lfdirstate.drop(lfile)
328 lfdirstate.drop(lfile)
329
329
330 result = orig(text=text, user=user, date=date, match=match,
330 result = orig(text=text, user=user, date=date, match=match,
331 force=force, editor=editor, extra=extra)
331 force=force, editor=editor, extra=extra)
332 # This needs to be after commit; otherwise precommit hooks
332 # This needs to be after commit; otherwise precommit hooks
333 # get the wrong status
333 # get the wrong status
334 lfdirstate.write()
334 lfdirstate.write()
335 return result
335 return result
336
336
337 for f in match.files():
337 for f in match.files():
338 if lfutil.isstandin(f):
338 if lfutil.isstandin(f):
339 raise util.Abort(
339 raise util.Abort(
340 _('file "%s" is a largefile standin') % f,
340 _('file "%s" is a largefile standin') % f,
341 hint=('commit the largefile itself instead'))
341 hint=('commit the largefile itself instead'))
342
342
343 # Case 2: user calls commit with specified patterns: refresh
343 # Case 2: user calls commit with specified patterns: refresh
344 # any matching big files.
344 # any matching big files.
345 smatcher = lfutil.composestandinmatcher(self, match)
345 smatcher = lfutil.composestandinmatcher(self, match)
346 standins = lfutil.dirstate_walk(self.dirstate, smatcher)
346 standins = lfutil.dirstate_walk(self.dirstate, smatcher)
347
347
348 # No matching big files: get out of the way and pass control to
348 # No matching big files: get out of the way and pass control to
349 # the usual commit() method.
349 # the usual commit() method.
350 if not standins:
350 if not standins:
351 return orig(text=text, user=user, date=date, match=match,
351 return orig(text=text, user=user, date=date, match=match,
352 force=force, editor=editor, extra=extra)
352 force=force, editor=editor, extra=extra)
353
353
354 # Refresh all matching big files. It's possible that the
354 # Refresh all matching big files. It's possible that the
355 # commit will end up failing, in which case the big files will
355 # commit will end up failing, in which case the big files will
356 # stay refreshed. No harm done: the user modified them and
356 # stay refreshed. No harm done: the user modified them and
357 # asked to commit them, so sooner or later we're going to
357 # asked to commit them, so sooner or later we're going to
358 # refresh the standins. Might as well leave them refreshed.
358 # refresh the standins. Might as well leave them refreshed.
359 lfdirstate = lfutil.openlfdirstate(ui, self)
359 lfdirstate = lfutil.openlfdirstate(ui, self)
360 for standin in standins:
360 for standin in standins:
361 lfile = lfutil.splitstandin(standin)
361 lfile = lfutil.splitstandin(standin)
362 if lfdirstate[lfile] <> 'r':
362 if lfdirstate[lfile] <> 'r':
363 lfutil.updatestandin(self, standin)
363 lfutil.updatestandin(self, standin)
364 lfdirstate.normal(lfile)
364 lfdirstate.normal(lfile)
365 else:
365 else:
366 lfdirstate.drop(lfile)
366 lfdirstate.drop(lfile)
367
367
368 # Cook up a new matcher that only matches regular files or
368 # Cook up a new matcher that only matches regular files or
369 # standins corresponding to the big files requested by the
369 # standins corresponding to the big files requested by the
370 # user. Have to modify _files to prevent commit() from
370 # user. Have to modify _files to prevent commit() from
371 # complaining "not tracked" for big files.
371 # complaining "not tracked" for big files.
372 lfiles = lfutil.listlfiles(repo)
372 lfiles = lfutil.listlfiles(repo)
373 match = copy.copy(match)
373 match = copy.copy(match)
374 orig_matchfn = match.matchfn
374 orig_matchfn = match.matchfn
375
375
376 # Check both the list of largefiles and the list of
376 # Check both the list of largefiles and the list of
377 # standins because if a largefile was removed, it
377 # standins because if a largefile was removed, it
378 # won't be in the list of largefiles at this point
378 # won't be in the list of largefiles at this point
379 match._files += sorted(standins)
379 match._files += sorted(standins)
380
380
381 actualfiles = []
381 actualfiles = []
382 for f in match._files:
382 for f in match._files:
383 fstandin = lfutil.standin(f)
383 fstandin = lfutil.standin(f)
384
384
385 # ignore known largefiles and standins
385 # ignore known largefiles and standins
386 if f in lfiles or fstandin in standins:
386 if f in lfiles or fstandin in standins:
387 continue
387 continue
388
388
389 # append directory separator to avoid collisions
389 # append directory separator to avoid collisions
390 if not fstandin.endswith(os.sep):
390 if not fstandin.endswith(os.sep):
391 fstandin += os.sep
391 fstandin += os.sep
392
392
393 # prevalidate matching standin directories
393 # prevalidate matching standin directories
394 if util.any(st for st in match._files
394 if util.any(st for st in match._files
395 if st.startswith(fstandin)):
395 if st.startswith(fstandin)):
396 continue
396 continue
397 actualfiles.append(f)
397 actualfiles.append(f)
398 match._files = actualfiles
398 match._files = actualfiles
399
399
400 def matchfn(f):
400 def matchfn(f):
401 if orig_matchfn(f):
401 if orig_matchfn(f):
402 return f not in lfiles
402 return f not in lfiles
403 else:
403 else:
404 return f in standins
404 return f in standins
405
405
406 match.matchfn = matchfn
406 match.matchfn = matchfn
407 result = orig(text=text, user=user, date=date, match=match,
407 result = orig(text=text, user=user, date=date, match=match,
408 force=force, editor=editor, extra=extra)
408 force=force, editor=editor, extra=extra)
409 # This needs to be after commit; otherwise precommit hooks
409 # This needs to be after commit; otherwise precommit hooks
410 # get the wrong status
410 # get the wrong status
411 lfdirstate.write()
411 lfdirstate.write()
412 return result
412 return result
413 finally:
413 finally:
414 wlock.release()
414 wlock.release()
415
415
416 def push(self, remote, force=False, revs=None, newbranch=False):
416 def push(self, remote, force=False, revs=None, newbranch=False):
417 o = lfutil.findoutgoing(repo, remote, force)
417 o = lfutil.findoutgoing(repo, remote, force)
418 if o:
418 if o:
419 toupload = set()
419 toupload = set()
420 o = repo.changelog.nodesbetween(o, revs)[0]
420 o = repo.changelog.nodesbetween(o, revs)[0]
421 for n in o:
421 for n in o:
422 parents = [p for p in repo.changelog.parents(n)
422 parents = [p for p in repo.changelog.parents(n)
423 if p != node_.nullid]
423 if p != node_.nullid]
424 ctx = repo[n]
424 ctx = repo[n]
425 files = set(ctx.files())
425 files = set(ctx.files())
426 if len(parents) == 2:
426 if len(parents) == 2:
427 mc = ctx.manifest()
427 mc = ctx.manifest()
428 mp1 = ctx.parents()[0].manifest()
428 mp1 = ctx.parents()[0].manifest()
429 mp2 = ctx.parents()[1].manifest()
429 mp2 = ctx.parents()[1].manifest()
430 for f in mp1:
430 for f in mp1:
431 if f not in mc:
431 if f not in mc:
432 files.add(f)
432 files.add(f)
433 for f in mp2:
433 for f in mp2:
434 if f not in mc:
434 if f not in mc:
435 files.add(f)
435 files.add(f)
436 for f in mc:
436 for f in mc:
437 if mc[f] != mp1.get(f, None) or mc[f] != mp2.get(f,
437 if mc[f] != mp1.get(f, None) or mc[f] != mp2.get(f,
438 None):
438 None):
439 files.add(f)
439 files.add(f)
440
440
441 toupload = toupload.union(
441 toupload = toupload.union(
442 set([ctx[f].data().strip()
442 set([ctx[f].data().strip()
443 for f in files
443 for f in files
444 if lfutil.isstandin(f) and f in ctx]))
444 if lfutil.isstandin(f) and f in ctx]))
445 lfcommands.uploadlfiles(ui, self, remote, toupload)
445 lfcommands.uploadlfiles(ui, self, remote, toupload)
446 return super(lfiles_repo, self).push(remote, force, revs,
446 return super(lfiles_repo, self).push(remote, force, revs,
447 newbranch)
447 newbranch)
448
448
449 repo.__class__ = lfiles_repo
449 repo.__class__ = lfiles_repo
450
450
451 def checkrequireslfiles(ui, repo, **kwargs):
451 def checkrequireslfiles(ui, repo, **kwargs):
452 if 'largefiles' not in repo.requirements and util.any(
452 if 'largefiles' not in repo.requirements and util.any(
453 lfutil.shortname+'/' in f[0] for f in repo.store.datafiles()):
453 lfutil.shortname+'/' in f[0] for f in repo.store.datafiles()):
454 repo.requirements.add('largefiles')
454 repo.requirements.add('largefiles')
455 repo._writerequirements()
455 repo._writerequirements()
456
456
457 ui.setconfig('hooks', 'changegroup.lfiles', checkrequireslfiles)
457 ui.setconfig('hooks', 'changegroup.lfiles', checkrequireslfiles)
458 ui.setconfig('hooks', 'commit.lfiles', checkrequireslfiles)
458 ui.setconfig('hooks', 'commit.lfiles', checkrequireslfiles)
@@ -1,1007 +1,1009 b''
1 $ "$TESTDIR/hghave" symlink unix-permissions serve || exit 80
1 $ "$TESTDIR/hghave" symlink unix-permissions serve || exit 80
2 $ USERCACHE=`pwd`/cache; export USERCACHE
2 $ USERCACHE=`pwd`/cache; export USERCACHE
3 $ mkdir -p ${USERCACHE}
3 $ mkdir -p ${USERCACHE}
4 $ cat >> $HGRCPATH <<EOF
4 $ cat >> $HGRCPATH <<EOF
5 > [extensions]
5 > [extensions]
6 > largefiles=
6 > largefiles=
7 > purge=
7 > purge=
8 > rebase=
8 > rebase=
9 > transplant=
9 > transplant=
10 > [phases]
10 > [phases]
11 > publish=False
11 > publish=False
12 > [largefiles]
12 > [largefiles]
13 > minsize=2
13 > minsize=2
14 > patterns=glob:**.dat
14 > patterns=glob:**.dat
15 > usercache=${USERCACHE}
15 > usercache=${USERCACHE}
16 > [hooks]
16 > [hooks]
17 > precommit=echo "Invoking status precommit hook"; hg status
17 > precommit=echo "Invoking status precommit hook"; hg status
18 > EOF
18 > EOF
19
19
20 Create the repo with a couple of revisions of both large and normal
20 Create the repo with a couple of revisions of both large and normal
21 files, testing that status correctly shows largefiles and that summary output
21 files, testing that status correctly shows largefiles and that summary output
22 is correct.
22 is correct.
23
23
24 $ hg init a
24 $ hg init a
25 $ cd a
25 $ cd a
26 $ mkdir sub
26 $ mkdir sub
27 $ echo normal1 > normal1
27 $ echo normal1 > normal1
28 $ echo normal2 > sub/normal2
28 $ echo normal2 > sub/normal2
29 $ echo large1 > large1
29 $ echo large1 > large1
30 $ echo large2 > sub/large2
30 $ echo large2 > sub/large2
31 $ hg add normal1 sub/normal2
31 $ hg add normal1 sub/normal2
32 $ hg add --large large1 sub/large2
32 $ hg add --large large1 sub/large2
33 $ hg commit -m "add files"
33 $ hg commit -m "add files"
34 Invoking status precommit hook
34 Invoking status precommit hook
35 A large1
35 A large1
36 A normal1
36 A normal1
37 A sub/large2
37 A sub/large2
38 A sub/normal2
38 A sub/normal2
39 $ echo normal11 > normal1
39 $ echo normal11 > normal1
40 $ echo normal22 > sub/normal2
40 $ echo normal22 > sub/normal2
41 $ echo large11 > large1
41 $ echo large11 > large1
42 $ echo large22 > sub/large2
42 $ echo large22 > sub/large2
43 $ hg commit -m "edit files"
43 $ hg commit -m "edit files"
44 Invoking status precommit hook
44 Invoking status precommit hook
45 M large1
45 M large1
46 M normal1
46 M normal1
47 M sub/large2
47 M sub/large2
48 M sub/normal2
48 M sub/normal2
49 $ hg sum --large
49 $ hg sum --large
50 parent: 1:ce8896473775 tip
50 parent: 1:ce8896473775 tip
51 edit files
51 edit files
52 branch: default
52 branch: default
53 commit: (clean)
53 commit: (clean)
54 update: (current)
54 update: (current)
55 largefiles: No remote repo
55 largefiles: No remote repo
56
56
57 Commit preserved largefile contents.
57 Commit preserved largefile contents.
58
58
59 $ cat normal1
59 $ cat normal1
60 normal11
60 normal11
61 $ cat large1
61 $ cat large1
62 large11
62 large11
63 $ cat sub/normal2
63 $ cat sub/normal2
64 normal22
64 normal22
65 $ cat sub/large2
65 $ cat sub/large2
66 large22
66 large22
67
67
68 Remove both largefiles and normal files.
68 Remove both largefiles and normal files.
69
69
70 $ hg remove normal1 large1
70 $ hg remove normal1 large1
71 $ hg status large1
72 R large1
71 $ hg commit -m "remove files"
73 $ hg commit -m "remove files"
72 Invoking status precommit hook
74 Invoking status precommit hook
73 R large1
75 R large1
74 R normal1
76 R normal1
75 $ ls
77 $ ls
76 sub
78 sub
77 $ echo "testlargefile" > large1-test
79 $ echo "testlargefile" > large1-test
78 $ hg add --large large1-test
80 $ hg add --large large1-test
79 $ hg st
81 $ hg st
80 A large1-test
82 A large1-test
81 $ hg rm large1-test
83 $ hg rm large1-test
82 not removing large1-test: file has been marked for add (use forget to undo)
84 not removing large1-test: file has been marked for add (use forget to undo)
83 $ hg st
85 $ hg st
84 A large1-test
86 A large1-test
85 $ hg forget large1-test
87 $ hg forget large1-test
86 $ hg st
88 $ hg st
87 ? large1-test
89 ? large1-test
88 $ rm large1-test
90 $ rm large1-test
89
91
90 Copy both largefiles and normal files (testing that status output is correct).
92 Copy both largefiles and normal files (testing that status output is correct).
91
93
92 $ hg cp sub/normal2 normal1
94 $ hg cp sub/normal2 normal1
93 $ hg cp sub/large2 large1
95 $ hg cp sub/large2 large1
94 $ hg commit -m "copy files"
96 $ hg commit -m "copy files"
95 Invoking status precommit hook
97 Invoking status precommit hook
96 A large1
98 A large1
97 A normal1
99 A normal1
98 $ cat normal1
100 $ cat normal1
99 normal22
101 normal22
100 $ cat large1
102 $ cat large1
101 large22
103 large22
102
104
103 Test moving largefiles and verify that normal files are also unaffected.
105 Test moving largefiles and verify that normal files are also unaffected.
104
106
105 $ hg mv normal1 normal3
107 $ hg mv normal1 normal3
106 $ hg mv large1 large3
108 $ hg mv large1 large3
107 $ hg mv sub/normal2 sub/normal4
109 $ hg mv sub/normal2 sub/normal4
108 $ hg mv sub/large2 sub/large4
110 $ hg mv sub/large2 sub/large4
109 $ hg commit -m "move files"
111 $ hg commit -m "move files"
110 Invoking status precommit hook
112 Invoking status precommit hook
111 A large3
113 A large3
112 A normal3
114 A normal3
113 A sub/large4
115 A sub/large4
114 A sub/normal4
116 A sub/normal4
115 R large1
117 R large1
116 R normal1
118 R normal1
117 R sub/large2
119 R sub/large2
118 R sub/normal2
120 R sub/normal2
119 $ cat normal3
121 $ cat normal3
120 normal22
122 normal22
121 $ cat large3
123 $ cat large3
122 large22
124 large22
123 $ cat sub/normal4
125 $ cat sub/normal4
124 normal22
126 normal22
125 $ cat sub/large4
127 $ cat sub/large4
126 large22
128 large22
127
129
128 Test archiving the various revisions. These hit corner cases known with
130 Test archiving the various revisions. These hit corner cases known with
129 archiving.
131 archiving.
130
132
131 $ hg archive -r 0 ../archive0
133 $ hg archive -r 0 ../archive0
132 $ hg archive -r 1 ../archive1
134 $ hg archive -r 1 ../archive1
133 $ hg archive -r 2 ../archive2
135 $ hg archive -r 2 ../archive2
134 $ hg archive -r 3 ../archive3
136 $ hg archive -r 3 ../archive3
135 $ hg archive -r 4 ../archive4
137 $ hg archive -r 4 ../archive4
136 $ cd ../archive0
138 $ cd ../archive0
137 $ cat normal1
139 $ cat normal1
138 normal1
140 normal1
139 $ cat large1
141 $ cat large1
140 large1
142 large1
141 $ cat sub/normal2
143 $ cat sub/normal2
142 normal2
144 normal2
143 $ cat sub/large2
145 $ cat sub/large2
144 large2
146 large2
145 $ cd ../archive1
147 $ cd ../archive1
146 $ cat normal1
148 $ cat normal1
147 normal11
149 normal11
148 $ cat large1
150 $ cat large1
149 large11
151 large11
150 $ cat sub/normal2
152 $ cat sub/normal2
151 normal22
153 normal22
152 $ cat sub/large2
154 $ cat sub/large2
153 large22
155 large22
154 $ cd ../archive2
156 $ cd ../archive2
155 $ ls
157 $ ls
156 sub
158 sub
157 $ cat sub/normal2
159 $ cat sub/normal2
158 normal22
160 normal22
159 $ cat sub/large2
161 $ cat sub/large2
160 large22
162 large22
161 $ cd ../archive3
163 $ cd ../archive3
162 $ cat normal1
164 $ cat normal1
163 normal22
165 normal22
164 $ cat large1
166 $ cat large1
165 large22
167 large22
166 $ cat sub/normal2
168 $ cat sub/normal2
167 normal22
169 normal22
168 $ cat sub/large2
170 $ cat sub/large2
169 large22
171 large22
170 $ cd ../archive4
172 $ cd ../archive4
171 $ cat normal3
173 $ cat normal3
172 normal22
174 normal22
173 $ cat large3
175 $ cat large3
174 large22
176 large22
175 $ cat sub/normal4
177 $ cat sub/normal4
176 normal22
178 normal22
177 $ cat sub/large4
179 $ cat sub/large4
178 large22
180 large22
179
181
180 Commit corner case: specify files to commit.
182 Commit corner case: specify files to commit.
181
183
182 $ cd ../a
184 $ cd ../a
183 $ echo normal3 > normal3
185 $ echo normal3 > normal3
184 $ echo large3 > large3
186 $ echo large3 > large3
185 $ echo normal4 > sub/normal4
187 $ echo normal4 > sub/normal4
186 $ echo large4 > sub/large4
188 $ echo large4 > sub/large4
187 $ hg commit normal3 large3 sub/normal4 sub/large4 -m "edit files again"
189 $ hg commit normal3 large3 sub/normal4 sub/large4 -m "edit files again"
188 Invoking status precommit hook
190 Invoking status precommit hook
189 M large3
191 M large3
190 M normal3
192 M normal3
191 M sub/large4
193 M sub/large4
192 M sub/normal4
194 M sub/normal4
193 $ cat normal3
195 $ cat normal3
194 normal3
196 normal3
195 $ cat large3
197 $ cat large3
196 large3
198 large3
197 $ cat sub/normal4
199 $ cat sub/normal4
198 normal4
200 normal4
199 $ cat sub/large4
201 $ cat sub/large4
200 large4
202 large4
201
203
202 One more commit corner case: commit from a subdirectory.
204 One more commit corner case: commit from a subdirectory.
203
205
204 $ cd ../a
206 $ cd ../a
205 $ echo normal33 > normal3
207 $ echo normal33 > normal3
206 $ echo large33 > large3
208 $ echo large33 > large3
207 $ echo normal44 > sub/normal4
209 $ echo normal44 > sub/normal4
208 $ echo large44 > sub/large4
210 $ echo large44 > sub/large4
209 $ cd sub
211 $ cd sub
210 $ hg commit -m "edit files yet again"
212 $ hg commit -m "edit files yet again"
211 Invoking status precommit hook
213 Invoking status precommit hook
212 M large3
214 M large3
213 M normal3
215 M normal3
214 M sub/large4
216 M sub/large4
215 M sub/normal4
217 M sub/normal4
216 $ cat ../normal3
218 $ cat ../normal3
217 normal33
219 normal33
218 $ cat ../large3
220 $ cat ../large3
219 large33
221 large33
220 $ cat normal4
222 $ cat normal4
221 normal44
223 normal44
222 $ cat large4
224 $ cat large4
223 large44
225 large44
224
226
225 Committing standins is not allowed.
227 Committing standins is not allowed.
226
228
227 $ cd ..
229 $ cd ..
228 $ echo large3 > large3
230 $ echo large3 > large3
229 $ hg commit .hglf/large3 -m "try to commit standin"
231 $ hg commit .hglf/large3 -m "try to commit standin"
230 abort: file ".hglf/large3" is a largefile standin
232 abort: file ".hglf/large3" is a largefile standin
231 (commit the largefile itself instead)
233 (commit the largefile itself instead)
232 [255]
234 [255]
233
235
234 Corner cases for adding largefiles.
236 Corner cases for adding largefiles.
235
237
236 $ echo large5 > large5
238 $ echo large5 > large5
237 $ hg add --large large5
239 $ hg add --large large5
238 $ hg add --large large5
240 $ hg add --large large5
239 large5 already a largefile
241 large5 already a largefile
240 $ mkdir sub2
242 $ mkdir sub2
241 $ echo large6 > sub2/large6
243 $ echo large6 > sub2/large6
242 $ echo large7 > sub2/large7
244 $ echo large7 > sub2/large7
243 $ hg add --large sub2
245 $ hg add --large sub2
244 adding sub2/large6 as a largefile (glob)
246 adding sub2/large6 as a largefile (glob)
245 adding sub2/large7 as a largefile (glob)
247 adding sub2/large7 as a largefile (glob)
246 $ hg st
248 $ hg st
247 M large3
249 M large3
248 A large5
250 A large5
249 A sub2/large6
251 A sub2/large6
250 A sub2/large7
252 A sub2/large7
251
253
252 Config settings (pattern **.dat, minsize 2 MB) are respected.
254 Config settings (pattern **.dat, minsize 2 MB) are respected.
253
255
254 $ echo testdata > test.dat
256 $ echo testdata > test.dat
255 $ dd bs=1k count=2k if=/dev/zero of=reallylarge > /dev/null 2> /dev/null
257 $ dd bs=1k count=2k if=/dev/zero of=reallylarge > /dev/null 2> /dev/null
256 $ hg add
258 $ hg add
257 adding reallylarge as a largefile
259 adding reallylarge as a largefile
258 adding test.dat as a largefile
260 adding test.dat as a largefile
259
261
260 Test that minsize and --lfsize handle float values;
262 Test that minsize and --lfsize handle float values;
261 also tests that --lfsize overrides largefiles.minsize.
263 also tests that --lfsize overrides largefiles.minsize.
262 (0.250 MB = 256 kB = 262144 B)
264 (0.250 MB = 256 kB = 262144 B)
263
265
264 $ dd if=/dev/zero of=ratherlarge bs=1024 count=256 > /dev/null 2> /dev/null
266 $ dd if=/dev/zero of=ratherlarge bs=1024 count=256 > /dev/null 2> /dev/null
265 $ dd if=/dev/zero of=medium bs=1024 count=128 > /dev/null 2> /dev/null
267 $ dd if=/dev/zero of=medium bs=1024 count=128 > /dev/null 2> /dev/null
266 $ hg --config largefiles.minsize=.25 add
268 $ hg --config largefiles.minsize=.25 add
267 adding ratherlarge as a largefile
269 adding ratherlarge as a largefile
268 adding medium
270 adding medium
269 $ hg forget medium
271 $ hg forget medium
270 $ hg --config largefiles.minsize=.25 add --lfsize=.125
272 $ hg --config largefiles.minsize=.25 add --lfsize=.125
271 adding medium as a largefile
273 adding medium as a largefile
272 $ dd if=/dev/zero of=notlarge bs=1024 count=127 > /dev/null 2> /dev/null
274 $ dd if=/dev/zero of=notlarge bs=1024 count=127 > /dev/null 2> /dev/null
273 $ hg --config largefiles.minsize=.25 add --lfsize=.125
275 $ hg --config largefiles.minsize=.25 add --lfsize=.125
274 adding notlarge
276 adding notlarge
275 $ hg forget notlarge
277 $ hg forget notlarge
276
278
277 Test forget on largefiles.
279 Test forget on largefiles.
278
280
279 $ hg forget large3 large5 test.dat reallylarge ratherlarge medium
281 $ hg forget large3 large5 test.dat reallylarge ratherlarge medium
280 $ hg commit -m "add/edit more largefiles"
282 $ hg commit -m "add/edit more largefiles"
281 Invoking status precommit hook
283 Invoking status precommit hook
282 A sub2/large6
284 A sub2/large6
283 A sub2/large7
285 A sub2/large7
284 R large3
286 R large3
285 ? large5
287 ? large5
286 ? medium
288 ? medium
287 ? notlarge
289 ? notlarge
288 ? ratherlarge
290 ? ratherlarge
289 ? reallylarge
291 ? reallylarge
290 ? test.dat
292 ? test.dat
291 $ hg st
293 $ hg st
292 ? large3
294 ? large3
293 ? large5
295 ? large5
294 ? medium
296 ? medium
295 ? notlarge
297 ? notlarge
296 ? ratherlarge
298 ? ratherlarge
297 ? reallylarge
299 ? reallylarge
298 ? test.dat
300 ? test.dat
299
301
300 Purge with largefiles: verify that largefiles are still in the working
302 Purge with largefiles: verify that largefiles are still in the working
301 dir after a purge.
303 dir after a purge.
302
304
303 $ hg purge --all
305 $ hg purge --all
304 $ cat sub/large4
306 $ cat sub/large4
305 large44
307 large44
306 $ cat sub2/large6
308 $ cat sub2/large6
307 large6
309 large6
308 $ cat sub2/large7
310 $ cat sub2/large7
309 large7
311 large7
310
312
311 Test addremove: verify that files that should be added as largfiles are added as
313 Test addremove: verify that files that should be added as largfiles are added as
312 such and that already-existing largfiles are not added as normal files by
314 such and that already-existing largfiles are not added as normal files by
313 accident.
315 accident.
314
316
315 $ rm normal3
317 $ rm normal3
316 $ rm sub/large4
318 $ rm sub/large4
317 $ echo "testing addremove with patterns" > testaddremove.dat
319 $ echo "testing addremove with patterns" > testaddremove.dat
318 $ echo "normaladdremove" > normaladdremove
320 $ echo "normaladdremove" > normaladdremove
319 $ hg addremove
321 $ hg addremove
320 removing sub/large4
322 removing sub/large4
321 adding testaddremove.dat as a largefile
323 adding testaddremove.dat as a largefile
322 removing normal3
324 removing normal3
323 adding normaladdremove
325 adding normaladdremove
324
326
325 Clone a largefiles repo.
327 Clone a largefiles repo.
326
328
327 $ hg clone . ../b
329 $ hg clone . ../b
328 updating to branch default
330 updating to branch default
329 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
331 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
330 getting changed largefiles
332 getting changed largefiles
331 3 largefiles updated, 0 removed
333 3 largefiles updated, 0 removed
332 $ cd ../b
334 $ cd ../b
333 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
335 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
334 7:daea875e9014 add/edit more largefiles
336 7:daea875e9014 add/edit more largefiles
335 6:4355d653f84f edit files yet again
337 6:4355d653f84f edit files yet again
336 5:9d5af5072dbd edit files again
338 5:9d5af5072dbd edit files again
337 4:74c02385b94c move files
339 4:74c02385b94c move files
338 3:9e8fbc4bce62 copy files
340 3:9e8fbc4bce62 copy files
339 2:51a0ae4d5864 remove files
341 2:51a0ae4d5864 remove files
340 1:ce8896473775 edit files
342 1:ce8896473775 edit files
341 0:30d30fe6a5be add files
343 0:30d30fe6a5be add files
342 $ cat normal3
344 $ cat normal3
343 normal33
345 normal33
344 $ cat sub/normal4
346 $ cat sub/normal4
345 normal44
347 normal44
346 $ cat sub/large4
348 $ cat sub/large4
347 large44
349 large44
348 $ cat sub2/large6
350 $ cat sub2/large6
349 large6
351 large6
350 $ cat sub2/large7
352 $ cat sub2/large7
351 large7
353 large7
352 $ cd ..
354 $ cd ..
353 $ hg clone a -r 3 c
355 $ hg clone a -r 3 c
354 adding changesets
356 adding changesets
355 adding manifests
357 adding manifests
356 adding file changes
358 adding file changes
357 added 4 changesets with 10 changes to 4 files
359 added 4 changesets with 10 changes to 4 files
358 updating to branch default
360 updating to branch default
359 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
361 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
360 getting changed largefiles
362 getting changed largefiles
361 2 largefiles updated, 0 removed
363 2 largefiles updated, 0 removed
362 $ cd c
364 $ cd c
363 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
365 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
364 3:9e8fbc4bce62 copy files
366 3:9e8fbc4bce62 copy files
365 2:51a0ae4d5864 remove files
367 2:51a0ae4d5864 remove files
366 1:ce8896473775 edit files
368 1:ce8896473775 edit files
367 0:30d30fe6a5be add files
369 0:30d30fe6a5be add files
368 $ cat normal1
370 $ cat normal1
369 normal22
371 normal22
370 $ cat large1
372 $ cat large1
371 large22
373 large22
372 $ cat sub/normal2
374 $ cat sub/normal2
373 normal22
375 normal22
374 $ cat sub/large2
376 $ cat sub/large2
375 large22
377 large22
376
378
377 Old revisions of a clone have correct largefiles content (this also
379 Old revisions of a clone have correct largefiles content (this also
378 tests update).
380 tests update).
379
381
380 $ hg update -r 1
382 $ hg update -r 1
381 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
383 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
382 getting changed largefiles
384 getting changed largefiles
383 1 largefiles updated, 0 removed
385 1 largefiles updated, 0 removed
384 $ cat large1
386 $ cat large1
385 large11
387 large11
386 $ cat sub/large2
388 $ cat sub/large2
387 large22
389 large22
388
390
389 Rebasing between two repositories does not revert largefiles to old
391 Rebasing between two repositories does not revert largefiles to old
390 revisions (this was a very bad bug that took a lot of work to fix).
392 revisions (this was a very bad bug that took a lot of work to fix).
391
393
392 $ cd ..
394 $ cd ..
393 $ hg clone a d
395 $ hg clone a d
394 updating to branch default
396 updating to branch default
395 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
397 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
396 getting changed largefiles
398 getting changed largefiles
397 3 largefiles updated, 0 removed
399 3 largefiles updated, 0 removed
398 $ cd b
400 $ cd b
399 $ echo large4-modified > sub/large4
401 $ echo large4-modified > sub/large4
400 $ echo normal3-modified > normal3
402 $ echo normal3-modified > normal3
401 $ hg commit -m "modify normal file and largefile in repo b"
403 $ hg commit -m "modify normal file and largefile in repo b"
402 Invoking status precommit hook
404 Invoking status precommit hook
403 M normal3
405 M normal3
404 M sub/large4
406 M sub/large4
405 $ cd ../d
407 $ cd ../d
406 $ echo large6-modified > sub2/large6
408 $ echo large6-modified > sub2/large6
407 $ echo normal4-modified > sub/normal4
409 $ echo normal4-modified > sub/normal4
408 $ hg commit -m "modify normal file largefile in repo d"
410 $ hg commit -m "modify normal file largefile in repo d"
409 Invoking status precommit hook
411 Invoking status precommit hook
410 M sub/normal4
412 M sub/normal4
411 M sub2/large6
413 M sub2/large6
412 $ cd ..
414 $ cd ..
413 $ hg clone d e
415 $ hg clone d e
414 updating to branch default
416 updating to branch default
415 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
417 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
416 getting changed largefiles
418 getting changed largefiles
417 3 largefiles updated, 0 removed
419 3 largefiles updated, 0 removed
418 $ cd d
420 $ cd d
419 $ hg pull --rebase ../b
421 $ hg pull --rebase ../b
420 pulling from ../b
422 pulling from ../b
421 searching for changes
423 searching for changes
422 adding changesets
424 adding changesets
423 adding manifests
425 adding manifests
424 adding file changes
426 adding file changes
425 added 1 changesets with 2 changes to 2 files (+1 heads)
427 added 1 changesets with 2 changes to 2 files (+1 heads)
426 Invoking status precommit hook
428 Invoking status precommit hook
427 M sub/normal4
429 M sub/normal4
428 M sub2/large6
430 M sub2/large6
429 saved backup bundle to $TESTTMP/d/.hg/strip-backup/f574fb32bb45-backup.hg
431 saved backup bundle to $TESTTMP/d/.hg/strip-backup/f574fb32bb45-backup.hg
430 nothing to rebase
432 nothing to rebase
431 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
433 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
432 9:598410d3eb9a modify normal file largefile in repo d
434 9:598410d3eb9a modify normal file largefile in repo d
433 8:a381d2c8c80e modify normal file and largefile in repo b
435 8:a381d2c8c80e modify normal file and largefile in repo b
434 7:daea875e9014 add/edit more largefiles
436 7:daea875e9014 add/edit more largefiles
435 6:4355d653f84f edit files yet again
437 6:4355d653f84f edit files yet again
436 5:9d5af5072dbd edit files again
438 5:9d5af5072dbd edit files again
437 4:74c02385b94c move files
439 4:74c02385b94c move files
438 3:9e8fbc4bce62 copy files
440 3:9e8fbc4bce62 copy files
439 2:51a0ae4d5864 remove files
441 2:51a0ae4d5864 remove files
440 1:ce8896473775 edit files
442 1:ce8896473775 edit files
441 0:30d30fe6a5be add files
443 0:30d30fe6a5be add files
442 $ cat normal3
444 $ cat normal3
443 normal3-modified
445 normal3-modified
444 $ cat sub/normal4
446 $ cat sub/normal4
445 normal4-modified
447 normal4-modified
446 $ cat sub/large4
448 $ cat sub/large4
447 large4-modified
449 large4-modified
448 $ cat sub2/large6
450 $ cat sub2/large6
449 large6-modified
451 large6-modified
450 $ cat sub2/large7
452 $ cat sub2/large7
451 large7
453 large7
452 $ cd ../e
454 $ cd ../e
453 $ hg pull ../b
455 $ hg pull ../b
454 pulling from ../b
456 pulling from ../b
455 searching for changes
457 searching for changes
456 adding changesets
458 adding changesets
457 adding manifests
459 adding manifests
458 adding file changes
460 adding file changes
459 added 1 changesets with 2 changes to 2 files (+1 heads)
461 added 1 changesets with 2 changes to 2 files (+1 heads)
460 (run 'hg heads' to see heads, 'hg merge' to merge)
462 (run 'hg heads' to see heads, 'hg merge' to merge)
461 caching new largefiles
463 caching new largefiles
462 0 largefiles cached
464 0 largefiles cached
463 $ hg rebase
465 $ hg rebase
464 Invoking status precommit hook
466 Invoking status precommit hook
465 M sub/normal4
467 M sub/normal4
466 M sub2/large6
468 M sub2/large6
467 saved backup bundle to $TESTTMP/e/.hg/strip-backup/f574fb32bb45-backup.hg
469 saved backup bundle to $TESTTMP/e/.hg/strip-backup/f574fb32bb45-backup.hg
468 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
470 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
469 9:598410d3eb9a modify normal file largefile in repo d
471 9:598410d3eb9a modify normal file largefile in repo d
470 8:a381d2c8c80e modify normal file and largefile in repo b
472 8:a381d2c8c80e modify normal file and largefile in repo b
471 7:daea875e9014 add/edit more largefiles
473 7:daea875e9014 add/edit more largefiles
472 6:4355d653f84f edit files yet again
474 6:4355d653f84f edit files yet again
473 5:9d5af5072dbd edit files again
475 5:9d5af5072dbd edit files again
474 4:74c02385b94c move files
476 4:74c02385b94c move files
475 3:9e8fbc4bce62 copy files
477 3:9e8fbc4bce62 copy files
476 2:51a0ae4d5864 remove files
478 2:51a0ae4d5864 remove files
477 1:ce8896473775 edit files
479 1:ce8896473775 edit files
478 0:30d30fe6a5be add files
480 0:30d30fe6a5be add files
479 $ cat normal3
481 $ cat normal3
480 normal3-modified
482 normal3-modified
481 $ cat sub/normal4
483 $ cat sub/normal4
482 normal4-modified
484 normal4-modified
483 $ cat sub/large4
485 $ cat sub/large4
484 large4-modified
486 large4-modified
485 $ cat sub2/large6
487 $ cat sub2/large6
486 large6-modified
488 large6-modified
487 $ cat sub2/large7
489 $ cat sub2/large7
488 large7
490 large7
489
491
490 Rollback on largefiles.
492 Rollback on largefiles.
491
493
492 $ echo large4-modified-again > sub/large4
494 $ echo large4-modified-again > sub/large4
493 $ hg commit -m "Modify large4 again"
495 $ hg commit -m "Modify large4 again"
494 Invoking status precommit hook
496 Invoking status precommit hook
495 M sub/large4
497 M sub/large4
496 $ hg rollback
498 $ hg rollback
497 repository tip rolled back to revision 9 (undo commit)
499 repository tip rolled back to revision 9 (undo commit)
498 working directory now based on revision 9
500 working directory now based on revision 9
499 $ hg st
501 $ hg st
500 M sub/large4
502 M sub/large4
501 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
503 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
502 9:598410d3eb9a modify normal file largefile in repo d
504 9:598410d3eb9a modify normal file largefile in repo d
503 8:a381d2c8c80e modify normal file and largefile in repo b
505 8:a381d2c8c80e modify normal file and largefile in repo b
504 7:daea875e9014 add/edit more largefiles
506 7:daea875e9014 add/edit more largefiles
505 6:4355d653f84f edit files yet again
507 6:4355d653f84f edit files yet again
506 5:9d5af5072dbd edit files again
508 5:9d5af5072dbd edit files again
507 4:74c02385b94c move files
509 4:74c02385b94c move files
508 3:9e8fbc4bce62 copy files
510 3:9e8fbc4bce62 copy files
509 2:51a0ae4d5864 remove files
511 2:51a0ae4d5864 remove files
510 1:ce8896473775 edit files
512 1:ce8896473775 edit files
511 0:30d30fe6a5be add files
513 0:30d30fe6a5be add files
512 $ cat sub/large4
514 $ cat sub/large4
513 large4-modified-again
515 large4-modified-again
514
516
515 "update --check" refuses to update with uncommitted changes.
517 "update --check" refuses to update with uncommitted changes.
516 $ hg update --check 8
518 $ hg update --check 8
517 abort: uncommitted local changes
519 abort: uncommitted local changes
518 [255]
520 [255]
519
521
520 "update --clean" leaves correct largefiles in working copy.
522 "update --clean" leaves correct largefiles in working copy.
521
523
522 $ hg update --clean
524 $ hg update --clean
523 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
525 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
524 getting changed largefiles
526 getting changed largefiles
525 1 largefiles updated, 0 removed
527 1 largefiles updated, 0 removed
526 $ cat normal3
528 $ cat normal3
527 normal3-modified
529 normal3-modified
528 $ cat sub/normal4
530 $ cat sub/normal4
529 normal4-modified
531 normal4-modified
530 $ cat sub/large4
532 $ cat sub/large4
531 large4-modified
533 large4-modified
532 $ cat sub2/large6
534 $ cat sub2/large6
533 large6-modified
535 large6-modified
534 $ cat sub2/large7
536 $ cat sub2/large7
535 large7
537 large7
536
538
537 Now "update check" is happy.
539 Now "update check" is happy.
538 $ hg update --check 8
540 $ hg update --check 8
539 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
541 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
540 getting changed largefiles
542 getting changed largefiles
541 1 largefiles updated, 0 removed
543 1 largefiles updated, 0 removed
542 $ hg update --check
544 $ hg update --check
543 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
545 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
544 getting changed largefiles
546 getting changed largefiles
545 1 largefiles updated, 0 removed
547 1 largefiles updated, 0 removed
546
548
547 Test removing empty largefiles directories on update
549 Test removing empty largefiles directories on update
548 $ test -d sub2 && echo "sub2 exists"
550 $ test -d sub2 && echo "sub2 exists"
549 sub2 exists
551 sub2 exists
550 $ hg update -q null
552 $ hg update -q null
551 $ test -d sub2 && echo "error: sub2 should not exist anymore"
553 $ test -d sub2 && echo "error: sub2 should not exist anymore"
552 [1]
554 [1]
553 $ hg update -q
555 $ hg update -q
554
556
555 Test hg remove removes empty largefiles directories
557 Test hg remove removes empty largefiles directories
556 $ test -d sub2 && echo "sub2 exists"
558 $ test -d sub2 && echo "sub2 exists"
557 sub2 exists
559 sub2 exists
558 $ hg remove sub2/*
560 $ hg remove sub2/*
559 $ test -d sub2 && echo "error: sub2 should not exist anymore"
561 $ test -d sub2 && echo "error: sub2 should not exist anymore"
560 [1]
562 [1]
561 $ hg revert sub2/large6 sub2/large7
563 $ hg revert sub2/large6 sub2/large7
562
564
563 "revert" works on largefiles (and normal files too).
565 "revert" works on largefiles (and normal files too).
564 $ echo hack3 >> normal3
566 $ echo hack3 >> normal3
565 $ echo hack4 >> sub/normal4
567 $ echo hack4 >> sub/normal4
566 $ echo hack4 >> sub/large4
568 $ echo hack4 >> sub/large4
567 $ rm sub2/large6
569 $ rm sub2/large6
568 $ hg revert sub2/large6
570 $ hg revert sub2/large6
569 $ hg rm sub2/large6
571 $ hg rm sub2/large6
570 $ echo new >> sub2/large8
572 $ echo new >> sub2/large8
571 $ hg add --large sub2/large8
573 $ hg add --large sub2/large8
572 # XXX we don't really want to report that we're reverting the standin;
574 # XXX we don't really want to report that we're reverting the standin;
573 # that's just an implementation detail. But I don't see an obvious fix. ;-(
575 # that's just an implementation detail. But I don't see an obvious fix. ;-(
574 $ hg revert sub
576 $ hg revert sub
575 reverting .hglf/sub/large4 (glob)
577 reverting .hglf/sub/large4 (glob)
576 reverting sub/normal4 (glob)
578 reverting sub/normal4 (glob)
577 $ hg status
579 $ hg status
578 M normal3
580 M normal3
579 A sub2/large8
581 A sub2/large8
580 R sub2/large6
582 R sub2/large6
581 ? sub/large4.orig
583 ? sub/large4.orig
582 ? sub/normal4.orig
584 ? sub/normal4.orig
583 $ cat sub/normal4
585 $ cat sub/normal4
584 normal4-modified
586 normal4-modified
585 $ cat sub/large4
587 $ cat sub/large4
586 large4-modified
588 large4-modified
587 $ hg revert -a --no-backup
589 $ hg revert -a --no-backup
588 undeleting .hglf/sub2/large6 (glob)
590 undeleting .hglf/sub2/large6 (glob)
589 forgetting .hglf/sub2/large8 (glob)
591 forgetting .hglf/sub2/large8 (glob)
590 reverting normal3
592 reverting normal3
591 $ hg status
593 $ hg status
592 ? sub/large4.orig
594 ? sub/large4.orig
593 ? sub/normal4.orig
595 ? sub/normal4.orig
594 ? sub2/large8
596 ? sub2/large8
595 $ cat normal3
597 $ cat normal3
596 normal3-modified
598 normal3-modified
597 $ cat sub2/large6
599 $ cat sub2/large6
598 large6-modified
600 large6-modified
599 $ rm sub/*.orig sub2/large8
601 $ rm sub/*.orig sub2/large8
600
602
601 revert some files to an older revision
603 revert some files to an older revision
602 $ hg revert --no-backup -r 8 sub2
604 $ hg revert --no-backup -r 8 sub2
603 reverting .hglf/sub2/large6 (glob)
605 reverting .hglf/sub2/large6 (glob)
604 $ cat sub2/large6
606 $ cat sub2/large6
605 large6
607 large6
606 $ hg revert --no-backup sub2
608 $ hg revert --no-backup sub2
607 reverting .hglf/sub2/large6 (glob)
609 reverting .hglf/sub2/large6 (glob)
608 $ hg status
610 $ hg status
609
611
610 "verify --large" actually verifies largefiles
612 "verify --large" actually verifies largefiles
611
613
612 $ hg verify --large
614 $ hg verify --large
613 checking changesets
615 checking changesets
614 checking manifests
616 checking manifests
615 crosschecking files in changesets and manifests
617 crosschecking files in changesets and manifests
616 checking files
618 checking files
617 10 files, 10 changesets, 28 total revisions
619 10 files, 10 changesets, 28 total revisions
618 searching 1 changesets for largefiles
620 searching 1 changesets for largefiles
619 verified existence of 3 revisions of 3 largefiles
621 verified existence of 3 revisions of 3 largefiles
620
622
621 Merging does not revert to old versions of largefiles and also check
623 Merging does not revert to old versions of largefiles and also check
622 that merging after having pulled from a non-default remote works
624 that merging after having pulled from a non-default remote works
623 correctly.
625 correctly.
624
626
625 $ cd ..
627 $ cd ..
626 $ hg clone -r 7 e temp
628 $ hg clone -r 7 e temp
627 adding changesets
629 adding changesets
628 adding manifests
630 adding manifests
629 adding file changes
631 adding file changes
630 added 8 changesets with 24 changes to 10 files
632 added 8 changesets with 24 changes to 10 files
631 updating to branch default
633 updating to branch default
632 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
634 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
633 getting changed largefiles
635 getting changed largefiles
634 3 largefiles updated, 0 removed
636 3 largefiles updated, 0 removed
635 $ hg clone temp f
637 $ hg clone temp f
636 updating to branch default
638 updating to branch default
637 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
639 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
638 getting changed largefiles
640 getting changed largefiles
639 3 largefiles updated, 0 removed
641 3 largefiles updated, 0 removed
640 # Delete the largefiles in the largefiles system cache so that we have an
642 # Delete the largefiles in the largefiles system cache so that we have an
641 # opportunity to test that caching after a pull works.
643 # opportunity to test that caching after a pull works.
642 $ rm ${USERCACHE}/*
644 $ rm ${USERCACHE}/*
643 $ cd f
645 $ cd f
644 $ echo "large4-merge-test" > sub/large4
646 $ echo "large4-merge-test" > sub/large4
645 $ hg commit -m "Modify large4 to test merge"
647 $ hg commit -m "Modify large4 to test merge"
646 Invoking status precommit hook
648 Invoking status precommit hook
647 M sub/large4
649 M sub/large4
648 $ hg pull ../e
650 $ hg pull ../e
649 pulling from ../e
651 pulling from ../e
650 searching for changes
652 searching for changes
651 adding changesets
653 adding changesets
652 adding manifests
654 adding manifests
653 adding file changes
655 adding file changes
654 added 2 changesets with 4 changes to 4 files (+1 heads)
656 added 2 changesets with 4 changes to 4 files (+1 heads)
655 (run 'hg heads' to see heads, 'hg merge' to merge)
657 (run 'hg heads' to see heads, 'hg merge' to merge)
656 caching new largefiles
658 caching new largefiles
657 2 largefiles cached
659 2 largefiles cached
658 $ hg merge
660 $ hg merge
659 merging sub/large4
661 merging sub/large4
660 largefile sub/large4 has a merge conflict
662 largefile sub/large4 has a merge conflict
661 keep (l)ocal or take (o)ther? l
663 keep (l)ocal or take (o)ther? l
662 3 files updated, 1 files merged, 0 files removed, 0 files unresolved
664 3 files updated, 1 files merged, 0 files removed, 0 files unresolved
663 (branch merge, don't forget to commit)
665 (branch merge, don't forget to commit)
664 getting changed largefiles
666 getting changed largefiles
665 1 largefiles updated, 0 removed
667 1 largefiles updated, 0 removed
666 $ hg commit -m "Merge repos e and f"
668 $ hg commit -m "Merge repos e and f"
667 Invoking status precommit hook
669 Invoking status precommit hook
668 M normal3
670 M normal3
669 M sub/normal4
671 M sub/normal4
670 M sub2/large6
672 M sub2/large6
671 $ cat normal3
673 $ cat normal3
672 normal3-modified
674 normal3-modified
673 $ cat sub/normal4
675 $ cat sub/normal4
674 normal4-modified
676 normal4-modified
675 $ cat sub/large4
677 $ cat sub/large4
676 large4-merge-test
678 large4-merge-test
677 $ cat sub2/large6
679 $ cat sub2/large6
678 large6-modified
680 large6-modified
679 $ cat sub2/large7
681 $ cat sub2/large7
680 large7
682 large7
681
683
682 Test status after merging with a branch that introduces a new largefile:
684 Test status after merging with a branch that introduces a new largefile:
683
685
684 $ echo large > large
686 $ echo large > large
685 $ hg add --large large
687 $ hg add --large large
686 $ hg commit -m 'add largefile'
688 $ hg commit -m 'add largefile'
687 Invoking status precommit hook
689 Invoking status precommit hook
688 A large
690 A large
689 $ hg update -q ".^"
691 $ hg update -q ".^"
690 $ echo change >> normal3
692 $ echo change >> normal3
691 $ hg commit -m 'some change'
693 $ hg commit -m 'some change'
692 Invoking status precommit hook
694 Invoking status precommit hook
693 M normal3
695 M normal3
694 created new head
696 created new head
695 $ hg merge
697 $ hg merge
696 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
698 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
697 (branch merge, don't forget to commit)
699 (branch merge, don't forget to commit)
698 getting changed largefiles
700 getting changed largefiles
699 1 largefiles updated, 0 removed
701 1 largefiles updated, 0 removed
700 $ hg status
702 $ hg status
701 M large
703 M large
702
704
703 Test that a normal file and a largefile with the same name and path cannot
705 Test that a normal file and a largefile with the same name and path cannot
704 coexist.
706 coexist.
705
707
706 $ rm sub2/large7
708 $ rm sub2/large7
707 $ echo "largeasnormal" > sub2/large7
709 $ echo "largeasnormal" > sub2/large7
708 $ hg add sub2/large7
710 $ hg add sub2/large7
709 sub2/large7 already a largefile
711 sub2/large7 already a largefile
710
712
711 Test that transplanting a largefile change works correctly.
713 Test that transplanting a largefile change works correctly.
712
714
713 $ cd ..
715 $ cd ..
714 $ hg clone -r 8 d g
716 $ hg clone -r 8 d g
715 adding changesets
717 adding changesets
716 adding manifests
718 adding manifests
717 adding file changes
719 adding file changes
718 added 9 changesets with 26 changes to 10 files
720 added 9 changesets with 26 changes to 10 files
719 updating to branch default
721 updating to branch default
720 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
722 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
721 getting changed largefiles
723 getting changed largefiles
722 3 largefiles updated, 0 removed
724 3 largefiles updated, 0 removed
723 $ cd g
725 $ cd g
724 $ hg transplant -s ../d 598410d3eb9a
726 $ hg transplant -s ../d 598410d3eb9a
725 searching for changes
727 searching for changes
726 searching for changes
728 searching for changes
727 adding changesets
729 adding changesets
728 adding manifests
730 adding manifests
729 adding file changes
731 adding file changes
730 added 1 changesets with 2 changes to 2 files
732 added 1 changesets with 2 changes to 2 files
731 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
733 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
732 9:598410d3eb9a modify normal file largefile in repo d
734 9:598410d3eb9a modify normal file largefile in repo d
733 8:a381d2c8c80e modify normal file and largefile in repo b
735 8:a381d2c8c80e modify normal file and largefile in repo b
734 7:daea875e9014 add/edit more largefiles
736 7:daea875e9014 add/edit more largefiles
735 6:4355d653f84f edit files yet again
737 6:4355d653f84f edit files yet again
736 5:9d5af5072dbd edit files again
738 5:9d5af5072dbd edit files again
737 4:74c02385b94c move files
739 4:74c02385b94c move files
738 3:9e8fbc4bce62 copy files
740 3:9e8fbc4bce62 copy files
739 2:51a0ae4d5864 remove files
741 2:51a0ae4d5864 remove files
740 1:ce8896473775 edit files
742 1:ce8896473775 edit files
741 0:30d30fe6a5be add files
743 0:30d30fe6a5be add files
742 $ cat normal3
744 $ cat normal3
743 normal3-modified
745 normal3-modified
744 $ cat sub/normal4
746 $ cat sub/normal4
745 normal4-modified
747 normal4-modified
746 $ cat sub/large4
748 $ cat sub/large4
747 large4-modified
749 large4-modified
748 $ cat sub2/large6
750 $ cat sub2/large6
749 large6-modified
751 large6-modified
750 $ cat sub2/large7
752 $ cat sub2/large7
751 large7
753 large7
752
754
753 Test that renaming a largefile results in correct output for status
755 Test that renaming a largefile results in correct output for status
754
756
755 $ hg rename sub/large4 large4-renamed
757 $ hg rename sub/large4 large4-renamed
756 $ hg commit -m "test rename output"
758 $ hg commit -m "test rename output"
757 Invoking status precommit hook
759 Invoking status precommit hook
758 A large4-renamed
760 A large4-renamed
759 R sub/large4
761 R sub/large4
760 $ cat large4-renamed
762 $ cat large4-renamed
761 large4-modified
763 large4-modified
762 $ cd sub2
764 $ cd sub2
763 $ hg rename large6 large6-renamed
765 $ hg rename large6 large6-renamed
764 $ hg st
766 $ hg st
765 A sub2/large6-renamed
767 A sub2/large6-renamed
766 R sub2/large6
768 R sub2/large6
767 $ cd ..
769 $ cd ..
768
770
769 Test --normal flag
771 Test --normal flag
770
772
771 $ dd if=/dev/urandom bs=2k count=11k > new-largefile 2> /dev/null
773 $ dd if=/dev/urandom bs=2k count=11k > new-largefile 2> /dev/null
772 $ hg add --normal --large new-largefile
774 $ hg add --normal --large new-largefile
773 abort: --normal cannot be used with --large
775 abort: --normal cannot be used with --large
774 [255]
776 [255]
775 $ hg add --normal new-largefile
777 $ hg add --normal new-largefile
776 new-largefile: up to 69 MB of RAM may be required to manage this file
778 new-largefile: up to 69 MB of RAM may be required to manage this file
777 (use 'hg revert new-largefile' to cancel the pending addition)
779 (use 'hg revert new-largefile' to cancel the pending addition)
778 $ cd ..
780 $ cd ..
779
781
780 vanilla clients not locked out from largefiles servers on vanilla repos
782 vanilla clients not locked out from largefiles servers on vanilla repos
781 $ mkdir r1
783 $ mkdir r1
782 $ cd r1
784 $ cd r1
783 $ hg init
785 $ hg init
784 $ echo c1 > f1
786 $ echo c1 > f1
785 $ hg add f1
787 $ hg add f1
786 $ hg commit -m "m1"
788 $ hg commit -m "m1"
787 Invoking status precommit hook
789 Invoking status precommit hook
788 A f1
790 A f1
789 $ cd ..
791 $ cd ..
790 $ hg serve -R r1 -d -p $HGPORT --pid-file hg.pid
792 $ hg serve -R r1 -d -p $HGPORT --pid-file hg.pid
791 $ cat hg.pid >> $DAEMON_PIDS
793 $ cat hg.pid >> $DAEMON_PIDS
792 $ hg --config extensions.largefiles=! clone http://localhost:$HGPORT r2
794 $ hg --config extensions.largefiles=! clone http://localhost:$HGPORT r2
793 requesting all changes
795 requesting all changes
794 adding changesets
796 adding changesets
795 adding manifests
797 adding manifests
796 adding file changes
798 adding file changes
797 added 1 changesets with 1 changes to 1 files
799 added 1 changesets with 1 changes to 1 files
798 updating to branch default
800 updating to branch default
799 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
801 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
800
802
801 largefiles clients still work with vanilla servers
803 largefiles clients still work with vanilla servers
802 $ hg --config extensions.largefiles=! serve -R r1 -d -p $HGPORT1 --pid-file hg.pid
804 $ hg --config extensions.largefiles=! serve -R r1 -d -p $HGPORT1 --pid-file hg.pid
803 $ cat hg.pid >> $DAEMON_PIDS
805 $ cat hg.pid >> $DAEMON_PIDS
804 $ hg clone http://localhost:$HGPORT1 r3
806 $ hg clone http://localhost:$HGPORT1 r3
805 requesting all changes
807 requesting all changes
806 adding changesets
808 adding changesets
807 adding manifests
809 adding manifests
808 adding file changes
810 adding file changes
809 added 1 changesets with 1 changes to 1 files
811 added 1 changesets with 1 changes to 1 files
810 updating to branch default
812 updating to branch default
811 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
813 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
812
814
813 vanilla clients locked out from largefiles http repos
815 vanilla clients locked out from largefiles http repos
814 $ mkdir r4
816 $ mkdir r4
815 $ cd r4
817 $ cd r4
816 $ hg init
818 $ hg init
817 $ echo c1 > f1
819 $ echo c1 > f1
818 $ hg add --large f1
820 $ hg add --large f1
819 $ hg commit -m "m1"
821 $ hg commit -m "m1"
820 Invoking status precommit hook
822 Invoking status precommit hook
821 A f1
823 A f1
822 $ cd ..
824 $ cd ..
823 $ hg serve -R r4 -d -p $HGPORT2 --pid-file hg.pid
825 $ hg serve -R r4 -d -p $HGPORT2 --pid-file hg.pid
824 $ cat hg.pid >> $DAEMON_PIDS
826 $ cat hg.pid >> $DAEMON_PIDS
825 $ hg --config extensions.largefiles=! clone http://localhost:$HGPORT2 r5
827 $ hg --config extensions.largefiles=! clone http://localhost:$HGPORT2 r5
826 abort: remote error:
828 abort: remote error:
827
829
828 This repository uses the largefiles extension.
830 This repository uses the largefiles extension.
829
831
830 Please enable it in your Mercurial config file.
832 Please enable it in your Mercurial config file.
831 [255]
833 [255]
832
834
833 used all HGPORTs, kill all daemons
835 used all HGPORTs, kill all daemons
834 $ "$TESTDIR/killdaemons.py"
836 $ "$TESTDIR/killdaemons.py"
835
837
836 vanilla clients locked out from largefiles ssh repos
838 vanilla clients locked out from largefiles ssh repos
837 $ hg --config extensions.largefiles=! clone -e "python $TESTDIR/dummyssh" ssh://user@dummy/r4 r5
839 $ hg --config extensions.largefiles=! clone -e "python $TESTDIR/dummyssh" ssh://user@dummy/r4 r5
838 abort: remote error:
840 abort: remote error:
839
841
840 This repository uses the largefiles extension.
842 This repository uses the largefiles extension.
841
843
842 Please enable it in your Mercurial config file.
844 Please enable it in your Mercurial config file.
843 [255]
845 [255]
844
846
845 largefiles clients refuse to push largefiles repos to vanilla servers
847 largefiles clients refuse to push largefiles repos to vanilla servers
846 $ mkdir r6
848 $ mkdir r6
847 $ cd r6
849 $ cd r6
848 $ hg init
850 $ hg init
849 $ echo c1 > f1
851 $ echo c1 > f1
850 $ hg add f1
852 $ hg add f1
851 $ hg commit -m "m1"
853 $ hg commit -m "m1"
852 Invoking status precommit hook
854 Invoking status precommit hook
853 A f1
855 A f1
854 $ cat >> .hg/hgrc <<!
856 $ cat >> .hg/hgrc <<!
855 > [web]
857 > [web]
856 > push_ssl = false
858 > push_ssl = false
857 > allow_push = *
859 > allow_push = *
858 > !
860 > !
859 $ cd ..
861 $ cd ..
860 $ hg clone r6 r7
862 $ hg clone r6 r7
861 updating to branch default
863 updating to branch default
862 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
864 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
863 $ cd r7
865 $ cd r7
864 $ echo c2 > f2
866 $ echo c2 > f2
865 $ hg add --large f2
867 $ hg add --large f2
866 $ hg commit -m "m2"
868 $ hg commit -m "m2"
867 Invoking status precommit hook
869 Invoking status precommit hook
868 A f2
870 A f2
869 $ hg --config extensions.largefiles=! -R ../r6 serve -d -p $HGPORT --pid-file ../hg.pid
871 $ hg --config extensions.largefiles=! -R ../r6 serve -d -p $HGPORT --pid-file ../hg.pid
870 $ cat ../hg.pid >> $DAEMON_PIDS
872 $ cat ../hg.pid >> $DAEMON_PIDS
871 $ hg push http://localhost:$HGPORT
873 $ hg push http://localhost:$HGPORT
872 pushing to http://localhost:$HGPORT/
874 pushing to http://localhost:$HGPORT/
873 searching for changes
875 searching for changes
874 abort: http://localhost:$HGPORT/ does not appear to be a largefile store
876 abort: http://localhost:$HGPORT/ does not appear to be a largefile store
875 [255]
877 [255]
876 $ cd ..
878 $ cd ..
877
879
878 putlfile errors are shown (issue3123)
880 putlfile errors are shown (issue3123)
879 Corrupt the cached largefile in r7
881 Corrupt the cached largefile in r7
880 $ echo corruption > $USERCACHE/4cdac4d8b084d0b599525cf732437fb337d422a8
882 $ echo corruption > $USERCACHE/4cdac4d8b084d0b599525cf732437fb337d422a8
881 $ hg init empty
883 $ hg init empty
882 $ hg serve -R empty -d -p $HGPORT1 --pid-file hg.pid \
884 $ hg serve -R empty -d -p $HGPORT1 --pid-file hg.pid \
883 > --config 'web.allow_push=*' --config web.push_ssl=False
885 > --config 'web.allow_push=*' --config web.push_ssl=False
884 $ cat hg.pid >> $DAEMON_PIDS
886 $ cat hg.pid >> $DAEMON_PIDS
885 $ hg push -R r7 http://localhost:$HGPORT1
887 $ hg push -R r7 http://localhost:$HGPORT1
886 pushing to http://localhost:$HGPORT1/
888 pushing to http://localhost:$HGPORT1/
887 searching for changes
889 searching for changes
888 remote: largefiles: failed to put 4cdac4d8b084d0b599525cf732437fb337d422a8 into store: largefile contents do not match hash
890 remote: largefiles: failed to put 4cdac4d8b084d0b599525cf732437fb337d422a8 into store: largefile contents do not match hash
889 abort: remotestore: could not put $TESTTMP/r7/.hg/largefiles/4cdac4d8b084d0b599525cf732437fb337d422a8 to remote store http://localhost:$HGPORT1/
891 abort: remotestore: could not put $TESTTMP/r7/.hg/largefiles/4cdac4d8b084d0b599525cf732437fb337d422a8 to remote store http://localhost:$HGPORT1/
890 [255]
892 [255]
891 $ rm -rf empty
893 $ rm -rf empty
892
894
893 Clone a local repository owned by another user
895 Clone a local repository owned by another user
894 We have to simulate that here by setting $HOME and removing write permissions
896 We have to simulate that here by setting $HOME and removing write permissions
895 $ ORIGHOME="$HOME"
897 $ ORIGHOME="$HOME"
896 $ mkdir alice
898 $ mkdir alice
897 $ HOME="`pwd`/alice"
899 $ HOME="`pwd`/alice"
898 $ cd alice
900 $ cd alice
899 $ hg init pubrepo
901 $ hg init pubrepo
900 $ cd pubrepo
902 $ cd pubrepo
901 $ dd if=/dev/urandom bs=1k count=11k > a-large-file 2> /dev/null
903 $ dd if=/dev/urandom bs=1k count=11k > a-large-file 2> /dev/null
902 $ hg add --large a-large-file
904 $ hg add --large a-large-file
903 $ hg commit -m "Add a large file"
905 $ hg commit -m "Add a large file"
904 Invoking status precommit hook
906 Invoking status precommit hook
905 A a-large-file
907 A a-large-file
906 $ cd ..
908 $ cd ..
907 $ chmod -R a-w pubrepo
909 $ chmod -R a-w pubrepo
908 $ cd ..
910 $ cd ..
909 $ mkdir bob
911 $ mkdir bob
910 $ HOME="`pwd`/bob"
912 $ HOME="`pwd`/bob"
911 $ cd bob
913 $ cd bob
912 $ hg clone --pull ../alice/pubrepo pubrepo
914 $ hg clone --pull ../alice/pubrepo pubrepo
913 requesting all changes
915 requesting all changes
914 adding changesets
916 adding changesets
915 adding manifests
917 adding manifests
916 adding file changes
918 adding file changes
917 added 1 changesets with 1 changes to 1 files
919 added 1 changesets with 1 changes to 1 files
918 updating to branch default
920 updating to branch default
919 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
921 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
920 getting changed largefiles
922 getting changed largefiles
921 1 largefiles updated, 0 removed
923 1 largefiles updated, 0 removed
922 $ cd ..
924 $ cd ..
923 $ chmod -R u+w alice/pubrepo
925 $ chmod -R u+w alice/pubrepo
924 $ HOME="$ORIGHOME"
926 $ HOME="$ORIGHOME"
925
927
926 Symlink to a large largefile should behave the same as a symlink to a normal file
928 Symlink to a large largefile should behave the same as a symlink to a normal file
927 $ hg init largesymlink
929 $ hg init largesymlink
928 $ cd largesymlink
930 $ cd largesymlink
929 $ dd if=/dev/zero bs=1k count=10k of=largefile 2>/dev/null
931 $ dd if=/dev/zero bs=1k count=10k of=largefile 2>/dev/null
930 $ hg add --large largefile
932 $ hg add --large largefile
931 $ hg commit -m "commit a large file"
933 $ hg commit -m "commit a large file"
932 Invoking status precommit hook
934 Invoking status precommit hook
933 A largefile
935 A largefile
934 $ ln -s largefile largelink
936 $ ln -s largefile largelink
935 $ hg add largelink
937 $ hg add largelink
936 $ hg commit -m "commit a large symlink"
938 $ hg commit -m "commit a large symlink"
937 Invoking status precommit hook
939 Invoking status precommit hook
938 A largelink
940 A largelink
939 $ rm -f largelink
941 $ rm -f largelink
940 $ hg up >/dev/null
942 $ hg up >/dev/null
941 $ test -f largelink
943 $ test -f largelink
942 [1]
944 [1]
943 $ test -L largelink
945 $ test -L largelink
944 [1]
946 [1]
945 $ rm -f largelink # make next part of the test independent of the previous
947 $ rm -f largelink # make next part of the test independent of the previous
946 $ hg up -C >/dev/null
948 $ hg up -C >/dev/null
947 $ test -f largelink
949 $ test -f largelink
948 $ test -L largelink
950 $ test -L largelink
949 $ cd ..
951 $ cd ..
950
952
951 test for pattern matching on 'hg status':
953 test for pattern matching on 'hg status':
952 to boost performance, largefiles checks whether specified patterns are
954 to boost performance, largefiles checks whether specified patterns are
953 related to largefiles in working directory (NOT to STANDIN) or not.
955 related to largefiles in working directory (NOT to STANDIN) or not.
954
956
955 $ hg init statusmatch
957 $ hg init statusmatch
956 $ cd statusmatch
958 $ cd statusmatch
957
959
958 $ mkdir -p a/b/c/d
960 $ mkdir -p a/b/c/d
959 $ echo normal > a/b/c/d/e.normal.txt
961 $ echo normal > a/b/c/d/e.normal.txt
960 $ hg add a/b/c/d/e.normal.txt
962 $ hg add a/b/c/d/e.normal.txt
961 $ echo large > a/b/c/d/e.large.txt
963 $ echo large > a/b/c/d/e.large.txt
962 $ hg add --large a/b/c/d/e.large.txt
964 $ hg add --large a/b/c/d/e.large.txt
963 $ mkdir -p a/b/c/x
965 $ mkdir -p a/b/c/x
964 $ echo normal > a/b/c/x/y.normal.txt
966 $ echo normal > a/b/c/x/y.normal.txt
965 $ hg add a/b/c/x/y.normal.txt
967 $ hg add a/b/c/x/y.normal.txt
966 $ hg commit -m 'add files'
968 $ hg commit -m 'add files'
967 Invoking status precommit hook
969 Invoking status precommit hook
968 A a/b/c/d/e.large.txt
970 A a/b/c/d/e.large.txt
969 A a/b/c/d/e.normal.txt
971 A a/b/c/d/e.normal.txt
970 A a/b/c/x/y.normal.txt
972 A a/b/c/x/y.normal.txt
971
973
972 (1) no pattern: no performance boost
974 (1) no pattern: no performance boost
973 $ hg status -A
975 $ hg status -A
974 C a/b/c/d/e.large.txt
976 C a/b/c/d/e.large.txt
975 C a/b/c/d/e.normal.txt
977 C a/b/c/d/e.normal.txt
976 C a/b/c/x/y.normal.txt
978 C a/b/c/x/y.normal.txt
977
979
978 (2) pattern not related to largefiles: performance boost
980 (2) pattern not related to largefiles: performance boost
979 $ hg status -A a/b/c/x
981 $ hg status -A a/b/c/x
980 C a/b/c/x/y.normal.txt
982 C a/b/c/x/y.normal.txt
981
983
982 (3) pattern related to largefiles: no performance boost
984 (3) pattern related to largefiles: no performance boost
983 $ hg status -A a/b/c/d
985 $ hg status -A a/b/c/d
984 C a/b/c/d/e.large.txt
986 C a/b/c/d/e.large.txt
985 C a/b/c/d/e.normal.txt
987 C a/b/c/d/e.normal.txt
986
988
987 (4) pattern related to STANDIN (not to largefiles): performance boost
989 (4) pattern related to STANDIN (not to largefiles): performance boost
988 $ hg status -A .hglf/a
990 $ hg status -A .hglf/a
989 C .hglf/a/b/c/d/e.large.txt
991 C .hglf/a/b/c/d/e.large.txt
990
992
991 (5) mixed case: no performance boost
993 (5) mixed case: no performance boost
992 $ hg status -A a/b/c/x a/b/c/d
994 $ hg status -A a/b/c/x a/b/c/d
993 C a/b/c/d/e.large.txt
995 C a/b/c/d/e.large.txt
994 C a/b/c/d/e.normal.txt
996 C a/b/c/d/e.normal.txt
995 C a/b/c/x/y.normal.txt
997 C a/b/c/x/y.normal.txt
996
998
997 verify that largefiles doesn't break filesets
999 verify that largefiles doesn't break filesets
998
1000
999 $ hg log --rev . --exclude "set:binary()"
1001 $ hg log --rev . --exclude "set:binary()"
1000 changeset: 0:41bd42f10efa
1002 changeset: 0:41bd42f10efa
1001 tag: tip
1003 tag: tip
1002 user: test
1004 user: test
1003 date: Thu Jan 01 00:00:00 1970 +0000
1005 date: Thu Jan 01 00:00:00 1970 +0000
1004 summary: add files
1006 summary: add files
1005
1007
1006
1008
1007 $ cd ..
1009 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now