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