##// END OF EJS Templates
inotify: server: new data structure to keep track of changes....
inotify: server: new data structure to keep track of changes. == Rationale for the new structure == Current structure was a dictionary tree. One directory was tracked as a dictionary: - keys: file/subdir name - values: - for a file, the status (a/r/m/...) - for a subdir, the directory representing the subdir It allowed efficient lookups, no matter of the type of the terminal leaf: for part in path.split('/'): tree = tree[part] However, there is no way to represent a directory and a file with the same name because keys are conflicting in the dictionary. Concrete example: Initial state: root dir |- foo (file) |- bar (file) # data state is: {'foo': 'n', 'bar': 'n'} Remove foo: root dir |- bar (file) # Data becomes {'foo': 'r'} until next commit. Add foo, as a directory, and foo/barbar file: root dir |- bar (file) |-> foo (dir) |- barbar (file) # New state should be represented as: {'foo': {'barbar': 'a'}, 'bar': 'n'} however, the key "foo" is already used and represents the old file. The dirstate: D foo A foo/barbar cannot be represented, hence the need for a new structure. == The new structure == 'directory' class. Represents one directory level. * Notable attributes: Two dictionaries: - 'files' Maps filename -> status for the current dir. - 'dirs' Maps subdir's name -> directory object representing the subdir * methods - walk(), formerly server.walk - lookup(), old server.lookup - dir(), old server.dir This new class allows embedding all the tree walks/lookups in its own class, instead of having everything mixed together in server. Incidently, since files and directories are not stored in the same dictionaries, we are solving the previous key conflict problem. The small drawback is that lookup operation is a bit more complex: for a path a/b/c/d/e we have to check twice the leaf, if e is a directory or a file.

File last commit:

r8691:a0a541d6 default
r9115:b55d4471 default
Show More
test-convert-git
173 lines | 3.6 KiB | text/plain | TextLexer
#!/bin/sh
"$TESTDIR/hghave" git || exit 80
echo "[extensions]" >> $HGRCPATH
echo "convert=" >> $HGRCPATH
echo 'hgext.graphlog =' >> $HGRCPATH
GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE
GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
count=10
commit()
{
GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000"
GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
git commit "$@" >/dev/null 2>/dev/null || echo "git commit error"
count=`expr $count + 1`
}
mkdir git-repo
cd git-repo
git init-db >/dev/null 2>/dev/null
echo a > a
mkdir d
echo b > d/b
git add a d
commit -a -m t1
# Remove the directory, then try to replace it with a file
# (issue 754)
git rm -f d/b
commit -m t2
echo d > d
git add d
commit -m t3
echo b >> a
commit -a -m t4.1
git checkout -b other HEAD^ >/dev/null 2>/dev/null
echo c > a
echo a >> a
commit -a -m t4.2
git checkout master >/dev/null 2>/dev/null
git pull --no-commit . other > /dev/null 2>/dev/null
commit -m 'Merge branch other'
cd ..
hg convert --datesort git-repo
hg up -q -R git-repo-hg
hg -R git-repo-hg tip -v
count=10
mkdir git-repo2
cd git-repo2
git init-db >/dev/null 2>/dev/null
echo foo > foo
git add foo
commit -a -m 'add foo'
echo >> foo
commit -a -m 'change foo'
git checkout -b Bar HEAD^ >/dev/null 2>/dev/null
echo quux >> quux
git add quux
commit -a -m 'add quux'
echo bar > bar
git add bar
commit -a -m 'add bar'
git checkout -b Baz HEAD^ >/dev/null 2>/dev/null
echo baz > baz
git add baz
commit -a -m 'add baz'
git checkout master >/dev/null 2>/dev/null
git pull --no-commit . Bar Baz > /dev/null 2>/dev/null
commit -m 'Octopus merge'
echo bar >> bar
commit -a -m 'change bar'
git checkout -b Foo HEAD^ >/dev/null 2>/dev/null
echo >> foo
commit -a -m 'change foo'
git checkout master >/dev/null 2>/dev/null
git pull --no-commit -s ours . Foo > /dev/null 2>/dev/null
commit -m 'Discard change to foo'
cd ..
glog()
{
hg glog --template '{rev} "{desc|firstline}" files: {files}\n' "$@"
}
splitrepo()
{
msg="$1"
files="$2"
opts=$3
echo "% $files: $msg"
prefix=`echo "$files" | sed -e 's/ /-/g'`
fmap="$prefix.fmap"
repo="$prefix.repo"
for i in $files; do
echo "include $i" >> "$fmap"
done
hg -q convert $opts --filemap "$fmap" --datesort git-repo2 "$repo"
hg up -q -R "$repo"
glog -R "$repo"
hg -R "$repo" manifest --debug
}
echo '% full conversion'
hg -q convert --datesort git-repo2 fullrepo
hg up -q -R fullrepo
glog -R fullrepo
hg -R fullrepo manifest --debug
splitrepo 'octopus merge' 'foo bar baz'
splitrepo 'only some parents of an octopus merge; "discard" a head' 'foo baz quux'
echo
echo '% test binary conversion (issue 1359)'
mkdir git-repo3
cd git-repo3
git init-db >/dev/null 2>/dev/null
python -c 'file("b", "wb").write("".join([chr(i) for i in range(256)])*16)'
git add b
commit -a -m addbinary
cd ..
echo '% convert binary file'
hg convert git-repo3 git-repo3-hg
cd git-repo3-hg
hg up -C
python -c 'print len(file("b", "rb").read())'
cd ..
echo
echo '% test author vs committer'
mkdir git-repo4
cd git-repo4
git init-db >/dev/null 2>/dev/null
echo >> foo
git add foo
commit -a -m addfoo
echo >> foo
GIT_AUTHOR_NAME="nottest"
commit -a -m addfoo2
cd ..
echo '% convert author committer'
hg convert git-repo4 git-repo4-hg
hg -R git-repo4-hg log -v
echo '% --sourceorder should fail'
hg convert --sourcesort git-repo4 git-repo4-sourcesort-hg
true