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