##// END OF EJS Templates
largefiles: update _subdirlfs() comment...
Matt Harbison -
r24007:240343e1 default
parent child Browse files
Show More
@@ -1,371 +1,371 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 os
11 import os
12
12
13 from mercurial import error, manifest, match as match_, util
13 from mercurial import error, manifest, match as match_, util
14 from mercurial.i18n import _
14 from mercurial.i18n import _
15 from mercurial import scmutil, localrepo
15 from mercurial import scmutil, localrepo
16
16
17 import lfcommands
17 import lfcommands
18 import lfutil
18 import lfutil
19
19
20 def reposetup(ui, repo):
20 def reposetup(ui, repo):
21 # wire repositories should be given new wireproto functions
21 # wire repositories should be given new wireproto functions
22 # by "proto.wirereposetup()" via "hg.wirepeersetupfuncs"
22 # by "proto.wirereposetup()" via "hg.wirepeersetupfuncs"
23 if not repo.local():
23 if not repo.local():
24 return
24 return
25
25
26 class lfilesrepo(repo.__class__):
26 class lfilesrepo(repo.__class__):
27 lfstatus = False
27 lfstatus = False
28 def status_nolfiles(self, *args, **kwargs):
28 def status_nolfiles(self, *args, **kwargs):
29 return super(lfilesrepo, self).status(*args, **kwargs)
29 return super(lfilesrepo, self).status(*args, **kwargs)
30
30
31 # When lfstatus is set, return a context that gives the names
31 # When lfstatus is set, return a context that gives the names
32 # of largefiles instead of their corresponding standins and
32 # of largefiles instead of their corresponding standins and
33 # identifies the largefiles as always binary, regardless of
33 # identifies the largefiles as always binary, regardless of
34 # their actual contents.
34 # their actual contents.
35 def __getitem__(self, changeid):
35 def __getitem__(self, changeid):
36 ctx = super(lfilesrepo, self).__getitem__(changeid)
36 ctx = super(lfilesrepo, self).__getitem__(changeid)
37 if self.lfstatus:
37 if self.lfstatus:
38 class lfilesmanifestdict(manifest.manifestdict):
38 class lfilesmanifestdict(manifest.manifestdict):
39 def __contains__(self, filename):
39 def __contains__(self, filename):
40 orig = super(lfilesmanifestdict, self).__contains__
40 orig = super(lfilesmanifestdict, self).__contains__
41 return orig(filename) or orig(lfutil.standin(filename))
41 return orig(filename) or orig(lfutil.standin(filename))
42 class lfilesctx(ctx.__class__):
42 class lfilesctx(ctx.__class__):
43 def files(self):
43 def files(self):
44 filenames = super(lfilesctx, self).files()
44 filenames = super(lfilesctx, self).files()
45 return [lfutil.splitstandin(f) or f for f in filenames]
45 return [lfutil.splitstandin(f) or f for f in filenames]
46 def manifest(self):
46 def manifest(self):
47 man1 = super(lfilesctx, self).manifest()
47 man1 = super(lfilesctx, self).manifest()
48 man1.__class__ = lfilesmanifestdict
48 man1.__class__ = lfilesmanifestdict
49 return man1
49 return man1
50 def filectx(self, path, fileid=None, filelog=None):
50 def filectx(self, path, fileid=None, filelog=None):
51 orig = super(lfilesctx, self).filectx
51 orig = super(lfilesctx, self).filectx
52 try:
52 try:
53 if filelog is not None:
53 if filelog is not None:
54 result = orig(path, fileid, filelog)
54 result = orig(path, fileid, filelog)
55 else:
55 else:
56 result = orig(path, fileid)
56 result = orig(path, fileid)
57 except error.LookupError:
57 except error.LookupError:
58 # Adding a null character will cause Mercurial to
58 # Adding a null character will cause Mercurial to
59 # identify this as a binary file.
59 # identify this as a binary file.
60 if filelog is not None:
60 if filelog is not None:
61 result = orig(lfutil.standin(path), fileid,
61 result = orig(lfutil.standin(path), fileid,
62 filelog)
62 filelog)
63 else:
63 else:
64 result = orig(lfutil.standin(path), fileid)
64 result = orig(lfutil.standin(path), fileid)
65 olddata = result.data
65 olddata = result.data
66 result.data = lambda: olddata() + '\0'
66 result.data = lambda: olddata() + '\0'
67 return result
67 return result
68 ctx.__class__ = lfilesctx
68 ctx.__class__ = lfilesctx
69 return ctx
69 return ctx
70
70
71 # Figure out the status of big files and insert them into the
71 # Figure out the status of big files and insert them into the
72 # appropriate list in the result. Also removes standin files
72 # appropriate list in the result. Also removes standin files
73 # from the listing. Revert to the original status if
73 # from the listing. Revert to the original status if
74 # self.lfstatus is False.
74 # self.lfstatus is False.
75 # XXX large file status is buggy when used on repo proxy.
75 # XXX large file status is buggy when used on repo proxy.
76 # XXX this needs to be investigated.
76 # XXX this needs to be investigated.
77 @localrepo.unfilteredmethod
77 @localrepo.unfilteredmethod
78 def status(self, node1='.', node2=None, match=None, ignored=False,
78 def status(self, node1='.', node2=None, match=None, ignored=False,
79 clean=False, unknown=False, listsubrepos=False):
79 clean=False, unknown=False, listsubrepos=False):
80 listignored, listclean, listunknown = ignored, clean, unknown
80 listignored, listclean, listunknown = ignored, clean, unknown
81 orig = super(lfilesrepo, self).status
81 orig = super(lfilesrepo, self).status
82 if not self.lfstatus:
82 if not self.lfstatus:
83 return orig(node1, node2, match, listignored, listclean,
83 return orig(node1, node2, match, listignored, listclean,
84 listunknown, listsubrepos)
84 listunknown, listsubrepos)
85
85
86 # some calls in this function rely on the old version of status
86 # some calls in this function rely on the old version of status
87 self.lfstatus = False
87 self.lfstatus = False
88 ctx1 = self[node1]
88 ctx1 = self[node1]
89 ctx2 = self[node2]
89 ctx2 = self[node2]
90 working = ctx2.rev() is None
90 working = ctx2.rev() is None
91 parentworking = working and ctx1 == self['.']
91 parentworking = working and ctx1 == self['.']
92
92
93 if match is None:
93 if match is None:
94 match = match_.always(self.root, self.getcwd())
94 match = match_.always(self.root, self.getcwd())
95
95
96 wlock = None
96 wlock = None
97 try:
97 try:
98 try:
98 try:
99 # updating the dirstate is optional
99 # updating the dirstate is optional
100 # so we don't wait on the lock
100 # so we don't wait on the lock
101 wlock = self.wlock(False)
101 wlock = self.wlock(False)
102 except error.LockError:
102 except error.LockError:
103 pass
103 pass
104
104
105 # First check if paths or patterns were specified on the
105 # First check if paths or patterns were specified on the
106 # command line. If there were, and they don't match any
106 # command line. If there were, and they don't match any
107 # largefiles, we should just bail here and let super
107 # largefiles, we should just bail here and let super
108 # handle it -- thus gaining a big performance boost.
108 # handle it -- thus gaining a big performance boost.
109 lfdirstate = lfutil.openlfdirstate(ui, self)
109 lfdirstate = lfutil.openlfdirstate(ui, self)
110 if not match.always():
110 if not match.always():
111 for f in lfdirstate:
111 for f in lfdirstate:
112 if match(f):
112 if match(f):
113 break
113 break
114 else:
114 else:
115 return orig(node1, node2, match, listignored, listclean,
115 return orig(node1, node2, match, listignored, listclean,
116 listunknown, listsubrepos)
116 listunknown, listsubrepos)
117
117
118 # Create a copy of match that matches standins instead
118 # Create a copy of match that matches standins instead
119 # of largefiles.
119 # of largefiles.
120 def tostandins(files):
120 def tostandins(files):
121 if not working:
121 if not working:
122 return files
122 return files
123 newfiles = []
123 newfiles = []
124 dirstate = self.dirstate
124 dirstate = self.dirstate
125 for f in files:
125 for f in files:
126 sf = lfutil.standin(f)
126 sf = lfutil.standin(f)
127 if sf in dirstate:
127 if sf in dirstate:
128 newfiles.append(sf)
128 newfiles.append(sf)
129 elif sf in dirstate.dirs():
129 elif sf in dirstate.dirs():
130 # Directory entries could be regular or
130 # Directory entries could be regular or
131 # standin, check both
131 # standin, check both
132 newfiles.extend((f, sf))
132 newfiles.extend((f, sf))
133 else:
133 else:
134 newfiles.append(f)
134 newfiles.append(f)
135 return newfiles
135 return newfiles
136
136
137 m = copy.copy(match)
137 m = copy.copy(match)
138 m._files = tostandins(m._files)
138 m._files = tostandins(m._files)
139
139
140 result = orig(node1, node2, m, ignored, clean, unknown,
140 result = orig(node1, node2, m, ignored, clean, unknown,
141 listsubrepos)
141 listsubrepos)
142 if working:
142 if working:
143
143
144 def sfindirstate(f):
144 def sfindirstate(f):
145 sf = lfutil.standin(f)
145 sf = lfutil.standin(f)
146 dirstate = self.dirstate
146 dirstate = self.dirstate
147 return sf in dirstate or sf in dirstate.dirs()
147 return sf in dirstate or sf in dirstate.dirs()
148
148
149 match._files = [f for f in match._files
149 match._files = [f for f in match._files
150 if sfindirstate(f)]
150 if sfindirstate(f)]
151 # Don't waste time getting the ignored and unknown
151 # Don't waste time getting the ignored and unknown
152 # files from lfdirstate
152 # files from lfdirstate
153 unsure, s = lfdirstate.status(match, [], False, listclean,
153 unsure, s = lfdirstate.status(match, [], False, listclean,
154 False)
154 False)
155 (modified, added, removed, clean) = (s.modified, s.added,
155 (modified, added, removed, clean) = (s.modified, s.added,
156 s.removed, s.clean)
156 s.removed, s.clean)
157 if parentworking:
157 if parentworking:
158 for lfile in unsure:
158 for lfile in unsure:
159 standin = lfutil.standin(lfile)
159 standin = lfutil.standin(lfile)
160 if standin not in ctx1:
160 if standin not in ctx1:
161 # from second parent
161 # from second parent
162 modified.append(lfile)
162 modified.append(lfile)
163 elif ctx1[standin].data().strip() \
163 elif ctx1[standin].data().strip() \
164 != lfutil.hashfile(self.wjoin(lfile)):
164 != lfutil.hashfile(self.wjoin(lfile)):
165 modified.append(lfile)
165 modified.append(lfile)
166 else:
166 else:
167 if listclean:
167 if listclean:
168 clean.append(lfile)
168 clean.append(lfile)
169 lfdirstate.normal(lfile)
169 lfdirstate.normal(lfile)
170 else:
170 else:
171 tocheck = unsure + modified + added + clean
171 tocheck = unsure + modified + added + clean
172 modified, added, clean = [], [], []
172 modified, added, clean = [], [], []
173 checkexec = self.dirstate._checkexec
173 checkexec = self.dirstate._checkexec
174
174
175 for lfile in tocheck:
175 for lfile in tocheck:
176 standin = lfutil.standin(lfile)
176 standin = lfutil.standin(lfile)
177 if standin in ctx1:
177 if standin in ctx1:
178 abslfile = self.wjoin(lfile)
178 abslfile = self.wjoin(lfile)
179 if ((ctx1[standin].data().strip() !=
179 if ((ctx1[standin].data().strip() !=
180 lfutil.hashfile(abslfile)) or
180 lfutil.hashfile(abslfile)) or
181 (checkexec and
181 (checkexec and
182 ('x' in ctx1.flags(standin)) !=
182 ('x' in ctx1.flags(standin)) !=
183 bool(lfutil.getexecutable(abslfile)))):
183 bool(lfutil.getexecutable(abslfile)))):
184 modified.append(lfile)
184 modified.append(lfile)
185 elif listclean:
185 elif listclean:
186 clean.append(lfile)
186 clean.append(lfile)
187 else:
187 else:
188 added.append(lfile)
188 added.append(lfile)
189
189
190 # at this point, 'removed' contains largefiles
190 # at this point, 'removed' contains largefiles
191 # marked as 'R' in the working context.
191 # marked as 'R' in the working context.
192 # then, largefiles not managed also in the target
192 # then, largefiles not managed also in the target
193 # context should be excluded from 'removed'.
193 # context should be excluded from 'removed'.
194 removed = [lfile for lfile in removed
194 removed = [lfile for lfile in removed
195 if lfutil.standin(lfile) in ctx1]
195 if lfutil.standin(lfile) in ctx1]
196
196
197 # Standins no longer found in lfdirstate has been
197 # Standins no longer found in lfdirstate has been
198 # removed
198 # removed
199 for standin in ctx1.walk(lfutil.getstandinmatcher(self)):
199 for standin in ctx1.walk(lfutil.getstandinmatcher(self)):
200 lfile = lfutil.splitstandin(standin)
200 lfile = lfutil.splitstandin(standin)
201 if not match(lfile):
201 if not match(lfile):
202 continue
202 continue
203 if lfile not in lfdirstate:
203 if lfile not in lfdirstate:
204 removed.append(lfile)
204 removed.append(lfile)
205
205
206 # Filter result lists
206 # Filter result lists
207 result = list(result)
207 result = list(result)
208
208
209 # Largefiles are not really removed when they're
209 # Largefiles are not really removed when they're
210 # still in the normal dirstate. Likewise, normal
210 # still in the normal dirstate. Likewise, normal
211 # files are not really removed if they are still in
211 # files are not really removed if they are still in
212 # lfdirstate. This happens in merges where files
212 # lfdirstate. This happens in merges where files
213 # change type.
213 # change type.
214 removed = [f for f in removed
214 removed = [f for f in removed
215 if f not in self.dirstate]
215 if f not in self.dirstate]
216 result[2] = [f for f in result[2]
216 result[2] = [f for f in result[2]
217 if f not in lfdirstate]
217 if f not in lfdirstate]
218
218
219 lfiles = set(lfdirstate._map)
219 lfiles = set(lfdirstate._map)
220 # Unknown files
220 # Unknown files
221 result[4] = set(result[4]).difference(lfiles)
221 result[4] = set(result[4]).difference(lfiles)
222 # Ignored files
222 # Ignored files
223 result[5] = set(result[5]).difference(lfiles)
223 result[5] = set(result[5]).difference(lfiles)
224 # combine normal files and largefiles
224 # combine normal files and largefiles
225 normals = [[fn for fn in filelist
225 normals = [[fn for fn in filelist
226 if not lfutil.isstandin(fn)]
226 if not lfutil.isstandin(fn)]
227 for filelist in result]
227 for filelist in result]
228 lfstatus = (modified, added, removed, s.deleted, [], [],
228 lfstatus = (modified, added, removed, s.deleted, [], [],
229 clean)
229 clean)
230 result = [sorted(list1 + list2)
230 result = [sorted(list1 + list2)
231 for (list1, list2) in zip(normals, lfstatus)]
231 for (list1, list2) in zip(normals, lfstatus)]
232 else: # not against working directory
232 else: # not against working directory
233 result = [[lfutil.splitstandin(f) or f for f in items]
233 result = [[lfutil.splitstandin(f) or f for f in items]
234 for items in result]
234 for items in result]
235
235
236 if wlock:
236 if wlock:
237 lfdirstate.write()
237 lfdirstate.write()
238
238
239 finally:
239 finally:
240 if wlock:
240 if wlock:
241 wlock.release()
241 wlock.release()
242
242
243 self.lfstatus = True
243 self.lfstatus = True
244 return scmutil.status(*result)
244 return scmutil.status(*result)
245
245
246 def commitctx(self, ctx, *args, **kwargs):
246 def commitctx(self, ctx, *args, **kwargs):
247 node = super(lfilesrepo, self).commitctx(ctx, *args, **kwargs)
247 node = super(lfilesrepo, self).commitctx(ctx, *args, **kwargs)
248 class lfilesctx(ctx.__class__):
248 class lfilesctx(ctx.__class__):
249 def markcommitted(self, node):
249 def markcommitted(self, node):
250 orig = super(lfilesctx, self).markcommitted
250 orig = super(lfilesctx, self).markcommitted
251 return lfutil.markcommitted(orig, self, node)
251 return lfutil.markcommitted(orig, self, node)
252 ctx.__class__ = lfilesctx
252 ctx.__class__ = lfilesctx
253 return node
253 return node
254
254
255 # Before commit, largefile standins have not had their
255 # Before commit, largefile standins have not had their
256 # contents updated to reflect the hash of their largefile.
256 # contents updated to reflect the hash of their largefile.
257 # Do that here.
257 # Do that here.
258 def commit(self, text="", user=None, date=None, match=None,
258 def commit(self, text="", user=None, date=None, match=None,
259 force=False, editor=False, extra={}):
259 force=False, editor=False, extra={}):
260 orig = super(lfilesrepo, self).commit
260 orig = super(lfilesrepo, self).commit
261
261
262 wlock = self.wlock()
262 wlock = self.wlock()
263 try:
263 try:
264 lfcommithook = self._lfcommithooks[-1]
264 lfcommithook = self._lfcommithooks[-1]
265 match = lfcommithook(self, match)
265 match = lfcommithook(self, match)
266 result = orig(text=text, user=user, date=date, match=match,
266 result = orig(text=text, user=user, date=date, match=match,
267 force=force, editor=editor, extra=extra)
267 force=force, editor=editor, extra=extra)
268 return result
268 return result
269 finally:
269 finally:
270 wlock.release()
270 wlock.release()
271
271
272 def push(self, remote, force=False, revs=None, newbranch=False):
272 def push(self, remote, force=False, revs=None, newbranch=False):
273 if remote.local():
273 if remote.local():
274 missing = set(self.requirements) - remote.local().supported
274 missing = set(self.requirements) - remote.local().supported
275 if missing:
275 if missing:
276 msg = _("required features are not"
276 msg = _("required features are not"
277 " supported in the destination:"
277 " supported in the destination:"
278 " %s") % (', '.join(sorted(missing)))
278 " %s") % (', '.join(sorted(missing)))
279 raise util.Abort(msg)
279 raise util.Abort(msg)
280 return super(lfilesrepo, self).push(remote, force=force, revs=revs,
280 return super(lfilesrepo, self).push(remote, force=force, revs=revs,
281 newbranch=newbranch)
281 newbranch=newbranch)
282
282
283 # TODO: _subdirlfs should be moved into "lfutil.py", because
283 # TODO: _subdirlfs should be moved into "lfutil.py", because
284 # it is referred only from "lfutil.updatestandinsbymatch"
284 # it is referred only from "lfutil.updatestandinsbymatch"
285 def _subdirlfs(self, files, lfiles):
285 def _subdirlfs(self, files, lfiles):
286 '''
286 '''
287 Adjust matched file list
287 Adjust matched file list
288 If we pass a directory to commit whose only committable files
288 If we pass a directory to commit whose only committable files
289 are largefiles, the core commit code aborts before finding
289 are largefiles, the core commit code aborts before finding
290 the largefiles.
290 the largefiles.
291 So we do the following:
291 So we do the following:
292 For directories that only have largefiles as matches,
292 For directories that only have largefiles as matches,
293 we explicitly add the largefiles to the match list and remove
293 we explicitly add the largefiles to the match list and remove
294 the directory.
294 the directory.
295 In other cases, we leave the match list unmodified.
295 In other cases, we leave the match list unmodified.
296 '''
296 '''
297 actualfiles = []
297 actualfiles = []
298 dirs = []
298 dirs = []
299 regulars = []
299 regulars = []
300
300
301 for f in files:
301 for f in files:
302 if lfutil.isstandin(f + '/'):
302 if lfutil.isstandin(f + '/'):
303 raise util.Abort(
303 raise util.Abort(
304 _('file "%s" is a largefile standin') % f,
304 _('file "%s" is a largefile standin') % f,
305 hint=('commit the largefile itself instead'))
305 hint=('commit the largefile itself instead'))
306 # Scan directories
306 # Scan directories
307 if os.path.isdir(self.wjoin(f)):
307 if os.path.isdir(self.wjoin(f)):
308 dirs.append(f)
308 dirs.append(f)
309 else:
309 else:
310 regulars.append(f)
310 regulars.append(f)
311
311
312 for f in dirs:
312 for f in dirs:
313 matcheddir = False
313 matcheddir = False
314 d = self.dirstate.normalize(f) + '/'
314 d = self.dirstate.normalize(f) + '/'
315 # Check for matched normal files
315 # Check for matched normal files
316 for mf in regulars:
316 for mf in regulars:
317 if self.dirstate.normalize(mf).startswith(d):
317 if self.dirstate.normalize(mf).startswith(d):
318 actualfiles.append(f)
318 actualfiles.append(f)
319 matcheddir = True
319 matcheddir = True
320 break
320 break
321 if not matcheddir:
321 if not matcheddir:
322 # If no normal match, manually append
322 # If no normal match, manually append
323 # any matching largefiles
323 # any matching largefiles
324 for lf in lfiles:
324 for lf in lfiles:
325 if self.dirstate.normalize(lf).startswith(d):
325 if self.dirstate.normalize(lf).startswith(d):
326 actualfiles.append(lf)
326 actualfiles.append(lf)
327 if not matcheddir:
327 if not matcheddir:
328 # There may still be normal files in the dir, so
328 # There may still be normal files in the dir, so
329 # make sure a directory is in the list, which
329 # make sure _a_ directory is in the list, which
330 # forces status to walk and call the match
330 # forces status/dirstate to walk all files and
331 # function on the matcher. Windows does NOT
331 # call the match function on the matcher, even
332 # require this.
332 # on case sensitive filesytems.
333 actualfiles.append('.')
333 actualfiles.append('.')
334 matcheddir = True
334 matcheddir = True
335 # Nothing in dir, so readd it
335 # Nothing in dir, so readd it
336 # and let commit reject it
336 # and let commit reject it
337 if not matcheddir:
337 if not matcheddir:
338 actualfiles.append(f)
338 actualfiles.append(f)
339
339
340 # Always add normal files
340 # Always add normal files
341 actualfiles += regulars
341 actualfiles += regulars
342 return actualfiles
342 return actualfiles
343
343
344 repo.__class__ = lfilesrepo
344 repo.__class__ = lfilesrepo
345
345
346 # stack of hooks being executed before committing.
346 # stack of hooks being executed before committing.
347 # only last element ("_lfcommithooks[-1]") is used for each committing.
347 # only last element ("_lfcommithooks[-1]") is used for each committing.
348 repo._lfcommithooks = [lfutil.updatestandinsbymatch]
348 repo._lfcommithooks = [lfutil.updatestandinsbymatch]
349
349
350 # Stack of status writer functions taking "*msg, **opts" arguments
350 # Stack of status writer functions taking "*msg, **opts" arguments
351 # like "ui.status()". Only last element ("_lfstatuswriters[-1]")
351 # like "ui.status()". Only last element ("_lfstatuswriters[-1]")
352 # is used to write status out.
352 # is used to write status out.
353 repo._lfstatuswriters = [ui.status]
353 repo._lfstatuswriters = [ui.status]
354
354
355 def prepushoutgoinghook(local, remote, outgoing):
355 def prepushoutgoinghook(local, remote, outgoing):
356 if outgoing.missing:
356 if outgoing.missing:
357 toupload = set()
357 toupload = set()
358 addfunc = lambda fn, lfhash: toupload.add(lfhash)
358 addfunc = lambda fn, lfhash: toupload.add(lfhash)
359 lfutil.getlfilestoupload(local, outgoing.missing, addfunc)
359 lfutil.getlfilestoupload(local, outgoing.missing, addfunc)
360 lfcommands.uploadlfiles(ui, local, remote, toupload)
360 lfcommands.uploadlfiles(ui, local, remote, toupload)
361 repo.prepushoutgoinghooks.add("largefiles", prepushoutgoinghook)
361 repo.prepushoutgoinghooks.add("largefiles", prepushoutgoinghook)
362
362
363 def checkrequireslfiles(ui, repo, **kwargs):
363 def checkrequireslfiles(ui, repo, **kwargs):
364 if 'largefiles' not in repo.requirements and util.any(
364 if 'largefiles' not in repo.requirements and util.any(
365 lfutil.shortname+'/' in f[0] for f in repo.store.datafiles()):
365 lfutil.shortname+'/' in f[0] for f in repo.store.datafiles()):
366 repo.requirements.add('largefiles')
366 repo.requirements.add('largefiles')
367 repo._writerequirements()
367 repo._writerequirements()
368
368
369 ui.setconfig('hooks', 'changegroup.lfiles', checkrequireslfiles,
369 ui.setconfig('hooks', 'changegroup.lfiles', checkrequireslfiles,
370 'largefiles')
370 'largefiles')
371 ui.setconfig('hooks', 'commit.lfiles', checkrequireslfiles, 'largefiles')
371 ui.setconfig('hooks', 'commit.lfiles', checkrequireslfiles, 'largefiles')
General Comments 0
You need to be logged in to leave comments. Login now