convert: fix mercurial_sink.putcommit
Changeset
4ebc8693ce72 added some code to putcommit to avoid creating a
revision that touches no files, but this can break regular conversions
from some repositories:
- conceptually, since we're converting a repo, we should try to make
the new hg repo as similar as possible to the original repo - we
should create a new changeset, even if the original revision didn't
touch any files (maybe the commit message had some important bit);
- even if a "regular" revision that doesn't touch any file may seem
weird (and maybe even broken), it's completely legitimate for a merge
revision to not touch any file, and, if we just skip it, the
converted repo will end up with wrong history and possibly an extra
head.
As an example, say the crew and main hg repos are sync'ed. Somebody
sends an important patch to the mailing list. Matt quickly applies
and pushes it. But at the same time somebody also applies it to crew
and pushes it. Suppose the commit message ended up being a bit
different (say, there was a typo and somebody didn't fix it) or that
the date ended up being different (because of different patch-applying
scripts): the changeset hashes will be different, but the manifests
will be the same.
Since both changesets were pushed to public repos, it's hard to recall
them. If both are merged, the manifest from the resulting merge
revision will have the exact same contents as its parents - i.e. the
merge revision really doesn't touch any file at all.
To keep the file filtering stuff "working", the generic code was changed
to skip empty revisions if we're filtering the repo, fixing a bug in the
process (we want parents[0] instead of tip).
#!/bin/sh
hg init a
cd a
echo start > start
hg ci -Amstart -d '0 0'
echo new > new
hg ci -Amnew -d '0 0'
echo '% new file'
hg diff --git -r 0
hg cp new copy
hg ci -mcopy -d '0 0'
echo '% copy'
hg diff --git -r 1:tip
hg mv copy rename
hg ci -mrename -d '0 0'
echo '% rename'
hg diff --git -r 2:tip
hg rm rename
hg ci -mdelete -d '0 0'
echo '% delete'
hg diff --git -r 3:tip
cat > src <<EOF
1
2
3
4
5
EOF
hg ci -Amsrc -d '0 0'
chmod +x src
hg ci -munexec -d '0 0'
echo '% chmod 644'
hg diff --git -r 5:tip
hg mv src dst
chmod -x dst
echo a >> dst
hg ci -mrenamemod -d '0 0'
echo '% rename+mod+chmod'
hg diff --git -r 6:tip
echo '% nonexistent in tip+chmod'
hg diff --git -r 5:6
echo '% binary diff'
cp $TESTDIR/binfile.bin .
hg add binfile.bin
hg diff --git > b.diff
cat b.diff
echo '% import binary diff'
hg revert binfile.bin
rm binfile.bin
hg import -mfoo b.diff
cmp binfile.bin $TESTDIR/binfile.bin
echo
echo '% rename binary file'
hg mv binfile.bin renamed.bin
hg diff --git
echo
echo '% diff across many revisions'
hg mv dst dst2
hg ci -m 'mv dst dst2' -d '0 0'
echo >> start
hg ci -m 'change start' -d '0 0'
hg revert -r -2 start
hg mv dst2 dst3
hg ci -m 'mv dst2 dst3; revert start' -d '0 0'
hg diff --git -r 9:11
echo a >> foo
hg add foo
hg ci -m 'add foo'
echo b >> foo
hg ci -m 'change foo'
hg mv foo bar
hg ci -m 'mv foo bar'
echo c >> bar
hg ci -m 'change bar'
echo
echo '% file created before r1 and renamed before r2'
hg diff --git -r -3:-1
echo
echo '% file created in r1 and renamed before r2'
hg diff --git -r -4:-1
echo
echo '% file created after r1 and renamed before r2'
hg diff --git -r -5:-1
echo
echo '% comparing with the working dir'
echo >> start
hg ci -m 'change start again' -d '0 0'
echo > created
hg add created
hg ci -m 'add created'
hg mv created created2
hg ci -m 'mv created created2'
hg mv created2 created3
echo "% there's a copy in the working dir..."
hg diff --git
echo
echo "% ...but there's another copy between the original rev and the wd"
hg diff --git -r -2
echo
echo "% ...but the source of the copy was created after the original rev"
hg diff --git -r -3
hg ci -m 'mv created2 created3'
echo > brand-new
hg add brand-new
hg ci -m 'add brand-new'
hg mv brand-new brand-new2
echo '% created in parent of wd; renamed in the wd'
hg diff --git
echo
echo '% created between r1 and parent of wd; renamed in the wd'
hg diff --git -r -2
hg ci -m 'mv brand-new brand-new2'
echo '% one file is copied to many destinations and removed'
hg cp brand-new2 brand-new3
hg mv brand-new2 brand-new3-2
hg ci -m 'multiple renames/copies'
hg diff --git -r -2 -r -1
echo '% there should be a trailing TAB if there are spaces in the file name'
echo foo > 'with spaces'
hg add 'with spaces'
hg diff --git
hg ci -m 'add filename with spaces'