##// END OF EJS Templates
largefiles: check whether specified patterns are related to largefiles strictly...
FUJIWARA Katsunori -
r16110:41417443 stable
parent child Browse files
Show More
@@ -1,448 +1,450
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 result = super(lfiles_ctx, self).filectx(path,
67 fileid, filelog)
67 fileid, filelog)
68 except error.LookupError:
68 except error.LookupError:
69 # Adding a null character will cause Mercurial to
69 # Adding a null character will cause Mercurial to
70 # identify this as a binary file.
70 # identify this as a binary file.
71 result = super(lfiles_ctx, self).filectx(
71 result = super(lfiles_ctx, self).filectx(
72 lfutil.standin(path), fileid, filelog)
72 lfutil.standin(path), fileid, filelog)
73 olddata = result.data
73 olddata = result.data
74 result.data = lambda: olddata() + '\0'
74 result.data = lambda: olddata() + '\0'
75 return result
75 return result
76 ctx.__class__ = lfiles_ctx
76 ctx.__class__ = lfiles_ctx
77 return ctx
77 return ctx
78
78
79 # Figure out the status of big files and insert them into the
79 # Figure out the status of big files and insert them into the
80 # appropriate list in the result. Also removes standin files
80 # appropriate list in the result. Also removes standin files
81 # from the listing. Revert to the original status if
81 # from the listing. Revert to the original status if
82 # self.lfstatus is False.
82 # self.lfstatus is False.
83 def status(self, node1='.', node2=None, match=None, ignored=False,
83 def status(self, node1='.', node2=None, match=None, ignored=False,
84 clean=False, unknown=False, listsubrepos=False):
84 clean=False, unknown=False, listsubrepos=False):
85 listignored, listclean, listunknown = ignored, clean, unknown
85 listignored, listclean, listunknown = ignored, clean, unknown
86 if not self.lfstatus:
86 if not self.lfstatus:
87 return super(lfiles_repo, self).status(node1, node2, match,
87 return super(lfiles_repo, self).status(node1, node2, match,
88 listignored, listclean, listunknown, listsubrepos)
88 listignored, listclean, listunknown, listsubrepos)
89 else:
89 else:
90 # some calls in this function rely on the old version of status
90 # some calls in this function rely on the old version of status
91 self.lfstatus = False
91 self.lfstatus = False
92 if isinstance(node1, context.changectx):
92 if isinstance(node1, context.changectx):
93 ctx1 = node1
93 ctx1 = node1
94 else:
94 else:
95 ctx1 = repo[node1]
95 ctx1 = repo[node1]
96 if isinstance(node2, context.changectx):
96 if isinstance(node2, context.changectx):
97 ctx2 = node2
97 ctx2 = node2
98 else:
98 else:
99 ctx2 = repo[node2]
99 ctx2 = repo[node2]
100 working = ctx2.rev() is None
100 working = ctx2.rev() is None
101 parentworking = working and ctx1 == self['.']
101 parentworking = working and ctx1 == self['.']
102
102
103 def inctx(file, ctx):
103 def inctx(file, ctx):
104 try:
104 try:
105 if ctx.rev() is None:
105 if ctx.rev() is None:
106 return file in ctx.manifest()
106 return file in ctx.manifest()
107 ctx[file]
107 ctx[file]
108 return True
108 return True
109 except KeyError:
109 except KeyError:
110 return False
110 return False
111
111
112 if match is None:
112 if match is None:
113 match = match_.always(self.root, self.getcwd())
113 match = match_.always(self.root, self.getcwd())
114
114
115 # First check if there were files specified on the
115 # First check if there were files specified on the
116 # command line. If there were, and none of them were
116 # command line. If there were, and none of them were
117 # largefiles, we should just bail here and let super
117 # largefiles, we should just bail here and let super
118 # handle it -- thus gaining a big performance boost.
118 # handle it -- thus gaining a big performance boost.
119 lfdirstate = lfutil.openlfdirstate(ui, self)
119 lfdirstate = lfutil.openlfdirstate(ui, self)
120 if match.files() and not match.anypats():
120 if match.files() and not match.anypats():
121 matchedfiles = [f for f in match.files() if f in lfdirstate]
121 for f in lfdirstate:
122 if not matchedfiles:
122 if match(f):
123 break
124 else:
123 return super(lfiles_repo, self).status(node1, node2,
125 return super(lfiles_repo, self).status(node1, node2,
124 match, listignored, listclean,
126 match, listignored, listclean,
125 listunknown, listsubrepos)
127 listunknown, listsubrepos)
126
128
127 # Create a copy of match that matches standins instead
129 # Create a copy of match that matches standins instead
128 # of largefiles.
130 # of largefiles.
129 def tostandin(file):
131 def tostandin(file):
130 if inctx(lfutil.standin(file), ctx2):
132 if inctx(lfutil.standin(file), ctx2):
131 return lfutil.standin(file)
133 return lfutil.standin(file)
132 return file
134 return file
133
135
134 # Create a function that we can use to override what is
136 # Create a function that we can use to override what is
135 # normally the ignore matcher. We've already checked
137 # normally the ignore matcher. We've already checked
136 # for ignored files on the first dirstate walk, and
138 # for ignored files on the first dirstate walk, and
137 # unecessarily re-checking here causes a huge performance
139 # unecessarily re-checking here causes a huge performance
138 # hit because lfdirstate only knows about largefiles
140 # hit because lfdirstate only knows about largefiles
139 def _ignoreoverride(self):
141 def _ignoreoverride(self):
140 return False
142 return False
141
143
142 m = copy.copy(match)
144 m = copy.copy(match)
143 m._files = [tostandin(f) for f in m._files]
145 m._files = [tostandin(f) for f in m._files]
144
146
145 # Get ignored files here even if we weren't asked for them; we
147 # Get ignored files here even if we weren't asked for them; we
146 # must use the result here for filtering later
148 # must use the result here for filtering later
147 result = super(lfiles_repo, self).status(node1, node2, m,
149 result = super(lfiles_repo, self).status(node1, node2, m,
148 True, clean, unknown, listsubrepos)
150 True, clean, unknown, listsubrepos)
149 if working:
151 if working:
150 try:
152 try:
151 # Any non-largefiles that were explicitly listed must be
153 # Any non-largefiles that were explicitly listed must be
152 # taken out or lfdirstate.status will report an error.
154 # taken out or lfdirstate.status will report an error.
153 # The status of these files was already computed using
155 # The status of these files was already computed using
154 # super's status.
156 # super's status.
155 # Override lfdirstate's ignore matcher to not do
157 # Override lfdirstate's ignore matcher to not do
156 # anything
158 # anything
157 orig_ignore = lfdirstate._ignore
159 orig_ignore = lfdirstate._ignore
158 lfdirstate._ignore = _ignoreoverride
160 lfdirstate._ignore = _ignoreoverride
159
161
160 match._files = [f for f in match._files if f in
162 match._files = [f for f in match._files if f in
161 lfdirstate]
163 lfdirstate]
162 # Don't waste time getting the ignored and unknown
164 # Don't waste time getting the ignored and unknown
163 # files again; we already have them
165 # files again; we already have them
164 s = lfdirstate.status(match, [], False,
166 s = lfdirstate.status(match, [], False,
165 listclean, False)
167 listclean, False)
166 (unsure, modified, added, removed, missing, unknown,
168 (unsure, modified, added, removed, missing, unknown,
167 ignored, clean) = s
169 ignored, clean) = s
168 # Replace the list of ignored and unknown files with
170 # Replace the list of ignored and unknown files with
169 # the previously caclulated lists, and strip out the
171 # the previously caclulated lists, and strip out the
170 # largefiles
172 # largefiles
171 lfiles = set(lfdirstate._map)
173 lfiles = set(lfdirstate._map)
172 ignored = set(result[5]).difference(lfiles)
174 ignored = set(result[5]).difference(lfiles)
173 unknown = set(result[4]).difference(lfiles)
175 unknown = set(result[4]).difference(lfiles)
174 if parentworking:
176 if parentworking:
175 for lfile in unsure:
177 for lfile in unsure:
176 standin = lfutil.standin(lfile)
178 standin = lfutil.standin(lfile)
177 if standin not in ctx1:
179 if standin not in ctx1:
178 # from second parent
180 # from second parent
179 modified.append(lfile)
181 modified.append(lfile)
180 elif ctx1[standin].data().strip() \
182 elif ctx1[standin].data().strip() \
181 != lfutil.hashfile(self.wjoin(lfile)):
183 != lfutil.hashfile(self.wjoin(lfile)):
182 modified.append(lfile)
184 modified.append(lfile)
183 else:
185 else:
184 clean.append(lfile)
186 clean.append(lfile)
185 lfdirstate.normal(lfile)
187 lfdirstate.normal(lfile)
186 else:
188 else:
187 tocheck = unsure + modified + added + clean
189 tocheck = unsure + modified + added + clean
188 modified, added, clean = [], [], []
190 modified, added, clean = [], [], []
189
191
190 for lfile in tocheck:
192 for lfile in tocheck:
191 standin = lfutil.standin(lfile)
193 standin = lfutil.standin(lfile)
192 if inctx(standin, ctx1):
194 if inctx(standin, ctx1):
193 if ctx1[standin].data().strip() != \
195 if ctx1[standin].data().strip() != \
194 lfutil.hashfile(self.wjoin(lfile)):
196 lfutil.hashfile(self.wjoin(lfile)):
195 modified.append(lfile)
197 modified.append(lfile)
196 else:
198 else:
197 clean.append(lfile)
199 clean.append(lfile)
198 else:
200 else:
199 added.append(lfile)
201 added.append(lfile)
200 finally:
202 finally:
201 # Replace the original ignore function
203 # Replace the original ignore function
202 lfdirstate._ignore = orig_ignore
204 lfdirstate._ignore = orig_ignore
203
205
204 for standin in ctx1.manifest():
206 for standin in ctx1.manifest():
205 if not lfutil.isstandin(standin):
207 if not lfutil.isstandin(standin):
206 continue
208 continue
207 lfile = lfutil.splitstandin(standin)
209 lfile = lfutil.splitstandin(standin)
208 if not match(lfile):
210 if not match(lfile):
209 continue
211 continue
210 if lfile not in lfdirstate:
212 if lfile not in lfdirstate:
211 removed.append(lfile)
213 removed.append(lfile)
212
214
213 # Filter result lists
215 # Filter result lists
214 result = list(result)
216 result = list(result)
215
217
216 # Largefiles are not really removed when they're
218 # Largefiles are not really removed when they're
217 # still in the normal dirstate. Likewise, normal
219 # still in the normal dirstate. Likewise, normal
218 # files are not really removed if it's still in
220 # files are not really removed if it's still in
219 # lfdirstate. This happens in merges where files
221 # lfdirstate. This happens in merges where files
220 # change type.
222 # change type.
221 removed = [f for f in removed if f not in repo.dirstate]
223 removed = [f for f in removed if f not in repo.dirstate]
222 result[2] = [f for f in result[2] if f not in lfdirstate]
224 result[2] = [f for f in result[2] if f not in lfdirstate]
223
225
224 # Unknown files
226 # Unknown files
225 unknown = set(unknown).difference(ignored)
227 unknown = set(unknown).difference(ignored)
226 result[4] = [f for f in unknown
228 result[4] = [f for f in unknown
227 if (repo.dirstate[f] == '?' and
229 if (repo.dirstate[f] == '?' and
228 not lfutil.isstandin(f))]
230 not lfutil.isstandin(f))]
229 # Ignored files were calculated earlier by the dirstate,
231 # Ignored files were calculated earlier by the dirstate,
230 # and we already stripped out the largefiles from the list
232 # and we already stripped out the largefiles from the list
231 result[5] = ignored
233 result[5] = ignored
232 # combine normal files and largefiles
234 # combine normal files and largefiles
233 normals = [[fn for fn in filelist
235 normals = [[fn for fn in filelist
234 if not lfutil.isstandin(fn)]
236 if not lfutil.isstandin(fn)]
235 for filelist in result]
237 for filelist in result]
236 lfiles = (modified, added, removed, missing, [], [], clean)
238 lfiles = (modified, added, removed, missing, [], [], clean)
237 result = [sorted(list1 + list2)
239 result = [sorted(list1 + list2)
238 for (list1, list2) in zip(normals, lfiles)]
240 for (list1, list2) in zip(normals, lfiles)]
239 else:
241 else:
240 def toname(f):
242 def toname(f):
241 if lfutil.isstandin(f):
243 if lfutil.isstandin(f):
242 return lfutil.splitstandin(f)
244 return lfutil.splitstandin(f)
243 return f
245 return f
244 result = [[toname(f) for f in items] for items in result]
246 result = [[toname(f) for f in items] for items in result]
245
247
246 if not listunknown:
248 if not listunknown:
247 result[4] = []
249 result[4] = []
248 if not listignored:
250 if not listignored:
249 result[5] = []
251 result[5] = []
250 if not listclean:
252 if not listclean:
251 result[6] = []
253 result[6] = []
252 self.lfstatus = True
254 self.lfstatus = True
253 return result
255 return result
254
256
255 # As part of committing, copy all of the largefiles into the
257 # As part of committing, copy all of the largefiles into the
256 # cache.
258 # cache.
257 def commitctx(self, *args, **kwargs):
259 def commitctx(self, *args, **kwargs):
258 node = super(lfiles_repo, self).commitctx(*args, **kwargs)
260 node = super(lfiles_repo, self).commitctx(*args, **kwargs)
259 lfutil.copyalltostore(self, node)
261 lfutil.copyalltostore(self, node)
260 return node
262 return node
261
263
262 # Before commit, largefile standins have not had their
264 # Before commit, largefile standins have not had their
263 # contents updated to reflect the hash of their largefile.
265 # contents updated to reflect the hash of their largefile.
264 # Do that here.
266 # Do that here.
265 def commit(self, text="", user=None, date=None, match=None,
267 def commit(self, text="", user=None, date=None, match=None,
266 force=False, editor=False, extra={}):
268 force=False, editor=False, extra={}):
267 orig = super(lfiles_repo, self).commit
269 orig = super(lfiles_repo, self).commit
268
270
269 wlock = repo.wlock()
271 wlock = repo.wlock()
270 try:
272 try:
271 # Case 0: Rebase or Transplant
273 # Case 0: Rebase or Transplant
272 # We have to take the time to pull down the new largefiles now.
274 # We have to take the time to pull down the new largefiles now.
273 # Otherwise, any largefiles that were modified in the
275 # Otherwise, any largefiles that were modified in the
274 # destination changesets get overwritten, either by the rebase
276 # destination changesets get overwritten, either by the rebase
275 # or in the first commit after the rebase or transplant.
277 # or in the first commit after the rebase or transplant.
276 # updatelfiles will update the dirstate to mark any pulled
278 # updatelfiles will update the dirstate to mark any pulled
277 # largefiles as modified
279 # largefiles as modified
278 if getattr(repo, "_isrebasing", False) or \
280 if getattr(repo, "_isrebasing", False) or \
279 getattr(repo, "_istransplanting", False):
281 getattr(repo, "_istransplanting", False):
280 lfcommands.updatelfiles(repo.ui, repo, filelist=None,
282 lfcommands.updatelfiles(repo.ui, repo, filelist=None,
281 printmessage=False)
283 printmessage=False)
282 result = orig(text=text, user=user, date=date, match=match,
284 result = orig(text=text, user=user, date=date, match=match,
283 force=force, editor=editor, extra=extra)
285 force=force, editor=editor, extra=extra)
284 return result
286 return result
285 # Case 1: user calls commit with no specific files or
287 # Case 1: user calls commit with no specific files or
286 # include/exclude patterns: refresh and commit all files that
288 # include/exclude patterns: refresh and commit all files that
287 # are "dirty".
289 # are "dirty".
288 if ((match is None) or
290 if ((match is None) or
289 (not match.anypats() and not match.files())):
291 (not match.anypats() and not match.files())):
290 # Spend a bit of time here to get a list of files we know
292 # Spend a bit of time here to get a list of files we know
291 # are modified so we can compare only against those.
293 # are modified so we can compare only against those.
292 # It can cost a lot of time (several seconds)
294 # It can cost a lot of time (several seconds)
293 # otherwise to update all standins if the largefiles are
295 # otherwise to update all standins if the largefiles are
294 # large.
296 # large.
295 lfdirstate = lfutil.openlfdirstate(ui, self)
297 lfdirstate = lfutil.openlfdirstate(ui, self)
296 dirtymatch = match_.always(repo.root, repo.getcwd())
298 dirtymatch = match_.always(repo.root, repo.getcwd())
297 s = lfdirstate.status(dirtymatch, [], False, False, False)
299 s = lfdirstate.status(dirtymatch, [], False, False, False)
298 modifiedfiles = []
300 modifiedfiles = []
299 for i in s:
301 for i in s:
300 modifiedfiles.extend(i)
302 modifiedfiles.extend(i)
301 lfiles = lfutil.listlfiles(self)
303 lfiles = lfutil.listlfiles(self)
302 # this only loops through largefiles that exist (not
304 # this only loops through largefiles that exist (not
303 # removed/renamed)
305 # removed/renamed)
304 for lfile in lfiles:
306 for lfile in lfiles:
305 if lfile in modifiedfiles:
307 if lfile in modifiedfiles:
306 if os.path.exists(self.wjoin(lfutil.standin(lfile))):
308 if os.path.exists(self.wjoin(lfutil.standin(lfile))):
307 # this handles the case where a rebase is being
309 # this handles the case where a rebase is being
308 # performed and the working copy is not updated
310 # performed and the working copy is not updated
309 # yet.
311 # yet.
310 if os.path.exists(self.wjoin(lfile)):
312 if os.path.exists(self.wjoin(lfile)):
311 lfutil.updatestandin(self,
313 lfutil.updatestandin(self,
312 lfutil.standin(lfile))
314 lfutil.standin(lfile))
313 lfdirstate.normal(lfile)
315 lfdirstate.normal(lfile)
314 for lfile in lfdirstate:
316 for lfile in lfdirstate:
315 if lfile in modifiedfiles:
317 if lfile in modifiedfiles:
316 if not os.path.exists(
318 if not os.path.exists(
317 repo.wjoin(lfutil.standin(lfile))):
319 repo.wjoin(lfutil.standin(lfile))):
318 lfdirstate.drop(lfile)
320 lfdirstate.drop(lfile)
319
321
320 result = orig(text=text, user=user, date=date, match=match,
322 result = orig(text=text, user=user, date=date, match=match,
321 force=force, editor=editor, extra=extra)
323 force=force, editor=editor, extra=extra)
322 # This needs to be after commit; otherwise precommit hooks
324 # This needs to be after commit; otherwise precommit hooks
323 # get the wrong status
325 # get the wrong status
324 lfdirstate.write()
326 lfdirstate.write()
325 return result
327 return result
326
328
327 for f in match.files():
329 for f in match.files():
328 if lfutil.isstandin(f):
330 if lfutil.isstandin(f):
329 raise util.Abort(
331 raise util.Abort(
330 _('file "%s" is a largefile standin') % f,
332 _('file "%s" is a largefile standin') % f,
331 hint=('commit the largefile itself instead'))
333 hint=('commit the largefile itself instead'))
332
334
333 # Case 2: user calls commit with specified patterns: refresh
335 # Case 2: user calls commit with specified patterns: refresh
334 # any matching big files.
336 # any matching big files.
335 smatcher = lfutil.composestandinmatcher(self, match)
337 smatcher = lfutil.composestandinmatcher(self, match)
336 standins = lfutil.dirstate_walk(self.dirstate, smatcher)
338 standins = lfutil.dirstate_walk(self.dirstate, smatcher)
337
339
338 # No matching big files: get out of the way and pass control to
340 # No matching big files: get out of the way and pass control to
339 # the usual commit() method.
341 # the usual commit() method.
340 if not standins:
342 if not standins:
341 return orig(text=text, user=user, date=date, match=match,
343 return orig(text=text, user=user, date=date, match=match,
342 force=force, editor=editor, extra=extra)
344 force=force, editor=editor, extra=extra)
343
345
344 # Refresh all matching big files. It's possible that the
346 # Refresh all matching big files. It's possible that the
345 # commit will end up failing, in which case the big files will
347 # commit will end up failing, in which case the big files will
346 # stay refreshed. No harm done: the user modified them and
348 # stay refreshed. No harm done: the user modified them and
347 # asked to commit them, so sooner or later we're going to
349 # asked to commit them, so sooner or later we're going to
348 # refresh the standins. Might as well leave them refreshed.
350 # refresh the standins. Might as well leave them refreshed.
349 lfdirstate = lfutil.openlfdirstate(ui, self)
351 lfdirstate = lfutil.openlfdirstate(ui, self)
350 for standin in standins:
352 for standin in standins:
351 lfile = lfutil.splitstandin(standin)
353 lfile = lfutil.splitstandin(standin)
352 if lfdirstate[lfile] <> 'r':
354 if lfdirstate[lfile] <> 'r':
353 lfutil.updatestandin(self, standin)
355 lfutil.updatestandin(self, standin)
354 lfdirstate.normal(lfile)
356 lfdirstate.normal(lfile)
355 else:
357 else:
356 lfdirstate.drop(lfile)
358 lfdirstate.drop(lfile)
357
359
358 # Cook up a new matcher that only matches regular files or
360 # Cook up a new matcher that only matches regular files or
359 # standins corresponding to the big files requested by the
361 # standins corresponding to the big files requested by the
360 # user. Have to modify _files to prevent commit() from
362 # user. Have to modify _files to prevent commit() from
361 # complaining "not tracked" for big files.
363 # complaining "not tracked" for big files.
362 lfiles = lfutil.listlfiles(repo)
364 lfiles = lfutil.listlfiles(repo)
363 match = copy.copy(match)
365 match = copy.copy(match)
364 orig_matchfn = match.matchfn
366 orig_matchfn = match.matchfn
365
367
366 # Check both the list of largefiles and the list of
368 # Check both the list of largefiles and the list of
367 # standins because if a largefile was removed, it
369 # standins because if a largefile was removed, it
368 # won't be in the list of largefiles at this point
370 # won't be in the list of largefiles at this point
369 match._files += sorted(standins)
371 match._files += sorted(standins)
370
372
371 actualfiles = []
373 actualfiles = []
372 for f in match._files:
374 for f in match._files:
373 fstandin = lfutil.standin(f)
375 fstandin = lfutil.standin(f)
374
376
375 # ignore known largefiles and standins
377 # ignore known largefiles and standins
376 if f in lfiles or fstandin in standins:
378 if f in lfiles or fstandin in standins:
377 continue
379 continue
378
380
379 # append directory separator to avoid collisions
381 # append directory separator to avoid collisions
380 if not fstandin.endswith(os.sep):
382 if not fstandin.endswith(os.sep):
381 fstandin += os.sep
383 fstandin += os.sep
382
384
383 # prevalidate matching standin directories
385 # prevalidate matching standin directories
384 if util.any(st for st in match._files
386 if util.any(st for st in match._files
385 if st.startswith(fstandin)):
387 if st.startswith(fstandin)):
386 continue
388 continue
387 actualfiles.append(f)
389 actualfiles.append(f)
388 match._files = actualfiles
390 match._files = actualfiles
389
391
390 def matchfn(f):
392 def matchfn(f):
391 if orig_matchfn(f):
393 if orig_matchfn(f):
392 return f not in lfiles
394 return f not in lfiles
393 else:
395 else:
394 return f in standins
396 return f in standins
395
397
396 match.matchfn = matchfn
398 match.matchfn = matchfn
397 result = orig(text=text, user=user, date=date, match=match,
399 result = orig(text=text, user=user, date=date, match=match,
398 force=force, editor=editor, extra=extra)
400 force=force, editor=editor, extra=extra)
399 # This needs to be after commit; otherwise precommit hooks
401 # This needs to be after commit; otherwise precommit hooks
400 # get the wrong status
402 # get the wrong status
401 lfdirstate.write()
403 lfdirstate.write()
402 return result
404 return result
403 finally:
405 finally:
404 wlock.release()
406 wlock.release()
405
407
406 def push(self, remote, force=False, revs=None, newbranch=False):
408 def push(self, remote, force=False, revs=None, newbranch=False):
407 o = lfutil.findoutgoing(repo, remote, force)
409 o = lfutil.findoutgoing(repo, remote, force)
408 if o:
410 if o:
409 toupload = set()
411 toupload = set()
410 o = repo.changelog.nodesbetween(o, revs)[0]
412 o = repo.changelog.nodesbetween(o, revs)[0]
411 for n in o:
413 for n in o:
412 parents = [p for p in repo.changelog.parents(n)
414 parents = [p for p in repo.changelog.parents(n)
413 if p != node_.nullid]
415 if p != node_.nullid]
414 ctx = repo[n]
416 ctx = repo[n]
415 files = set(ctx.files())
417 files = set(ctx.files())
416 if len(parents) == 2:
418 if len(parents) == 2:
417 mc = ctx.manifest()
419 mc = ctx.manifest()
418 mp1 = ctx.parents()[0].manifest()
420 mp1 = ctx.parents()[0].manifest()
419 mp2 = ctx.parents()[1].manifest()
421 mp2 = ctx.parents()[1].manifest()
420 for f in mp1:
422 for f in mp1:
421 if f not in mc:
423 if f not in mc:
422 files.add(f)
424 files.add(f)
423 for f in mp2:
425 for f in mp2:
424 if f not in mc:
426 if f not in mc:
425 files.add(f)
427 files.add(f)
426 for f in mc:
428 for f in mc:
427 if mc[f] != mp1.get(f, None) or mc[f] != mp2.get(f,
429 if mc[f] != mp1.get(f, None) or mc[f] != mp2.get(f,
428 None):
430 None):
429 files.add(f)
431 files.add(f)
430
432
431 toupload = toupload.union(
433 toupload = toupload.union(
432 set([ctx[f].data().strip()
434 set([ctx[f].data().strip()
433 for f in files
435 for f in files
434 if lfutil.isstandin(f) and f in ctx]))
436 if lfutil.isstandin(f) and f in ctx]))
435 lfcommands.uploadlfiles(ui, self, remote, toupload)
437 lfcommands.uploadlfiles(ui, self, remote, toupload)
436 return super(lfiles_repo, self).push(remote, force, revs,
438 return super(lfiles_repo, self).push(remote, force, revs,
437 newbranch)
439 newbranch)
438
440
439 repo.__class__ = lfiles_repo
441 repo.__class__ = lfiles_repo
440
442
441 def checkrequireslfiles(ui, repo, **kwargs):
443 def checkrequireslfiles(ui, repo, **kwargs):
442 if 'largefiles' not in repo.requirements and util.any(
444 if 'largefiles' not in repo.requirements and util.any(
443 lfutil.shortname+'/' in f[0] for f in repo.store.datafiles()):
445 lfutil.shortname+'/' in f[0] for f in repo.store.datafiles()):
444 repo.requirements.add('largefiles')
446 repo.requirements.add('largefiles')
445 repo._writerequirements()
447 repo._writerequirements()
446
448
447 ui.setconfig('hooks', 'changegroup.lfiles', checkrequireslfiles)
449 ui.setconfig('hooks', 'changegroup.lfiles', checkrequireslfiles)
448 ui.setconfig('hooks', 'commit.lfiles', checkrequireslfiles)
450 ui.setconfig('hooks', 'commit.lfiles', checkrequireslfiles)
@@ -1,951 +1,997
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':
952 to boost performance, largefiles checks whether specified patterns are
953 related to largefiles in working directory (NOT to STANDIN) or not.
951
954
955 $ hg init statusmatch
956 $ cd statusmatch
957
958 $ mkdir -p a/b/c/d
959 $ echo normal > 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
962 $ hg add --large a/b/c/d/e.large.txt
963 $ mkdir -p a/b/c/x
964 $ echo normal > a/b/c/x/y.normal.txt
965 $ hg add a/b/c/x/y.normal.txt
966 $ hg commit -m 'add files'
967 Invoking status precommit hook
968 A a/b/c/d/e.large.txt
969 A a/b/c/d/e.normal.txt
970 A a/b/c/x/y.normal.txt
971
972 (1) no pattern: no performance boost
973 $ hg status -A
974 C a/b/c/d/e.large.txt
975 C a/b/c/d/e.normal.txt
976 C a/b/c/x/y.normal.txt
977
978 (2) pattern not related to largefiles: performance boost
979 $ hg status -A a/b/c/x
980 C a/b/c/x/y.normal.txt
981
982 (3) pattern related to largefiles: no performance boost
983 $ hg status -A a/b/c/d
984 C a/b/c/d/e.large.txt
985 C a/b/c/d/e.normal.txt
986
987 (4) pattern related to STANDIN (not to largefiles): performance boost
988 $ hg status -A .hglf/a
989 C .hglf/a/b/c/d/e.large.txt
990
991 (5) mixed case: no performance boost
992 $ hg status -A a/b/c/x a/b/c/d
993 C a/b/c/d/e.large.txt
994 C a/b/c/d/e.normal.txt
995 C a/b/c/x/y.normal.txt
996
997 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now