annotate hgext/largefiles/lfcommands.py @ 15472:6a7e874390b0 stable

largefiles: treat status of cache missed largefiles as "missing" correctly "hg status" may treat cache missed largefiles as "removed" incorrectly. assumptions for problem case: - there is no cache for largefile "L" - at first, update working directory to the revision in which "L" is not yet added, - then, update working directory to the revision in which "L" is already added and now, "hg status" treats "L" as "removed". current implementation does not allocate entry for cache missed largefile in ".hg/largefiles/dirstate", but files without ".hg/largefiles/dirstate" entry are treated as "removed" by largefiles extension. "hg revert" can not recover from this situation, but "rm -rf .hg/largefiles", because it causes dirstate rebuilding. this patch invokes normallookup() for cache missed largefiles to allocate entry in ".hg/largefiles/dirstate", so "hg status" can treat it as "missing" correctly.
author FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
date Fri, 11 Nov 2011 02:33:01 +0900
parents a53888685a6c
children 6c5e6ebe0812
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
1 # Copyright 2009-2010 Gregory P. Ward
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
2 # Copyright 2009-2010 Intelerad Medical Systems Incorporated
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
3 # Copyright 2010-2011 Fog Creek Software
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
4 # Copyright 2010-2011 Unity Technologies
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
5 #
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
6 # This software may be used and distributed according to the terms of the
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
7 # GNU General Public License version 2 or any later version.
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
8
15252
6e809bb4f969 largefiles: improve comments, internal docstrings
Greg Ward <greg@gerg.ca>
parents: 15230
diff changeset
9 '''High-level command function for lfconvert, plus the cmdtable.'''
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
10
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
11 import os
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
12 import shutil
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
13
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
14 from mercurial import util, match as match_, hg, node, context, error
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
15 from mercurial.i18n import _
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
16
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
17 import lfutil
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
18 import basestore
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
19
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
20 # -- Commands ----------------------------------------------------------
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
21
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
22 def lfconvert(ui, src, dest, *pats, **opts):
15230
697289c5d415 largefiles: improve help
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
23 '''convert a normal repository to a largefiles repository
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
24
15230
697289c5d415 largefiles: improve help
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
25 Convert repository SOURCE to a new repository DEST, identical to
697289c5d415 largefiles: improve help
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
26 SOURCE except that certain files will be converted as largefiles:
697289c5d415 largefiles: improve help
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
27 specifically, any file that matches any PATTERN *or* whose size is
697289c5d415 largefiles: improve help
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
28 above the minimum size threshold is converted as a largefile. The
697289c5d415 largefiles: improve help
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
29 size used to determine whether or not to track a file as a
697289c5d415 largefiles: improve help
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
30 largefile is the size of the first version of the file. The
697289c5d415 largefiles: improve help
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
31 minimum size can be specified either with --size or in
697289c5d415 largefiles: improve help
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
32 configuration as ``largefiles.size``.
697289c5d415 largefiles: improve help
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
33
697289c5d415 largefiles: improve help
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
34 After running this command you will need to make sure that
697289c5d415 largefiles: improve help
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
35 largefiles is enabled anywhere you intend to push the new
697289c5d415 largefiles: improve help
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
36 repository.
697289c5d415 largefiles: improve help
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
37
15332
0db47b8d025f largefiles: rename lfconvert --tonormal option to --to-normal
Greg Ward <greg@gerg.ca>
parents: 15317
diff changeset
38 Use --to-normal to convert largefiles back to normal files; after
15230
697289c5d415 largefiles: improve help
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
39 this, the DEST repository can be used without largefiles at all.'''
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
40
15332
0db47b8d025f largefiles: rename lfconvert --tonormal option to --to-normal
Greg Ward <greg@gerg.ca>
parents: 15317
diff changeset
41 if opts['to_normal']:
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
42 tolfile = False
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
43 else:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
44 tolfile = True
15227
a7686abf73a6 largefiles: factor out lfutil.getminsize()
Greg Ward <greg@gerg.ca>
parents: 15224
diff changeset
45 size = lfutil.getminsize(ui, True, opts.get('size'), default=None)
15340
0e58513cc59a largefiles: rearrange how lfconvert detects non-local repos
Greg Ward <greg@gerg.ca>
parents: 15339
diff changeset
46
0e58513cc59a largefiles: rearrange how lfconvert detects non-local repos
Greg Ward <greg@gerg.ca>
parents: 15339
diff changeset
47 if not hg.islocal(src):
0e58513cc59a largefiles: rearrange how lfconvert detects non-local repos
Greg Ward <greg@gerg.ca>
parents: 15339
diff changeset
48 raise util.Abort(_('%s is not a local Mercurial repo') % src)
0e58513cc59a largefiles: rearrange how lfconvert detects non-local repos
Greg Ward <greg@gerg.ca>
parents: 15339
diff changeset
49 if not hg.islocal(dest):
0e58513cc59a largefiles: rearrange how lfconvert detects non-local repos
Greg Ward <greg@gerg.ca>
parents: 15339
diff changeset
50 raise util.Abort(_('%s is not a local Mercurial repo') % dest)
0e58513cc59a largefiles: rearrange how lfconvert detects non-local repos
Greg Ward <greg@gerg.ca>
parents: 15339
diff changeset
51
15339
be1377d19018 largefiles: test lfconvert error handling; remove redundant code
Greg Ward <greg@gerg.ca>
parents: 15332
diff changeset
52 rsrc = hg.repository(ui, src)
be1377d19018 largefiles: test lfconvert error handling; remove redundant code
Greg Ward <greg@gerg.ca>
parents: 15332
diff changeset
53 ui.status(_('initializing destination %s\n') % dest)
be1377d19018 largefiles: test lfconvert error handling; remove redundant code
Greg Ward <greg@gerg.ca>
parents: 15332
diff changeset
54 rdst = hg.repository(ui, dest, create=True)
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
55
15171
547da6115d1d largefiles: eliminate naked exceptions
Matt Mackall <mpm@selenic.com>
parents: 15170
diff changeset
56 success = False
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
57 try:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
58 # Lock destination to prevent modification while it is converted to.
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
59 # Don't need to lock src because we are just reading from its history
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
60 # which can't change.
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
61 dst_lock = rdst.lock()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
62
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
63 # Get a list of all changesets in the source. The easy way to do this
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
64 # is to simply walk the changelog, using changelog.nodesbewteen().
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
65 # Take a look at mercurial/revlog.py:639 for more details.
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
66 # Use a generator instead of a list to decrease memory usage
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
67 ctxs = (rsrc[ctx] for ctx in rsrc.changelog.nodesbetween(None,
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
68 rsrc.heads())[0])
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
69 revmap = {node.nullid: node.nullid}
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
70 if tolfile:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
71 lfiles = set()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
72 normalfiles = set()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
73 if not pats:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
74 pats = ui.config(lfutil.longname, 'patterns', default=())
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
75 if pats:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
76 pats = pats.split(' ')
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
77 if pats:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
78 matcher = match_.match(rsrc.root, '', list(pats))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
79 else:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
80 matcher = None
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
81
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
82 lfiletohash = {}
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
83 for ctx in ctxs:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
84 ui.progress(_('converting revisions'), ctx.rev(),
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
85 unit=_('revision'), total=rsrc['tip'].rev())
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
86 _lfconvert_addchangeset(rsrc, rdst, ctx, revmap,
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
87 lfiles, normalfiles, matcher, size, lfiletohash)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
88 ui.progress(_('converting revisions'), None)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
89
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
90 if os.path.exists(rdst.wjoin(lfutil.shortname)):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
91 shutil.rmtree(rdst.wjoin(lfutil.shortname))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
92
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
93 for f in lfiletohash.keys():
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
94 if os.path.isfile(rdst.wjoin(f)):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
95 os.unlink(rdst.wjoin(f))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
96 try:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
97 os.removedirs(os.path.dirname(rdst.wjoin(f)))
15171
547da6115d1d largefiles: eliminate naked exceptions
Matt Mackall <mpm@selenic.com>
parents: 15170
diff changeset
98 except OSError:
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
99 pass
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
100
15303
07811b3b119b largefiles: include 'largefiles' in converted repository requirements
Eli Carter <eli.carter@tektronix.com>
parents: 15255
diff changeset
101 # If there were any files converted to largefiles, add largefiles
07811b3b119b largefiles: include 'largefiles' in converted repository requirements
Eli Carter <eli.carter@tektronix.com>
parents: 15255
diff changeset
102 # to the destination repository's requirements.
07811b3b119b largefiles: include 'largefiles' in converted repository requirements
Eli Carter <eli.carter@tektronix.com>
parents: 15255
diff changeset
103 if lfiles:
07811b3b119b largefiles: include 'largefiles' in converted repository requirements
Eli Carter <eli.carter@tektronix.com>
parents: 15255
diff changeset
104 rdst.requirements.add('largefiles')
07811b3b119b largefiles: include 'largefiles' in converted repository requirements
Eli Carter <eli.carter@tektronix.com>
parents: 15255
diff changeset
105 rdst._writerequirements()
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
106 else:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
107 for ctx in ctxs:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
108 ui.progress(_('converting revisions'), ctx.rev(),
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
109 unit=_('revision'), total=rsrc['tip'].rev())
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
110 _addchangeset(ui, rsrc, rdst, ctx, revmap)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
111
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
112 ui.progress(_('converting revisions'), None)
15171
547da6115d1d largefiles: eliminate naked exceptions
Matt Mackall <mpm@selenic.com>
parents: 15170
diff changeset
113 success = True
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
114 finally:
15171
547da6115d1d largefiles: eliminate naked exceptions
Matt Mackall <mpm@selenic.com>
parents: 15170
diff changeset
115 if not success:
547da6115d1d largefiles: eliminate naked exceptions
Matt Mackall <mpm@selenic.com>
parents: 15170
diff changeset
116 # we failed, remove the new directory
547da6115d1d largefiles: eliminate naked exceptions
Matt Mackall <mpm@selenic.com>
parents: 15170
diff changeset
117 shutil.rmtree(rdst.root)
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
118 dst_lock.release()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
119
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
120 def _addchangeset(ui, rsrc, rdst, ctx, revmap):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
121 # Convert src parents to dst parents
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
122 parents = []
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
123 for p in ctx.parents():
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
124 parents.append(revmap[p.node()])
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
125 while len(parents) < 2:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
126 parents.append(node.nullid)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
127
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
128 # Generate list of changed files
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
129 files = set(ctx.files())
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
130 if node.nullid not in parents:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
131 mc = ctx.manifest()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
132 mp1 = ctx.parents()[0].manifest()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
133 mp2 = ctx.parents()[1].manifest()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
134 files |= (set(mp1) | set(mp2)) - set(mc)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
135 for f in mc:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
136 if mc[f] != mp1.get(f, None) or mc[f] != mp2.get(f, None):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
137 files.add(f)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
138
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
139 def getfilectx(repo, memctx, f):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
140 if lfutil.standin(f) in files:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
141 # if the file isn't in the manifest then it was removed
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
142 # or renamed, raise IOError to indicate this
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
143 try:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
144 fctx = ctx.filectx(lfutil.standin(f))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
145 except error.LookupError:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
146 raise IOError()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
147 renamed = fctx.renamed()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
148 if renamed:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
149 renamed = lfutil.splitstandin(renamed[0])
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
150
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
151 hash = fctx.data().strip()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
152 path = lfutil.findfile(rsrc, hash)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
153 ### TODO: What if the file is not cached?
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
154 data = ''
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
155 fd = None
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
156 try:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
157 fd = open(path, 'rb')
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
158 data = fd.read()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
159 finally:
15172
fb1dcd2aae2a largefiles: fix multistatement line
Matt Mackall <mpm@selenic.com>
parents: 15171
diff changeset
160 if fd:
fb1dcd2aae2a largefiles: fix multistatement line
Matt Mackall <mpm@selenic.com>
parents: 15171
diff changeset
161 fd.close()
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
162 return context.memfilectx(f, data, 'l' in fctx.flags(),
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
163 'x' in fctx.flags(), renamed)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
164 else:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
165 try:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
166 fctx = ctx.filectx(f)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
167 except error.LookupError:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
168 raise IOError()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
169 renamed = fctx.renamed()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
170 if renamed:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
171 renamed = renamed[0]
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
172 data = fctx.data()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
173 if f == '.hgtags':
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
174 newdata = []
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
175 for line in data.splitlines():
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
176 id, name = line.split(' ', 1)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
177 newdata.append('%s %s\n' % (node.hex(revmap[node.bin(id)]),
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
178 name))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
179 data = ''.join(newdata)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
180 return context.memfilectx(f, data, 'l' in fctx.flags(),
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
181 'x' in fctx.flags(), renamed)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
182
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
183 dstfiles = []
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
184 for file in files:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
185 if lfutil.isstandin(file):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
186 dstfiles.append(lfutil.splitstandin(file))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
187 else:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
188 dstfiles.append(file)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
189 # Commit
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
190 mctx = context.memctx(rdst, parents, ctx.description(), dstfiles,
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
191 getfilectx, ctx.user(), ctx.date(), ctx.extra())
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
192 ret = rdst.commitctx(mctx)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
193 rdst.dirstate.setparents(ret)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
194 revmap[ctx.node()] = rdst.changelog.tip()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
195
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
196 def _lfconvert_addchangeset(rsrc, rdst, ctx, revmap, lfiles, normalfiles,
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
197 matcher, size, lfiletohash):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
198 # Convert src parents to dst parents
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
199 parents = []
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
200 for p in ctx.parents():
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
201 parents.append(revmap[p.node()])
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
202 while len(parents) < 2:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
203 parents.append(node.nullid)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
204
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
205 # Generate list of changed files
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
206 files = set(ctx.files())
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
207 if node.nullid not in parents:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
208 mc = ctx.manifest()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
209 mp1 = ctx.parents()[0].manifest()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
210 mp2 = ctx.parents()[1].manifest()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
211 files |= (set(mp1) | set(mp2)) - set(mc)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
212 for f in mc:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
213 if mc[f] != mp1.get(f, None) or mc[f] != mp2.get(f, None):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
214 files.add(f)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
215
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
216 dstfiles = []
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
217 for f in files:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
218 if f not in lfiles and f not in normalfiles:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
219 islfile = _islfile(f, ctx, matcher, size)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
220 # If this file was renamed or copied then copy
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
221 # the lfileness of its predecessor
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
222 if f in ctx.manifest():
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
223 fctx = ctx.filectx(f)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
224 renamed = fctx.renamed()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
225 renamedlfile = renamed and renamed[0] in lfiles
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
226 islfile |= renamedlfile
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
227 if 'l' in fctx.flags():
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
228 if renamedlfile:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
229 raise util.Abort(
15380
a53888685a6c largefiles: fix uppercase in abort message
Martin Geisler <mg@aragost.com>
parents: 15371
diff changeset
230 _('renamed/copied largefile %s becomes symlink')
15170
c1a4a3220711 largefiles: fix over-long lines
Matt Mackall <mpm@selenic.com>
parents: 15168
diff changeset
231 % f)
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
232 islfile = False
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
233 if islfile:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
234 lfiles.add(f)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
235 else:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
236 normalfiles.add(f)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
237
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
238 if f in lfiles:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
239 dstfiles.append(lfutil.standin(f))
15254
dd03d3a9f888 largefiles: more work on cleaning up comments
Greg Ward <greg@gerg.ca>
parents: 15253
diff changeset
240 # largefile in manifest if it has not been removed/renamed
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
241 if f in ctx.manifest():
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
242 if 'l' in ctx.filectx(f).flags():
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
243 if renamed and renamed[0] in lfiles:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
244 raise util.Abort(_('largefile %s becomes symlink') % f)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
245
15254
dd03d3a9f888 largefiles: more work on cleaning up comments
Greg Ward <greg@gerg.ca>
parents: 15253
diff changeset
246 # largefile was modified, update standins
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
247 fullpath = rdst.wjoin(f)
15371
f26ed4ea46d8 largefiles: remove lfutil.createdir, replace calls with util.makedirs
Hao Lian <hao@fogcreek.com>
parents: 15340
diff changeset
248 util.makedirs(os.path.dirname(fullpath))
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
249 m = util.sha1('')
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
250 m.update(ctx[f].data())
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
251 hash = m.hexdigest()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
252 if f not in lfiletohash or lfiletohash[f] != hash:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
253 try:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
254 fd = open(fullpath, 'wb')
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
255 fd.write(ctx[f].data())
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
256 finally:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
257 if fd:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
258 fd.close()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
259 executable = 'x' in ctx[f].flags()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
260 os.chmod(fullpath, lfutil.getmode(executable))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
261 lfutil.writestandin(rdst, lfutil.standin(f), hash,
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
262 executable)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
263 lfiletohash[f] = hash
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
264 else:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
265 # normal file
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
266 dstfiles.append(f)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
267
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
268 def getfilectx(repo, memctx, f):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
269 if lfutil.isstandin(f):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
270 # if the file isn't in the manifest then it was removed
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
271 # or renamed, raise IOError to indicate this
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
272 srcfname = lfutil.splitstandin(f)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
273 try:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
274 fctx = ctx.filectx(srcfname)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
275 except error.LookupError:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
276 raise IOError()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
277 renamed = fctx.renamed()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
278 if renamed:
15254
dd03d3a9f888 largefiles: more work on cleaning up comments
Greg Ward <greg@gerg.ca>
parents: 15253
diff changeset
279 # standin is always a largefile because largefile-ness
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
280 # doesn't change after rename or copy
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
281 renamed = lfutil.standin(renamed[0])
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
282
15313
3eb1a90ea409 largefiles: fix newline for lfconverted repos
Eli Carter <eli.carter@tektronix.com>
parents: 15303
diff changeset
283 return context.memfilectx(f, lfiletohash[srcfname] + '\n', 'l' in
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
284 fctx.flags(), 'x' in fctx.flags(), renamed)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
285 else:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
286 try:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
287 fctx = ctx.filectx(f)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
288 except error.LookupError:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
289 raise IOError()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
290 renamed = fctx.renamed()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
291 if renamed:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
292 renamed = renamed[0]
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
293
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
294 data = fctx.data()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
295 if f == '.hgtags':
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
296 newdata = []
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
297 for line in data.splitlines():
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
298 id, name = line.split(' ', 1)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
299 newdata.append('%s %s\n' % (node.hex(revmap[node.bin(id)]),
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
300 name))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
301 data = ''.join(newdata)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
302 return context.memfilectx(f, data, 'l' in fctx.flags(),
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
303 'x' in fctx.flags(), renamed)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
304
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
305 # Commit
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
306 mctx = context.memctx(rdst, parents, ctx.description(), dstfiles,
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
307 getfilectx, ctx.user(), ctx.date(), ctx.extra())
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
308 ret = rdst.commitctx(mctx)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
309 rdst.dirstate.setparents(ret)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
310 revmap[ctx.node()] = rdst.changelog.tip()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
311
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
312 def _islfile(file, ctx, matcher, size):
15252
6e809bb4f969 largefiles: improve comments, internal docstrings
Greg Ward <greg@gerg.ca>
parents: 15230
diff changeset
313 '''Return true if file should be considered a largefile, i.e.
6e809bb4f969 largefiles: improve comments, internal docstrings
Greg Ward <greg@gerg.ca>
parents: 15230
diff changeset
314 matcher matches it or it is larger than size.'''
6e809bb4f969 largefiles: improve comments, internal docstrings
Greg Ward <greg@gerg.ca>
parents: 15230
diff changeset
315 # never store special .hg* files as largefiles
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
316 if file == '.hgtags' or file == '.hgignore' or file == '.hgsigs':
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
317 return False
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
318 if matcher and matcher(file):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
319 return True
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
320 try:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
321 return ctx.filectx(file).size() >= size * 1024 * 1024
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
322 except error.LookupError:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
323 return False
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
324
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
325 def uploadlfiles(ui, rsrc, rdst, files):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
326 '''upload largefiles to the central store'''
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
327
15317
41f371150ccb largefiles: make the store primary, and the user cache secondary
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15313
diff changeset
328 if not files:
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
329 return
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
330
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
331 store = basestore._openstore(rsrc, rdst, put=True)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
332
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
333 at = 0
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
334 files = filter(lambda h: not store.exists(h), files)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
335 for hash in files:
15170
c1a4a3220711 largefiles: fix over-long lines
Matt Mackall <mpm@selenic.com>
parents: 15168
diff changeset
336 ui.progress(_('uploading largefiles'), at, unit='largefile',
c1a4a3220711 largefiles: fix over-long lines
Matt Mackall <mpm@selenic.com>
parents: 15168
diff changeset
337 total=len(files))
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
338 source = lfutil.findfile(rsrc, hash)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
339 if not source:
15253
67d010779907 largefiles: improve error reporting
Greg Ward <greg@gerg.ca>
parents: 15252
diff changeset
340 raise util.Abort(_('largefile %s missing from store'
67d010779907 largefiles: improve error reporting
Greg Ward <greg@gerg.ca>
parents: 15252
diff changeset
341 ' (needs to be uploaded)') % hash)
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
342 # XXX check for errors here
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
343 store.put(source, hash)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
344 at += 1
15173
3d27a8ff895f largefiles: mark a string for translation
Matt Mackall <mpm@selenic.com>
parents: 15172
diff changeset
345 ui.progress(_('uploading largefiles'), None)
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
346
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
347 def verifylfiles(ui, repo, all=False, contents=False):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
348 '''Verify that every big file revision in the current changeset
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
349 exists in the central store. With --contents, also verify that
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
350 the contents of each big file revision are correct (SHA-1 hash
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
351 matches the revision ID). With --all, check every changeset in
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
352 this repository.'''
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
353 if all:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
354 # Pass a list to the function rather than an iterator because we know a
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
355 # list will work.
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
356 revs = range(len(repo))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
357 else:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
358 revs = ['.']
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
359
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
360 store = basestore._openstore(repo)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
361 return store.verify(revs, contents=contents)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
362
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
363 def cachelfiles(ui, repo, node):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
364 '''cachelfiles ensures that all largefiles needed by the specified revision
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
365 are present in the repository's largefile cache.
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
366
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
367 returns a tuple (cached, missing). cached is the list of files downloaded
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
368 by this operation; missing is the list of files that were needed but could
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
369 not be found.'''
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
370 lfiles = lfutil.listlfiles(repo, node)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
371 toget = []
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
372
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
373 for lfile in lfiles:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
374 expectedhash = repo[node][lfutil.standin(lfile)].data().strip()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
375 # if it exists and its hash matches, it might have been locally
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
376 # modified before updating and the user chose 'local'. in this case,
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
377 # it will not be in any store, so don't look for it.
15255
7ab05d752405 largefiles: cosmetics, whitespace, code style
Greg Ward <greg@gerg.ca>
parents: 15254
diff changeset
378 if ((not os.path.exists(repo.wjoin(lfile)) or
7ab05d752405 largefiles: cosmetics, whitespace, code style
Greg Ward <greg@gerg.ca>
parents: 15254
diff changeset
379 expectedhash != lfutil.hashfile(repo.wjoin(lfile))) and
7ab05d752405 largefiles: cosmetics, whitespace, code style
Greg Ward <greg@gerg.ca>
parents: 15254
diff changeset
380 not lfutil.findfile(repo, expectedhash)):
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
381 toget.append((lfile, expectedhash))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
382
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
383 if toget:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
384 store = basestore._openstore(repo)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
385 ret = store.get(toget)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
386 return ret
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
387
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
388 return ([], [])
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
389
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
390 def updatelfiles(ui, repo, filelist=None, printmessage=True):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
391 wlock = repo.wlock()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
392 try:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
393 lfdirstate = lfutil.openlfdirstate(ui, repo)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
394 lfiles = set(lfutil.listlfiles(repo)) | set(lfdirstate)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
395
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
396 if filelist is not None:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
397 lfiles = [f for f in lfiles if f in filelist]
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
398
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
399 printed = False
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
400 if printmessage and lfiles:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
401 ui.status(_('getting changed largefiles\n'))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
402 printed = True
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
403 cachelfiles(ui, repo, '.')
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
404
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
405 updated, removed = 0, 0
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
406 for i in map(lambda f: _updatelfile(repo, lfdirstate, f), lfiles):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
407 # increment the appropriate counter according to _updatelfile's
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
408 # return value
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
409 updated += i > 0 and i or 0
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
410 removed -= i < 0 and i or 0
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
411 if printmessage and (removed or updated) and not printed:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
412 ui.status(_('getting changed largefiles\n'))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
413 printed = True
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
414
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
415 lfdirstate.write()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
416 if printed and printmessage:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
417 ui.status(_('%d largefiles updated, %d removed\n') % (updated,
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
418 removed))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
419 finally:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
420 wlock.release()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
421
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
422 def _updatelfile(repo, lfdirstate, lfile):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
423 '''updates a single largefile and copies the state of its standin from
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
424 the repository's dirstate to its state in the lfdirstate.
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
425
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
426 returns 1 if the file was modified, -1 if the file was removed, 0 if the
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
427 file was unchanged, and None if the needed largefile was missing from the
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
428 cache.'''
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
429 ret = 0
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
430 abslfile = repo.wjoin(lfile)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
431 absstandin = repo.wjoin(lfutil.standin(lfile))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
432 if os.path.exists(absstandin):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
433 if os.path.exists(absstandin+'.orig'):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
434 shutil.copyfile(abslfile, abslfile+'.orig')
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
435 expecthash = lfutil.readstandin(repo, lfile)
15255
7ab05d752405 largefiles: cosmetics, whitespace, code style
Greg Ward <greg@gerg.ca>
parents: 15254
diff changeset
436 if (expecthash != '' and
7ab05d752405 largefiles: cosmetics, whitespace, code style
Greg Ward <greg@gerg.ca>
parents: 15254
diff changeset
437 (not os.path.exists(abslfile) or
7ab05d752405 largefiles: cosmetics, whitespace, code style
Greg Ward <greg@gerg.ca>
parents: 15254
diff changeset
438 expecthash != lfutil.hashfile(abslfile))):
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
439 if not lfutil.copyfromcache(repo, expecthash, lfile):
15472
6a7e874390b0 largefiles: treat status of cache missed largefiles as "missing" correctly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15380
diff changeset
440 # use normallookup() to allocate entry in largefiles dirstate,
6a7e874390b0 largefiles: treat status of cache missed largefiles as "missing" correctly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15380
diff changeset
441 # because lack of it misleads lfiles_repo.status() into
6a7e874390b0 largefiles: treat status of cache missed largefiles as "missing" correctly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15380
diff changeset
442 # recognition that such cache missing files are REMOVED.
6a7e874390b0 largefiles: treat status of cache missed largefiles as "missing" correctly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15380
diff changeset
443 lfdirstate.normallookup(lfile)
6a7e874390b0 largefiles: treat status of cache missed largefiles as "missing" correctly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15380
diff changeset
444 return None # don't try to set the mode
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
445 ret = 1
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
446 mode = os.stat(absstandin).st_mode
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
447 if mode != os.stat(abslfile).st_mode:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
448 os.chmod(abslfile, mode)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
449 ret = 1
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
450 else:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
451 if os.path.exists(abslfile):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
452 os.unlink(abslfile)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
453 ret = -1
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
454 state = repo.dirstate[lfutil.standin(lfile)]
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
455 if state == 'n':
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
456 lfdirstate.normal(lfile)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
457 elif state == 'r':
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
458 lfdirstate.remove(lfile)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
459 elif state == 'a':
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
460 lfdirstate.add(lfile)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
461 elif state == '?':
15224
7c604d8c7e83 largefiles: remove pre-1.9 code from extension first bundled with 1.9
Na'Tosha Bard <natosha@unity3d.com>
parents: 15173
diff changeset
462 lfdirstate.drop(lfile)
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
463 return ret
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
464
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
465 # -- hg commands declarations ------------------------------------------------
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
466
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
467 cmdtable = {
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
468 'lfconvert': (lfconvert,
15230
697289c5d415 largefiles: improve help
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
469 [('s', 'size', '',
697289c5d415 largefiles: improve help
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
470 _('minimum size (MB) for files to be converted '
697289c5d415 largefiles: improve help
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
471 'as largefiles'),
697289c5d415 largefiles: improve help
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
472 'SIZE'),
15332
0db47b8d025f largefiles: rename lfconvert --tonormal option to --to-normal
Greg Ward <greg@gerg.ca>
parents: 15317
diff changeset
473 ('', 'to-normal', False,
15230
697289c5d415 largefiles: improve help
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
474 _('convert from a largefiles repo to a normal repo')),
697289c5d415 largefiles: improve help
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
475 ],
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
476 _('hg lfconvert SOURCE DEST [FILE ...]')),
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
477 }