test-hardlinks: add testcase for repo copied with 'cp -al'
This patch adds a case to test-hardlinks.t which demonstrates that
hardlinks in the working directory are broken up (using 'hg update').
Motivation for this patch:
'hg help clone' shows copying repositories *and* the working directory
using 'cp -al', creating hardlinks in the *working directory* too (not
just in the store).
Note that we can't use 'cp -al' since for example MacOS X doesn't
support these options on cp. I'm thus using the same trick as in
test-hardlinks-safety.t for creating hardlinks in the working dir.
$ cat > nlinks.py <<EOF
> import os, sys
> for f in sorted(sys.stdin.readlines()):
> f = f[:-1]
> print os.lstat(f).st_nlink, f
> EOF
$ nlinksdir()
> {
> find $1 -type f | python $TESTTMP/nlinks.py
> }
Some implementations of cp can't create hardlinks (replaces 'cp -al' on Linux):
$ cat > linkcp.py <<EOF
> from mercurial import util
> import sys
> util.copyfiles(sys.argv[1], sys.argv[2], hardlink=True)
> EOF
$ linkcp()
> {
> python $TESTTMP/linkcp.py $1 $2
> }
Prepare repo r1:
$ mkdir r1
$ cd r1
$ hg init
$ echo c1 > f1
$ hg add f1
$ hg ci -m0
$ mkdir d1
$ cd d1
$ echo c2 > f2
$ hg add f2
$ hg ci -m1
$ cd ../..
$ nlinksdir r1/.hg/store
1 r1/.hg/store/00changelog.i
1 r1/.hg/store/00manifest.i
1 r1/.hg/store/data/d1/f2.i
1 r1/.hg/store/data/f1.i
1 r1/.hg/store/fncache
1 r1/.hg/store/undo
Create hardlinked clone r2:
$ hg clone -U --debug r1 r2
linked 7 files
Create non-hardlinked clone r3:
$ hg clone --pull r1 r3
requesting all changes
adding changesets
adding manifests
adding file changes
added 2 changesets with 2 changes to 2 files
updating to branch default
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
Repos r1 and r2 should now contain hardlinked files:
$ nlinksdir r1/.hg/store
2 r1/.hg/store/00changelog.i
2 r1/.hg/store/00manifest.i
2 r1/.hg/store/data/d1/f2.i
2 r1/.hg/store/data/f1.i
2 r1/.hg/store/fncache
1 r1/.hg/store/undo
$ nlinksdir r2/.hg/store
2 r2/.hg/store/00changelog.i
2 r2/.hg/store/00manifest.i
2 r2/.hg/store/data/d1/f2.i
2 r2/.hg/store/data/f1.i
2 r2/.hg/store/fncache
Repo r3 should not be hardlinked:
$ nlinksdir r3/.hg/store
1 r3/.hg/store/00changelog.i
1 r3/.hg/store/00manifest.i
1 r3/.hg/store/data/d1/f2.i
1 r3/.hg/store/data/f1.i
1 r3/.hg/store/fncache
1 r3/.hg/store/undo
Create a non-inlined filelog in r3:
$ cd r3/d1
$ python -c 'for x in range(10000): print x' >> data1
$ for j in 0 1 2 3 4 5 6 7 8 9; do
> cat data1 >> f2
> hg commit -m$j
> done
$ cd ../..
$ nlinksdir r3/.hg/store
1 r3/.hg/store/00changelog.i
1 r3/.hg/store/00manifest.i
1 r3/.hg/store/data/d1/f2.d
1 r3/.hg/store/data/d1/f2.i
1 r3/.hg/store/data/f1.i
1 r3/.hg/store/fncache
1 r3/.hg/store/undo
Push to repo r1 should break up most hardlinks in r2:
$ hg -R r2 verify
checking changesets
checking manifests
crosschecking files in changesets and manifests
checking files
2 files, 2 changesets, 2 total revisions
$ cd r3
$ hg push
pushing to $TESTTMP/r1
searching for changes
adding changesets
adding manifests
adding file changes
added 10 changesets with 10 changes to 1 files
$ cd ..
$ nlinksdir r2/.hg/store
1 r2/.hg/store/00changelog.i
1 r2/.hg/store/00manifest.i
1 r2/.hg/store/data/d1/f2.i
2 r2/.hg/store/data/f1.i
1 r2/.hg/store/fncache
$ hg -R r2 verify
checking changesets
checking manifests
crosschecking files in changesets and manifests
checking files
2 files, 2 changesets, 2 total revisions
$ cd r1
$ hg up
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
Committing a change to f1 in r1 must break up hardlink f1.i in r2:
$ echo c1c1 >> f1
$ hg ci -m00
$ cd ..
$ nlinksdir r2/.hg/store
1 r2/.hg/store/00changelog.i
1 r2/.hg/store/00manifest.i
1 r2/.hg/store/data/d1/f2.i
1 r2/.hg/store/data/f1.i
1 r2/.hg/store/fncache
$ cd r3
$ hg tip --template '{rev}:{node|short}\n'
11:a6451b6bc41f
$ echo bla > f1
$ hg ci -m1
$ cd ..
Create hardlinked copy r4 of r3 (on Linux, we would call 'cp -al'):
$ linkcp r3 r4
r4 has hardlinks in the working dir (not just inside .hg):
$ nlinksdir r4
2 r4/.hg/00changelog.i
2 r4/.hg/branch
2 r4/.hg/branchheads.cache
2 r4/.hg/dirstate
2 r4/.hg/hgrc
2 r4/.hg/last-message.txt
2 r4/.hg/requires
2 r4/.hg/store/00changelog.i
2 r4/.hg/store/00manifest.i
2 r4/.hg/store/data/d1/f2.d
2 r4/.hg/store/data/d1/f2.i
2 r4/.hg/store/data/f1.i
2 r4/.hg/store/fncache
2 r4/.hg/store/undo
2 r4/.hg/tags.cache
2 r4/.hg/undo.branch
2 r4/.hg/undo.desc
2 r4/.hg/undo.dirstate
2 r4/d1/data1
2 r4/d1/f2
2 r4/f1
Update back to revision 11 in r4 should break hardlink of file f1:
$ hg -R r4 up 11
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ nlinksdir r4
2 r4/.hg/00changelog.i
1 r4/.hg/branch
2 r4/.hg/branchheads.cache
1 r4/.hg/dirstate
2 r4/.hg/hgrc
2 r4/.hg/last-message.txt
2 r4/.hg/requires
2 r4/.hg/store/00changelog.i
2 r4/.hg/store/00manifest.i
2 r4/.hg/store/data/d1/f2.d
2 r4/.hg/store/data/d1/f2.i
2 r4/.hg/store/data/f1.i
2 r4/.hg/store/fncache
2 r4/.hg/store/undo
2 r4/.hg/tags.cache
2 r4/.hg/undo.branch
2 r4/.hg/undo.desc
2 r4/.hg/undo.dirstate
2 r4/d1/data1
2 r4/d1/f2
1 r4/f1