convert: add a mode where mercurial_sink skips empty revisions.
The getchanges function of some converter_source classes can return
some false positives. I.e. they sometimes claim that a file "foo"
was changed in some revision, even though its contents are still the
same.
convert_svn is particularly bad, but I think this can also happen with
convert_cvs and, at least in theory, with mercurial_source.
For regular conversions this is not really a problem - as long as
getfile returns the right contents, we'll get a converted revision
with the right contents. But when we use --filemap, this could lead
to superfluous revisions being converted.
Instead of fixing every converter_source, I decided to change
mercurial_sink to work around this problem.
When --filemap is used, we're interested only in revisions that touch
some specific files. If a revision doesn't change any of these files,
then we're not interested in it (at least for revisions with a single
parent; merges are special).
For mercurial_sink, we abuse this property and rollback a commit if
the manifest text hasn't changed. This avoids duplicating the logic
from localrepo.filecommit to detect unchanged files.
# simple script to be used in hooks
# copy it to the current directory when the test starts:
#
# cp "$TESTDIR"/printenv.py .
#
# put something like this in the repo .hg/hgrc:
#
# [hooks]
# changegroup = python ../printenv.py <hookname> [exit] [output]
#
# - <hookname> is a mandatory argument (e.g. "changegroup")
# - [exit] is the exit code of the hook (default: 0)
# - [output] is the name of the output file (default: use sys.stdout)
# the file will be opened in append mode.
#
import os
import sys
exitcode = 0
out = sys.stdout
name = sys.argv[1]
if len(sys.argv) > 2:
exitcode = int(sys.argv[2])
if len(sys.argv) > 3:
out = open(sys.argv[3], "ab")
# variables with empty values may not exist on all platforms, filter
# them now for portability sake.
env = [k for k, v in os.environ.iteritems()
if k.startswith("HG_") and v]
env.sort()
# edit the variable part of the variable
url = os.environ.get("HG_URL", "")
if url.startswith("file:"):
os.environ["HG_URL"] = "file:"
elif url.startswith("remote:http"):
os.environ["HG_URL"] = "remote:http"
out.write("%s hook: " % name)
for v in env:
out.write("%s=%s " % (v, os.environ[v]))
out.write("\n")
out.close()
sys.exit(exitcode)