Mercurial > hg
changeset 15572:926bc23d0b6a stable
largefiles: copy files into .hg/largefiles atomically
Copying from the user cache into .hg/largefiles could fail halfway
though with a partially written file.
author | Martin Geisler <mg@aragost.com> |
---|---|
date | Thu, 24 Nov 2011 18:13:18 +0100 |
parents | 809788118aa2 |
children | a5e5c64cd90b 4a4a95029b31 |
files | hgext/largefiles/lfutil.py tests/test-largefiles-small-disk.t |
diffstat | 2 files changed, 34 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/hgext/largefiles/lfutil.py Thu Nov 24 18:12:13 2011 +0100 +++ b/hgext/largefiles/lfutil.py Thu Nov 24 18:13:18 2011 +0100 @@ -77,8 +77,11 @@ try: util.oslink(src, dest) except OSError: - # if hardlinks fail, fallback on copy - shutil.copyfile(src, dest) + # if hardlinks fail, fallback on atomic copy + dst = util.atomictempfile(dest) + for chunk in util.filechunkiter(open(src)): + dst.write(chunk) + dst.close() os.chmod(dest, os.stat(src).st_mode) def usercachepath(ui, hash):
--- a/tests/test-largefiles-small-disk.t Thu Nov 24 18:12:13 2011 +0100 +++ b/tests/test-largefiles-small-disk.t Thu Nov 24 18:13:18 2011 +0100 @@ -15,6 +15,10 @@ > yield f.read(4) > raise IOError(errno.ENOSPC, os.strerror(errno.ENOSPC)) > util.filechunkiter = filechunkiter + > # + > def oslink(src, dest): + > raise OSError("no hardlinks, try copying instead") + > util.oslink = oslink > EOF $ echo "[extensions]" >> $HGRCPATH @@ -37,3 +41,28 @@ >>> import os; os.path.exists("$HOME/.cache/largefiles/") False + +Make the commit with space on the device: + + $ hg commit -m big + +Now make a clone with a full disk, and make sure lfutil.link function +makes copies instead of hardlinks: + + $ cd .. + $ hg --config extensions.criple=$TESTTMP/criple.py clone --pull alice bob + requesting all changes + adding changesets + adding manifests + adding file changes + added 1 changesets with 1 changes to 1 files + updating to branch default + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + getting changed largefiles + abort: No space left on device + [255] + +The largefile is not created in .hg/largefiles: + + $ ls bob/.hg/largefiles + dirstate