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