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