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