repo-mirror.sh: Fixed conversion of darcs tags.
Warning, cannot access the index:
_darcs/index: opening of '_darcs/index' failed: permission denied (Permission denied)
diff -rN -u old-bii_scripts/bin/darcs-fastimport-convert.py new-bii_scripts/bin/darcs-fastimport-convert.py
--- old-bii_scripts/bin/darcs-fastimport-convert.py 1970-01-01 01:00:00.000000000 +0100
+++ new-bii_scripts/bin/darcs-fastimport-convert.py 2022-09-28 10:41:39.927257330 +0200
@@ -0,0 +1,186 @@
+#! /usr/bin/env python3
+# -*- coding: UTF-8 -*-
+"""A script fixing darcs fastimport files.
+"""
+
+# pylint: disable=invalid-name
+
+import argparse
+#import string
+import os.path
+import sys
+
+VERSION= "1.0"
+
+SUMMARY="A program for fixing tags in fastimport files created by darcs."
+
+USAGE= "%(prog)s [options] < FASTIMPORT > FASTIMPORT.NEW"
+
+DESC= '''
+This program fixes tags in fastimport files created by darcs.
+
+It does this by inserting "reset" commands in the fastimport file. See also
+
+ https://git-scm.com/docs/git-fast-import.
+
+The program also removes '*' characters from tag names since this
+is an invalid character in git.
+'''
+
+def to_int(st):
+ """convert to int or None."""
+ try:
+ return int(st)
+ except ValueError:
+ return None
+
+def line_split(line):
+ """split line in two elements."""
+ l= line.split(b" ", maxsplit=1)
+ if len(l)<2:
+ l.append(b"")
+ return l
+
+def filter_tagname(tag):
+ """remove forbidden characters in tag."""
+ return tag.translate(None,b"?*[")
+
+class Converter:
+ """class for line-wise parsing."""
+ # pylint: disable=too-few-public-methods
+ START=0
+ COMMIT=3
+ TAG=4
+ def __init__(self, fh):
+ """read from fh line by line."""
+ self.state= Converter.START
+ self.fh= fh
+ self.tagname=b""
+ self.datalen=0
+ self.dataline= b""
+ self.from_=b""
+ self.mark=b""
+ def iter(self):
+ """return next line."""
+ # pylint: disable=too-many-branches
+ # pylint: disable=too-many-statements
+ for line in self.fh.readlines():
+ #print(f"{line=}") #@@@
+ (tag, val)= line_split(line)
+ #print(f"{tag=} {val=}") #@@@
+ #sys.exit(1) #@@@
+ if self.datalen>0: # in data statement
+ self.datalen -= len(line)
+ if not self.dataline:
+ self.dataline= line.rstrip()
+ self.datalen= max(self.datalen, 0)
+ yield line
+ continue
+ if tag==b"data":
+ i= to_int(val)
+ if i is not None:
+ # data line
+ self.datalen= i
+ self.dataline= b""
+ yield line
+ continue
+ if tag==b"progress":
+ if self.state==Converter.TAG:
+ # a "tag" statement has ended
+ yield b"progress TAG %s\n" % self.tagname
+ yield b"reset refs/tags/%s\n" % self.tagname
+ yield b"from %s\n" % self.from_
+ self.state=Converter.START
+ elif self.state==Converter.COMMIT:
+ if self.dataline.startswith(b"TAG"):
+ self.tagname= \
+ filter_tagname(line_split(self.dataline)[1])
+ yield b"progress TAG %s\n" % self.tagname
+ yield b"reset refs/tags/%s\n" % self.tagname
+ yield b"from %s\n" % self.mark
+ self.state=Converter.START
+ self.dataline= b""
+ yield line
+ continue
+
+ if tag==b"from":
+ self.from_= val
+ # a "commit" statement ends here
+ yield line
+ continue
+ if tag==b"mark":
+ self.mark= val
+ yield line
+ continue
+ if tag==b"commit":
+ self.state=Converter.COMMIT
+ yield line
+ continue
+ if tag==b"tag":
+ self.state=Converter.TAG
+ self.tagname= filter_tagname(val.strip())
+ yield filter_tagname(line)
+ continue
+ yield line
+
+
+def process(args, rest):
+ """do all the work.
+ """
+ # pylint: disable= unused-argument
+ if args.summary:
+ print_summary()
+ sys.exit(0)
+ input_stream = sys.stdin.buffer
+
+ c= Converter(input_stream)
+ for l in c.iter():
+ sys.stdout.buffer.write(l)
+
+def script_shortname():
+ """return the name of this script without a path component."""
+ return os.path.basename(sys.argv[0])
+
+def print_summary():
+ """print a short summary of the scripts function."""
+ print("%-20s: %s\n" % (script_shortname(), SUMMARY))
+
+
+def main():
+ """The main function.
+
+ parse the command-line options and perform the command
+ """
+ parser = argparse.ArgumentParser(\
+ usage= USAGE,
+ description= DESC,
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ )
+ parser.add_argument('--version', action='version', version='%%(prog)s %s' % VERSION)
+
+ parser.add_argument("--summary",
+ action="store_true",
+ help="print a summary of the function of the program",
+ )
+
+ (args, remains) = parser.parse_known_args()
+ rest= []
+ check= True
+ for r in remains:
+ if (not check) or (not r.startswith("-")) or (r=="-"):
+ rest.append(r)
+ continue
+ if r=="--": # do not check further
+ check= False
+ continue
+ sys.exit("unknown option: %s" % repr(r))
+
+ if args.summary:
+ print_summary()
+ sys.exit(0)
+
+ process(args, rest)
+ sys.exit(0)
+
+if __name__ == "__main__":
+ main()
diff -rN -u old-bii_scripts/bin/repo-mirror.sh new-bii_scripts/bin/repo-mirror.sh
--- old-bii_scripts/bin/repo-mirror.sh 2022-09-28 10:41:39.927257330 +0200
+++ new-bii_scripts/bin/repo-mirror.sh 2022-09-28 10:41:39.927257330 +0200
@@ -24,6 +24,8 @@
MYDIR=$(dirname $SCRIPT_FULL_NAME)
MYNAME=$(basename $SCRIPT_FULL_NAME)
+DARCS_HELPER="$MYDIR/darcs-fastimport-convert.py"
+
# let python (mercurial) not fail on encoding errors:
export HGENCODINGMODE="replace"
@@ -307,7 +309,7 @@
if [ "$SRCREPOTYPE" == "darcs" ]; then
#CMD "touch $DST/darcs2git.marks"
#CMD "darcs convert export --read-marks darcs2git.marks --write-marks darcs2git.marks | (cd \"$DST\" && git fast-import --import-marks=darcs2git.marks --export-marks=darcs2git.marks)"
- CMD "darcs convert export | (cd \"$DST\" && git fast-import)"
+ CMD "darcs convert export | $DARCS_HELPER | (cd \"$DST\" && git fast-import)"
elif [ "$SRCREPOTYPE" == "mercurial" ]; then
python_check_module "hggit" "hg-git"
hg_check_command "hggit" "hggit"
@@ -328,8 +330,13 @@
hg_check_command "fastimport" "fastimport"
# note: python fastimport doesn't work when
# the export command uses --import-marks and --export-marks:
- CMD "darcs convert export > \"$DST/FASTIMPORT\""
- CMD "(cd \"$DST\" && hg fastimport --traceback --sourcesort FASTIMPORT && rm -d FASTIMPORT)"
+ CMD "darcs convert export | $DARCS_HELPER > \"$DST/FASTIMPORT\""
+ # Note: Currently mercurial fastimport has a problem here:
+ # If the mercurial repo already exists and the darcs
+ # repo has just one new tag, nothing else, that tag
+ # is not imported. New Tags are only imported when they are
+ # accompanied by other new regular patches.
+ CMD "(cd \"$DST\" && hg fastimport --traceback FASTIMPORT && rm -f FASTIMPORT)"
elif [ "$SRCREPOTYPE" == "git" ]; then
python_check_module "hggit" "hg-git"
hg_check_command "hggit" "hggit"
patch 0d1d1e4f4baadaaa1b9dfcb7598e2d8a76ae51cc
Author: Goetz Pfeiffer <goetzpf@googlemail.com>
Date: Tue Feb 15 10:25:07 CET 2022
* repo-mirror.sh: Fixed conversion of darcs tags.
To fix this, the script now calls the helper script
darcs-fastimport-convert.py