Mercurial > hg
comparison hgext/largefiles/lfutil.py @ 15794:0d91211dd12f
largefiles: fix inappropriate locking (issue3182)
Don't lock/write on operations that should be readonly (status).
Always lock when writing the lfdirstate (rollback).
Don't write lfdirstate until after committing; state isn't actually changed
until the commit is complete.
author | Levi Bard <levi@unity3d.com> |
---|---|
date | Sat, 07 Jan 2012 19:05:59 +0100 |
parents | 3ef07ecdb0d5 |
children | 3e5b6045ccfc |
comparison
equal
deleted
inserted
replaced
15793:3ef07ecdb0d5 | 15794:0d91211dd12f |
---|---|
152 lfdirstate = largefiles_dirstate(opener, ui, repo.root, | 152 lfdirstate = largefiles_dirstate(opener, ui, repo.root, |
153 repo.dirstate._validate) | 153 repo.dirstate._validate) |
154 | 154 |
155 # If the largefiles dirstate does not exist, populate and create | 155 # If the largefiles dirstate does not exist, populate and create |
156 # it. This ensures that we create it on the first meaningful | 156 # it. This ensures that we create it on the first meaningful |
157 # largefiles operation in a new clone. It also gives us an easy | 157 # largefiles operation in a new clone. |
158 # way to forcibly rebuild largefiles state: | |
159 # rm .hg/largefiles/dirstate && hg status | |
160 # Or even, if things are really messed up: | |
161 # rm -rf .hg/largefiles && hg status | |
162 if not os.path.exists(os.path.join(admin, 'dirstate')): | 158 if not os.path.exists(os.path.join(admin, 'dirstate')): |
163 util.makedirs(admin) | 159 util.makedirs(admin) |
164 matcher = getstandinmatcher(repo) | 160 matcher = getstandinmatcher(repo) |
165 for standin in dirstate_walk(repo.dirstate, matcher): | 161 for standin in dirstate_walk(repo.dirstate, matcher): |
166 lfile = splitstandin(standin) | 162 lfile = splitstandin(standin) |
170 if hash == hashfile(repo.wjoin(lfile)): | 166 if hash == hashfile(repo.wjoin(lfile)): |
171 lfdirstate.normal(lfile) | 167 lfdirstate.normal(lfile) |
172 except OSError, err: | 168 except OSError, err: |
173 if err.errno != errno.ENOENT: | 169 if err.errno != errno.ENOENT: |
174 raise | 170 raise |
175 | |
176 lfdirstate.write() | |
177 | |
178 return lfdirstate | 171 return lfdirstate |
179 | 172 |
180 def lfdirstate_status(lfdirstate, repo, rev): | 173 def lfdirstate_status(lfdirstate, repo, rev): |
181 wlock = repo.wlock() | 174 match = match_.always(repo.root, repo.getcwd()) |
182 try: | 175 s = lfdirstate.status(match, [], False, False, False) |
183 match = match_.always(repo.root, repo.getcwd()) | 176 unsure, modified, added, removed, missing, unknown, ignored, clean = s |
184 s = lfdirstate.status(match, [], False, False, False) | 177 for lfile in unsure: |
185 unsure, modified, added, removed, missing, unknown, ignored, clean = s | 178 if repo[rev][standin(lfile)].data().strip() != \ |
186 for lfile in unsure: | 179 hashfile(repo.wjoin(lfile)): |
187 if repo[rev][standin(lfile)].data().strip() != \ | 180 modified.append(lfile) |
188 hashfile(repo.wjoin(lfile)): | 181 else: |
189 modified.append(lfile) | 182 clean.append(lfile) |
190 else: | 183 lfdirstate.normal(lfile) |
191 clean.append(lfile) | |
192 lfdirstate.normal(lfile) | |
193 lfdirstate.write() | |
194 finally: | |
195 wlock.release() | |
196 return (modified, added, removed, missing, unknown, ignored, clean) | 184 return (modified, added, removed, missing, unknown, ignored, clean) |
197 | 185 |
198 def listlfiles(repo, rev=None, matcher=None): | 186 def listlfiles(repo, rev=None, matcher=None): |
199 '''return a list of largefiles in the working copy or the | 187 '''return a list of largefiles in the working copy or the |
200 specified changeset''' | 188 specified changeset''' |