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