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