annotate hgext/largefiles/lfutil.py @ 15316:c65f5b6e26d4 stable

largefiles: rename functions and methods to match desired behavior The original intent was that the largefiles would primarily be in the repository, with the global cache being only that--a cache. The naming conventions and actual intent have both strayed. In this first patch, the naming conventions are switched to match the actual intent, as are the configuration options.
author Benjamin Pollack <benjamin@bitquabit.com>
date Thu, 20 Oct 2011 13:24:09 -0400
parents 9aa9d4bb3d88
children 41f371150ccb
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
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
9 '''largefiles utility code: must not import other modules in this package.'''
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 errno
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
13 import shutil
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
14 import stat
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
15 import hashlib
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
16
15226
2223ea21c98f largefiles: cleanup import, now that we can assume > 1.9 for bundled extension
Na'Tosha Bard <natosha@unity3d.com>
parents: 15224
diff changeset
17 from mercurial import dirstate, httpconnection, match as match_, util, scmutil
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
18 from mercurial.i18n import _
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
19
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
20 shortname = '.hglf'
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
21 longname = 'largefiles'
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
22
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
23
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
24 # -- Portability wrappers ----------------------------------------------
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
25
15224
7c604d8c7e83 largefiles: remove pre-1.9 code from extension first bundled with 1.9
Na'Tosha Bard <natosha@unity3d.com>
parents: 15206
diff changeset
26 def dirstate_walk(dirstate, matcher, unknown=False, ignored=False):
7c604d8c7e83 largefiles: remove pre-1.9 code from extension first bundled with 1.9
Na'Tosha Bard <natosha@unity3d.com>
parents: 15206
diff changeset
27 return dirstate.walk(matcher, [], unknown, ignored)
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
28
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
29 def repo_add(repo, list):
15224
7c604d8c7e83 largefiles: remove pre-1.9 code from extension first bundled with 1.9
Na'Tosha Bard <natosha@unity3d.com>
parents: 15206
diff changeset
30 add = repo[None].add
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
31 return add(list)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
32
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
33 def repo_remove(repo, list, unlink=False):
15224
7c604d8c7e83 largefiles: remove pre-1.9 code from extension first bundled with 1.9
Na'Tosha Bard <natosha@unity3d.com>
parents: 15206
diff changeset
34 def remove(list, unlink):
7c604d8c7e83 largefiles: remove pre-1.9 code from extension first bundled with 1.9
Na'Tosha Bard <natosha@unity3d.com>
parents: 15206
diff changeset
35 wlock = repo.wlock()
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
36 try:
15224
7c604d8c7e83 largefiles: remove pre-1.9 code from extension first bundled with 1.9
Na'Tosha Bard <natosha@unity3d.com>
parents: 15206
diff changeset
37 if unlink:
7c604d8c7e83 largefiles: remove pre-1.9 code from extension first bundled with 1.9
Na'Tosha Bard <natosha@unity3d.com>
parents: 15206
diff changeset
38 for f in list:
7c604d8c7e83 largefiles: remove pre-1.9 code from extension first bundled with 1.9
Na'Tosha Bard <natosha@unity3d.com>
parents: 15206
diff changeset
39 try:
7c604d8c7e83 largefiles: remove pre-1.9 code from extension first bundled with 1.9
Na'Tosha Bard <natosha@unity3d.com>
parents: 15206
diff changeset
40 util.unlinkpath(repo.wjoin(f))
7c604d8c7e83 largefiles: remove pre-1.9 code from extension first bundled with 1.9
Na'Tosha Bard <natosha@unity3d.com>
parents: 15206
diff changeset
41 except OSError, inst:
7c604d8c7e83 largefiles: remove pre-1.9 code from extension first bundled with 1.9
Na'Tosha Bard <natosha@unity3d.com>
parents: 15206
diff changeset
42 if inst.errno != errno.ENOENT:
7c604d8c7e83 largefiles: remove pre-1.9 code from extension first bundled with 1.9
Na'Tosha Bard <natosha@unity3d.com>
parents: 15206
diff changeset
43 raise
7c604d8c7e83 largefiles: remove pre-1.9 code from extension first bundled with 1.9
Na'Tosha Bard <natosha@unity3d.com>
parents: 15206
diff changeset
44 repo[None].forget(list)
7c604d8c7e83 largefiles: remove pre-1.9 code from extension first bundled with 1.9
Na'Tosha Bard <natosha@unity3d.com>
parents: 15206
diff changeset
45 finally:
7c604d8c7e83 largefiles: remove pre-1.9 code from extension first bundled with 1.9
Na'Tosha Bard <natosha@unity3d.com>
parents: 15206
diff changeset
46 wlock.release()
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
47 return remove(list, unlink=unlink)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
48
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
49 def repo_forget(repo, list):
15224
7c604d8c7e83 largefiles: remove pre-1.9 code from extension first bundled with 1.9
Na'Tosha Bard <natosha@unity3d.com>
parents: 15206
diff changeset
50 forget = repo[None].forget
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
51 return forget(list)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
52
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
53 def findoutgoing(repo, remote, force):
15224
7c604d8c7e83 largefiles: remove pre-1.9 code from extension first bundled with 1.9
Na'Tosha Bard <natosha@unity3d.com>
parents: 15206
diff changeset
54 from mercurial import discovery
7c604d8c7e83 largefiles: remove pre-1.9 code from extension first bundled with 1.9
Na'Tosha Bard <natosha@unity3d.com>
parents: 15206
diff changeset
55 common, _anyinc, _heads = discovery.findcommonincoming(repo,
7c604d8c7e83 largefiles: remove pre-1.9 code from extension first bundled with 1.9
Na'Tosha Bard <natosha@unity3d.com>
parents: 15206
diff changeset
56 remote, force=force)
7c604d8c7e83 largefiles: remove pre-1.9 code from extension first bundled with 1.9
Na'Tosha Bard <natosha@unity3d.com>
parents: 15206
diff changeset
57 return repo.changelog.findmissing(common)
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
58
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
59 # -- Private worker functions ------------------------------------------
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
60
15227
a7686abf73a6 largefiles: factor out lfutil.getminsize()
Greg Ward <greg@gerg.ca>
parents: 15226
diff changeset
61 def getminsize(ui, assumelfiles, opt, default=10):
a7686abf73a6 largefiles: factor out lfutil.getminsize()
Greg Ward <greg@gerg.ca>
parents: 15226
diff changeset
62 lfsize = opt
a7686abf73a6 largefiles: factor out lfutil.getminsize()
Greg Ward <greg@gerg.ca>
parents: 15226
diff changeset
63 if not lfsize and assumelfiles:
15304
9aa9d4bb3d88 largefiles: rename config setting 'size' to 'minsize'
Greg Ward <greg@gerg.ca>
parents: 15255
diff changeset
64 lfsize = ui.config(longname, 'minsize', default=default)
15227
a7686abf73a6 largefiles: factor out lfutil.getminsize()
Greg Ward <greg@gerg.ca>
parents: 15226
diff changeset
65 if lfsize:
a7686abf73a6 largefiles: factor out lfutil.getminsize()
Greg Ward <greg@gerg.ca>
parents: 15226
diff changeset
66 try:
15228
ee625de3541e largefiles: allow minimum size to be a float
Greg Ward <greg@gerg.ca>
parents: 15227
diff changeset
67 lfsize = float(lfsize)
15227
a7686abf73a6 largefiles: factor out lfutil.getminsize()
Greg Ward <greg@gerg.ca>
parents: 15226
diff changeset
68 except ValueError:
15228
ee625de3541e largefiles: allow minimum size to be a float
Greg Ward <greg@gerg.ca>
parents: 15227
diff changeset
69 raise util.Abort(_('largefiles: size must be number (not %s)\n')
15227
a7686abf73a6 largefiles: factor out lfutil.getminsize()
Greg Ward <greg@gerg.ca>
parents: 15226
diff changeset
70 % lfsize)
a7686abf73a6 largefiles: factor out lfutil.getminsize()
Greg Ward <greg@gerg.ca>
parents: 15226
diff changeset
71 if lfsize is None:
a7686abf73a6 largefiles: factor out lfutil.getminsize()
Greg Ward <greg@gerg.ca>
parents: 15226
diff changeset
72 raise util.Abort(_('minimum size for largefiles must be specified'))
a7686abf73a6 largefiles: factor out lfutil.getminsize()
Greg Ward <greg@gerg.ca>
parents: 15226
diff changeset
73 return lfsize
a7686abf73a6 largefiles: factor out lfutil.getminsize()
Greg Ward <greg@gerg.ca>
parents: 15226
diff changeset
74
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
75 def link(src, dest):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
76 try:
15206
f85c76b16f27 largefiles: fix commit of specified file on non-windows
Na'Tosha Bard <natosha@unity3d.com>
parents: 15188
diff changeset
77 util.oslink(src, dest)
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
78 except OSError:
15252
6e809bb4f969 largefiles: improve comments, internal docstrings
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
79 # if hardlinks fail, fallback on copy
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
80 shutil.copyfile(src, dest)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
81 os.chmod(dest, os.stat(src).st_mode)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
82
15316
c65f5b6e26d4 largefiles: rename functions and methods to match desired behavior
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15304
diff changeset
83 def usercachepath(ui, hash):
c65f5b6e26d4 largefiles: rename functions and methods to match desired behavior
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15304
diff changeset
84 path = ui.config(longname, 'usercache', None)
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
85 if path:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
86 path = os.path.join(path, hash)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
87 else:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
88 if os.name == 'nt':
15255
7ab05d752405 largefiles: cosmetics, whitespace, code style
Greg Ward <greg@gerg.ca>
parents: 15253
diff changeset
89 appdata = os.getenv('LOCALAPPDATA', os.getenv('APPDATA'))
7ab05d752405 largefiles: cosmetics, whitespace, code style
Greg Ward <greg@gerg.ca>
parents: 15253
diff changeset
90 path = os.path.join(appdata, longname, hash)
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
91 elif os.name == 'posix':
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
92 path = os.path.join(os.getenv('HOME'), '.' + longname, hash)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
93 else:
15253
67d010779907 largefiles: improve error reporting
Greg Ward <greg@gerg.ca>
parents: 15252
diff changeset
94 raise util.Abort(_('unknown operating system: %s\n') % os.name)
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
95 return path
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
96
15316
c65f5b6e26d4 largefiles: rename functions and methods to match desired behavior
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15304
diff changeset
97 def inusercache(ui, hash):
c65f5b6e26d4 largefiles: rename functions and methods to match desired behavior
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15304
diff changeset
98 return os.path.exists(usercachepath(ui, hash))
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
99
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
100 def findfile(repo, hash):
15316
c65f5b6e26d4 largefiles: rename functions and methods to match desired behavior
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15304
diff changeset
101 if instore(repo, hash):
c65f5b6e26d4 largefiles: rename functions and methods to match desired behavior
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15304
diff changeset
102 repo.ui.note(_('Found %s in store\n') % hash)
c65f5b6e26d4 largefiles: rename functions and methods to match desired behavior
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15304
diff changeset
103 return storepath(repo, hash)
c65f5b6e26d4 largefiles: rename functions and methods to match desired behavior
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15304
diff changeset
104 if inusercache(repo.ui, hash):
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
105 repo.ui.note(_('Found %s in system cache\n') % hash)
15316
c65f5b6e26d4 largefiles: rename functions and methods to match desired behavior
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15304
diff changeset
106 return usercachepath(repo.ui, hash)
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
107 return None
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
108
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
109 class largefiles_dirstate(dirstate.dirstate):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
110 def __getitem__(self, key):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
111 return super(largefiles_dirstate, self).__getitem__(unixpath(key))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
112 def normal(self, f):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
113 return super(largefiles_dirstate, self).normal(unixpath(f))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
114 def remove(self, f):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
115 return super(largefiles_dirstate, self).remove(unixpath(f))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
116 def add(self, f):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
117 return super(largefiles_dirstate, self).add(unixpath(f))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
118 def drop(self, f):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
119 return super(largefiles_dirstate, self).drop(unixpath(f))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
120 def forget(self, f):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
121 return super(largefiles_dirstate, self).forget(unixpath(f))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
122
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
123 def openlfdirstate(ui, repo):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
124 '''
15252
6e809bb4f969 largefiles: improve comments, internal docstrings
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
125 Return a dirstate object that tracks largefiles: i.e. its root is
6e809bb4f969 largefiles: improve comments, internal docstrings
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
126 the repo root, but it is saved in .hg/largefiles/dirstate.
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
127 '''
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
128 admin = repo.join(longname)
15224
7c604d8c7e83 largefiles: remove pre-1.9 code from extension first bundled with 1.9
Na'Tosha Bard <natosha@unity3d.com>
parents: 15206
diff changeset
129 opener = scmutil.opener(admin)
15169
aa262fff87ac largefile: fix up hasattr usage
Matt Mackall <mpm@selenic.com>
parents: 15168
diff changeset
130 if util.safehasattr(repo.dirstate, '_validate'):
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
131 lfdirstate = largefiles_dirstate(opener, ui, repo.root,
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
132 repo.dirstate._validate)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
133 else:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
134 lfdirstate = largefiles_dirstate(opener, ui, repo.root)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
135
15252
6e809bb4f969 largefiles: improve comments, internal docstrings
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
136 # If the largefiles dirstate does not exist, populate and create
6e809bb4f969 largefiles: improve comments, internal docstrings
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
137 # it. This ensures that we create it on the first meaningful
6e809bb4f969 largefiles: improve comments, internal docstrings
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
138 # largefiles operation in a new clone. It also gives us an easy
6e809bb4f969 largefiles: improve comments, internal docstrings
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
139 # way to forcibly rebuild largefiles state:
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
140 # rm .hg/largefiles/dirstate && hg status
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
141 # Or even, if things are really messed up:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
142 # rm -rf .hg/largefiles && hg status
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
143 if not os.path.exists(os.path.join(admin, 'dirstate')):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
144 util.makedirs(admin)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
145 matcher = getstandinmatcher(repo)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
146 for standin in dirstate_walk(repo.dirstate, matcher):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
147 lfile = splitstandin(standin)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
148 hash = readstandin(repo, lfile)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
149 lfdirstate.normallookup(lfile)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
150 try:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
151 if hash == hashfile(lfile):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
152 lfdirstate.normal(lfile)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
153 except IOError, err:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
154 if err.errno != errno.ENOENT:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
155 raise
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
156
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
157 lfdirstate.write()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
158
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
159 return lfdirstate
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
160
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
161 def lfdirstate_status(lfdirstate, repo, rev):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
162 wlock = repo.wlock()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
163 try:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
164 match = match_.always(repo.root, repo.getcwd())
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
165 s = lfdirstate.status(match, [], False, False, False)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
166 unsure, modified, added, removed, missing, unknown, ignored, clean = s
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
167 for lfile in unsure:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
168 if repo[rev][standin(lfile)].data().strip() != \
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
169 hashfile(repo.wjoin(lfile)):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
170 modified.append(lfile)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
171 else:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
172 clean.append(lfile)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
173 lfdirstate.normal(lfile)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
174 lfdirstate.write()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
175 finally:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
176 wlock.release()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
177 return (modified, added, removed, missing, unknown, ignored, clean)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
178
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
179 def listlfiles(repo, rev=None, matcher=None):
15252
6e809bb4f969 largefiles: improve comments, internal docstrings
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
180 '''return a list of largefiles in the working copy or the
6e809bb4f969 largefiles: improve comments, internal docstrings
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
181 specified changeset'''
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
182
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
183 if matcher is None:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
184 matcher = getstandinmatcher(repo)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
185
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
186 # ignore unknown files in working directory
15255
7ab05d752405 largefiles: cosmetics, whitespace, code style
Greg Ward <greg@gerg.ca>
parents: 15253
diff changeset
187 return [splitstandin(f)
7ab05d752405 largefiles: cosmetics, whitespace, code style
Greg Ward <greg@gerg.ca>
parents: 15253
diff changeset
188 for f in repo[rev].walk(matcher)
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
189 if rev is not None or repo.dirstate[f] != '?']
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
190
15316
c65f5b6e26d4 largefiles: rename functions and methods to match desired behavior
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15304
diff changeset
191 def instore(repo, hash):
c65f5b6e26d4 largefiles: rename functions and methods to match desired behavior
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15304
diff changeset
192 return os.path.exists(storepath(repo, hash))
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
193
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
194 def createdir(dir):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
195 if not os.path.exists(dir):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
196 os.makedirs(dir)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
197
15316
c65f5b6e26d4 largefiles: rename functions and methods to match desired behavior
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15304
diff changeset
198 def storepath(repo, hash):
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
199 return repo.join(os.path.join(longname, hash))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
200
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
201 def copyfromcache(repo, hash, filename):
15252
6e809bb4f969 largefiles: improve comments, internal docstrings
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
202 '''Copy the specified largefile from the repo or system cache to
6e809bb4f969 largefiles: improve comments, internal docstrings
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
203 filename in the repository. Return true on success or false if the
6e809bb4f969 largefiles: improve comments, internal docstrings
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
204 file was not found in either cache (which should not happened:
6e809bb4f969 largefiles: improve comments, internal docstrings
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
205 this is meant to be called only after ensuring that the needed
6e809bb4f969 largefiles: improve comments, internal docstrings
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
206 largefile exists in the cache).'''
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
207 path = findfile(repo, hash)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
208 if path is None:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
209 return False
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
210 util.makedirs(os.path.dirname(repo.wjoin(filename)))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
211 shutil.copy(path, repo.wjoin(filename))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
212 return True
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
213
15316
c65f5b6e26d4 largefiles: rename functions and methods to match desired behavior
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15304
diff changeset
214 def copytostore(repo, rev, file, uploaded=False):
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
215 hash = readstandin(repo, file)
15316
c65f5b6e26d4 largefiles: rename functions and methods to match desired behavior
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15304
diff changeset
216 if instore(repo, hash):
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
217 return
15316
c65f5b6e26d4 largefiles: rename functions and methods to match desired behavior
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15304
diff changeset
218 copytostoreabsolute(repo, repo.wjoin(file), hash)
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
219
15316
c65f5b6e26d4 largefiles: rename functions and methods to match desired behavior
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15304
diff changeset
220 def copytostoreabsolute(repo, file, hash):
c65f5b6e26d4 largefiles: rename functions and methods to match desired behavior
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15304
diff changeset
221 createdir(os.path.dirname(storepath(repo, hash)))
c65f5b6e26d4 largefiles: rename functions and methods to match desired behavior
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15304
diff changeset
222 if inusercache(repo.ui, hash):
c65f5b6e26d4 largefiles: rename functions and methods to match desired behavior
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15304
diff changeset
223 link(usercachepath(repo.ui, hash), storepath(repo, hash))
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
224 else:
15316
c65f5b6e26d4 largefiles: rename functions and methods to match desired behavior
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15304
diff changeset
225 shutil.copyfile(file, storepath(repo, hash))
c65f5b6e26d4 largefiles: rename functions and methods to match desired behavior
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15304
diff changeset
226 os.chmod(storepath(repo, hash), os.stat(file).st_mode)
c65f5b6e26d4 largefiles: rename functions and methods to match desired behavior
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15304
diff changeset
227 linktousercache(repo, hash)
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
228
15316
c65f5b6e26d4 largefiles: rename functions and methods to match desired behavior
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15304
diff changeset
229 def linktousercache(repo, hash):
c65f5b6e26d4 largefiles: rename functions and methods to match desired behavior
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15304
diff changeset
230 createdir(os.path.dirname(usercachepath(repo.ui, hash)))
c65f5b6e26d4 largefiles: rename functions and methods to match desired behavior
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15304
diff changeset
231 link(storepath(repo, hash), usercachepath(repo.ui, hash))
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
232
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
233 def getstandinmatcher(repo, pats=[], opts={}):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
234 '''Return a match object that applies pats to the standin directory'''
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
235 standindir = repo.pathto(shortname)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
236 if pats:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
237 # patterns supplied: search standin directory relative to current dir
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
238 cwd = repo.getcwd()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
239 if os.path.isabs(cwd):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
240 # cwd is an absolute path for hg -R <reponame>
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
241 # work relative to the repository root in this case
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
242 cwd = ''
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
243 pats = [os.path.join(standindir, cwd, pat) for pat in pats]
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
244 elif os.path.isdir(standindir):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
245 # no patterns: relative to repo root
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
246 pats = [standindir]
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
247 else:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
248 # no patterns and no standin dir: return matcher that matches nothing
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
249 match = match_.match(repo.root, None, [], exact=True)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
250 match.matchfn = lambda f: False
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
251 return match
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
252 return getmatcher(repo, pats, opts, showbad=False)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
253
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
254 def getmatcher(repo, pats=[], opts={}, showbad=True):
15252
6e809bb4f969 largefiles: improve comments, internal docstrings
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
255 '''Wrapper around scmutil.match() that adds showbad: if false,
6e809bb4f969 largefiles: improve comments, internal docstrings
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
256 neuter the match object's bad() method so it does not print any
6e809bb4f969 largefiles: improve comments, internal docstrings
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
257 warnings about missing files or directories.'''
15224
7c604d8c7e83 largefiles: remove pre-1.9 code from extension first bundled with 1.9
Na'Tosha Bard <natosha@unity3d.com>
parents: 15206
diff changeset
258 match = scmutil.match(repo[None], pats, opts)
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
259
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
260 if not showbad:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
261 match.bad = lambda f, msg: None
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
262 return match
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
263
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
264 def composestandinmatcher(repo, rmatcher):
15252
6e809bb4f969 largefiles: improve comments, internal docstrings
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
265 '''Return a matcher that accepts standins corresponding to the
6e809bb4f969 largefiles: improve comments, internal docstrings
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
266 files accepted by rmatcher. Pass the list of files in the matcher
6e809bb4f969 largefiles: improve comments, internal docstrings
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
267 as the paths specified by the user.'''
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
268 smatcher = getstandinmatcher(repo, rmatcher.files())
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
269 isstandin = smatcher.matchfn
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
270 def composed_matchfn(f):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
271 return isstandin(f) and rmatcher.matchfn(splitstandin(f))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
272 smatcher.matchfn = composed_matchfn
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
273
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
274 return smatcher
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
275
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
276 def standin(filename):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
277 '''Return the repo-relative path to the standin for the specified big
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
278 file.'''
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
279 # Notes:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
280 # 1) Most callers want an absolute path, but _create_standin() needs
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
281 # it repo-relative so lfadd() can pass it to repo_add(). So leave
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
282 # it up to the caller to use repo.wjoin() to get an absolute path.
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
283 # 2) Join with '/' because that's what dirstate always uses, even on
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
284 # Windows. Change existing separator to '/' first in case we are
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
285 # passed filenames from an external source (like the command line).
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
286 return shortname + '/' + filename.replace(os.sep, '/')
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
287
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
288 def isstandin(filename):
15252
6e809bb4f969 largefiles: improve comments, internal docstrings
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
289 '''Return true if filename is a big file standin. filename must be
6e809bb4f969 largefiles: improve comments, internal docstrings
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
290 in Mercurial's internal form (slash-separated).'''
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
291 return filename.startswith(shortname + '/')
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
292
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
293 def splitstandin(filename):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
294 # Split on / because that's what dirstate always uses, even on Windows.
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
295 # Change local separator to / first just in case we are passed filenames
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
296 # from an external source (like the command line).
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
297 bits = filename.replace(os.sep, '/').split('/', 1)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
298 if len(bits) == 2 and bits[0] == shortname:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
299 return bits[1]
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
300 else:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
301 return None
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
302
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
303 def updatestandin(repo, standin):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
304 file = repo.wjoin(splitstandin(standin))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
305 if os.path.exists(file):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
306 hash = hashfile(file)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
307 executable = getexecutable(file)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
308 writestandin(repo, standin, hash, executable)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
309
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
310 def readstandin(repo, filename, node=None):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
311 '''read hex hash from standin for filename at given node, or working
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
312 directory if no node is given'''
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
313 return repo[node][standin(filename)].data().strip()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
314
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
315 def writestandin(repo, standin, hash, executable):
15252
6e809bb4f969 largefiles: improve comments, internal docstrings
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
316 '''write hash to <repo.root>/<standin>'''
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
317 writehash(hash, repo.wjoin(standin), executable)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
318
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
319 def copyandhash(instream, outfile):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
320 '''Read bytes from instream (iterable) and write them to outfile,
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
321 computing the SHA-1 hash of the data along the way. Close outfile
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
322 when done and return the binary hash.'''
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
323 hasher = util.sha1('')
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
324 for data in instream:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
325 hasher.update(data)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
326 outfile.write(data)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
327
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
328 # Blecch: closing a file that somebody else opened is rude and
15252
6e809bb4f969 largefiles: improve comments, internal docstrings
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
329 # wrong. But it's so darn convenient and practical! After all,
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
330 # outfile was opened just to copy and hash.
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
331 outfile.close()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
332
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
333 return hasher.digest()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
334
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
335 def hashrepofile(repo, file):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
336 return hashfile(repo.wjoin(file))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
337
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
338 def hashfile(file):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
339 if not os.path.exists(file):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
340 return ''
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
341 hasher = util.sha1('')
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
342 fd = open(file, 'rb')
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
343 for data in blockstream(fd):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
344 hasher.update(data)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
345 fd.close()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
346 return hasher.hexdigest()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
347
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
348 class limitreader(object):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
349 def __init__(self, f, limit):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
350 self.f = f
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
351 self.limit = limit
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
352
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
353 def read(self, length):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
354 if self.limit == 0:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
355 return ''
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
356 length = length > self.limit and self.limit or length
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
357 self.limit -= length
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
358 return self.f.read(length)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
359
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
360 def close(self):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
361 pass
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
362
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
363 def blockstream(infile, blocksize=128 * 1024):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
364 """Generator that yields blocks of data from infile and closes infile."""
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
365 while True:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
366 data = infile.read(blocksize)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
367 if not data:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
368 break
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
369 yield data
15252
6e809bb4f969 largefiles: improve comments, internal docstrings
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
370 # same blecch as copyandhash() above
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
371 infile.close()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
372
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
373 def readhash(filename):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
374 rfile = open(filename, 'rb')
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
375 hash = rfile.read(40)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
376 rfile.close()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
377 if len(hash) < 40:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
378 raise util.Abort(_('bad hash in \'%s\' (only %d bytes long)')
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
379 % (filename, len(hash)))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
380 return hash
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
381
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
382 def writehash(hash, filename, executable):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
383 util.makedirs(os.path.dirname(filename))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
384 if os.path.exists(filename):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
385 os.unlink(filename)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
386 wfile = open(filename, 'wb')
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
387
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
388 try:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
389 wfile.write(hash)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
390 wfile.write('\n')
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
391 finally:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
392 wfile.close()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
393 if os.path.exists(filename):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
394 os.chmod(filename, getmode(executable))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
395
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
396 def getexecutable(filename):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
397 mode = os.stat(filename).st_mode
15255
7ab05d752405 largefiles: cosmetics, whitespace, code style
Greg Ward <greg@gerg.ca>
parents: 15253
diff changeset
398 return ((mode & stat.S_IXUSR) and
7ab05d752405 largefiles: cosmetics, whitespace, code style
Greg Ward <greg@gerg.ca>
parents: 15253
diff changeset
399 (mode & stat.S_IXGRP) and
7ab05d752405 largefiles: cosmetics, whitespace, code style
Greg Ward <greg@gerg.ca>
parents: 15253
diff changeset
400 (mode & stat.S_IXOTH))
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
401
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
402 def getmode(executable):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
403 if executable:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
404 return 0755
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
405 else:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
406 return 0644
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
407
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
408 def urljoin(first, second, *arg):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
409 def join(left, right):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
410 if not left.endswith('/'):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
411 left += '/'
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
412 if right.startswith('/'):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
413 right = right[1:]
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
414 return left + right
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
415
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
416 url = join(first, second)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
417 for a in arg:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
418 url = join(url, a)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
419 return url
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
420
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
421 def hexsha1(data):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
422 """hexsha1 returns the hex-encoded sha1 sum of the data in the file-like
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
423 object data"""
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
424 h = hashlib.sha1()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
425 for chunk in util.filechunkiter(data):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
426 h.update(chunk)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
427 return h.hexdigest()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
428
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
429 def httpsendfile(ui, filename):
15224
7c604d8c7e83 largefiles: remove pre-1.9 code from extension first bundled with 1.9
Na'Tosha Bard <natosha@unity3d.com>
parents: 15206
diff changeset
430 return httpconnection.httpsendfile(ui, filename, 'rb')
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
431
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
432 def unixpath(path):
15252
6e809bb4f969 largefiles: improve comments, internal docstrings
Greg Ward <greg@gerg.ca>
parents: 15228
diff changeset
433 '''Return a version of path normalized for use with the lfdirstate.'''
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
434 return os.path.normpath(path).replace(os.sep, '/')
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
435
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
436 def islfilesrepo(repo):
15170
c1a4a3220711 largefiles: fix over-long lines
Matt Mackall <mpm@selenic.com>
parents: 15169
diff changeset
437 return ('largefiles' in repo.requirements and
15188
8e115063950d largefiles: don't break existing tests (syntax error, bad imports)
Greg Ward <greg@gerg.ca>
parents: 15171
diff changeset
438 any_(shortname + '/' in f[0] for f in repo.store.datafiles()))
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
439
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
440 def any_(gen):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
441 for x in gen:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
442 if x:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
443 return True
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
444 return False
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
445
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
446 class storeprotonotcapable(BaseException):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
447 def __init__(self, storetypes):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
448 self.storetypes = storetypes