parent
f35cf16987
commit
1d719db65c
4
Makefile
4
Makefile
|
@ -595,6 +595,7 @@ SUBDIR+= cvc3
|
|||
SUBDIR+= cvs-syncmail
|
||||
SUBDIR+= cvs2darcs
|
||||
SUBDIR+= cvs2fossil
|
||||
SUBDIR+= cvs2git
|
||||
SUBDIR+= cvs2hg
|
||||
SUBDIR+= cvsanaly
|
||||
SUBDIR+= cvsnt
|
||||
|
@ -2008,7 +2009,8 @@ SUBDIR+= libraw1394
|
|||
SUBDIR+= libre
|
||||
SUBDIR+= librem
|
||||
SUBDIR+= libreoffice-git
|
||||
SUBDIR+= libreswan
|
||||
SUBDIR+= libreswan-4
|
||||
SUBDIR+= libreswan-5
|
||||
SUBDIR+= libreswan-git
|
||||
SUBDIR+= libretro-4do
|
||||
SUBDIR+= libretro-beetle-lynx
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Convert a CVS repository to git via fossil.
|
|
@ -0,0 +1,36 @@
|
|||
# $NetBSD$
|
||||
|
||||
PKGNAME= cvs2git-3.0
|
||||
CATEGORIES= devel scm
|
||||
|
||||
MAINTAINER= wiz@NetBSD.org
|
||||
#HOMEPAGE= https://www.pkgsrc.org/
|
||||
COMMENT= Convert CVS repository to git
|
||||
LICENSE= 2-clause-bsd
|
||||
|
||||
DEPENDS+= cvs2fossil-[0-9]*:../../wip/cvs2fossil
|
||||
DEPENDS+= git-base-[0-9]*:../../devel/git-base
|
||||
DEPENDS+= git-filter-repo-[0-9]*:../../devel/git-filter-repo
|
||||
|
||||
WRKSRC= ${WRKDIR}
|
||||
USE_LANGUAGES= # empty
|
||||
INSTALLATION_DIRS= bin ${PKGMANDIR}/man1
|
||||
|
||||
PYTHON_VERSIONS_INCOMPATIBLE= 27
|
||||
REPLACE_PYTHON+= cvs2git
|
||||
|
||||
post-extract:
|
||||
${CP} ${FILESDIR}/cvs2git ${WRKSRC}
|
||||
${CP} ${FILESDIR}/cvs2git.1 ${WRKSRC}
|
||||
|
||||
do-configure:
|
||||
|
||||
do-build:
|
||||
|
||||
do-install:
|
||||
${INSTALL_SCRIPT} ${WRKDIR}/cvs2git ${DESTDIR}${PREFIX}/bin
|
||||
${INSTALL_MAN} ${FILESDIR}/cvs2git.1 ${DESTDIR}${PREFIX}/${PKGMANDIR}/man1
|
||||
|
||||
.include "../../lang/python/application.mk"
|
||||
.include "../../lang/python/pyversion.mk"
|
||||
.include "../../mk/bsd.pkg.mk"
|
|
@ -0,0 +1,3 @@
|
|||
@comment $NetBSD$
|
||||
bin/cvs2git
|
||||
man/man1/cvs2git.1
|
|
@ -0,0 +1,114 @@
|
|||
#!/usr/bin/env python3
|
||||
#
|
||||
# $NetBSD$
|
||||
#
|
||||
# Copyright (c) 2024 The NetBSD Foundation, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This code is derived from software contributed to The NetBSD Foundation
|
||||
# by Thomas Klausner.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
import argparse
|
||||
import os
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
|
||||
|
||||
def file_path(path):
|
||||
'''Check if argument is a valid file path.'''
|
||||
if Path(path).is_file():
|
||||
return str(Path(path).resolve())
|
||||
raise argparse.ArgumentTypeError(f"{path} is not a valid file path")
|
||||
|
||||
|
||||
def dir_path(path):
|
||||
'''Check if argument is a valid directory path.'''
|
||||
if Path(path).is_dir():
|
||||
return str(Path(path).resolve())
|
||||
raise argparse.ArgumentTypeError(f"{path} is not a valid directory path")
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser(description='Convert CVS repository to git')
|
||||
parser.add_argument('-m', dest='mailmap', type=file_path,
|
||||
help='use %(dest)s to map UNIX logins to names ' +
|
||||
'and email addresses')
|
||||
parser.add_argument('-f', dest='fixup_sql_script', type=file_path,
|
||||
help='run %(dest)s on fossil database to fix problems')
|
||||
parser.add_argument('-s', dest='merge_limit', type=int,
|
||||
help='pass %(dest)s to cvs2fossil ' +
|
||||
'(merge window time in seconds)')
|
||||
parser.add_argument('source', type=dir_path,
|
||||
help='source CVS repository master')
|
||||
# may not exist yet, can't use dir_path
|
||||
parser.add_argument('destination', type=str,
|
||||
help='base name of target git repository')
|
||||
args = parser.parse_args()
|
||||
|
||||
run_args = ['cvs2fossil', '-m']
|
||||
if args.fixup_sql_script:
|
||||
run_args += ['-f', args.fixup_sql_script]
|
||||
if args.merge_limit:
|
||||
run_args += ['-s', str(args.merge_limit)]
|
||||
run_args += [args.source, args.destination]
|
||||
|
||||
# convert to fossil using cvs2fossil
|
||||
subprocess.run(run_args, check=True)
|
||||
# cvs2fossil creates {args.destination} and {args.destination}.fossil,
|
||||
# but we don't need the former
|
||||
os.remove(args.destination)
|
||||
# export from fossil
|
||||
with open(f'{args.destination}.fossil.export', 'wb') as output:
|
||||
subprocess.run(['fossil1', 'export', '-R', f'{args.destination}.fossil'],
|
||||
stdout=output, check=True)
|
||||
# import to git
|
||||
subprocess.run(['git', 'init', f'{args.destination}.git'], check=True)
|
||||
with open(f'{args.destination}.fossil.export', 'rb') as input:
|
||||
subprocess.run(['git', 'fast-import'], check=True,
|
||||
cwd=f'{args.destination}.git', stdin=input)
|
||||
# HEAD is broken, fix it
|
||||
with open(f'{args.destination}.git/.git/HEAD', 'w', encoding='ASCII') as conf:
|
||||
conf.write('ref: refs/heads/trunk\n')
|
||||
# rename 'trunk' to 'main'
|
||||
subprocess.run(['git', 'branch', 'main', 'trunk'], check=True,
|
||||
cwd=f'{args.destination}.git')
|
||||
subprocess.run(['git', 'switch', 'main'], check=True,
|
||||
cwd=f'{args.destination}.git')
|
||||
subprocess.run(['git', 'branch', '-d', 'trunk'], check=True,
|
||||
cwd=f'{args.destination}.git')
|
||||
|
||||
# fix author names
|
||||
if args.mailmap:
|
||||
run_args = ['git', 'clone', f'{args.destination}.git',
|
||||
f'{args.destination}.rewrite.git']
|
||||
subprocess.run(run_args, check=True)
|
||||
run_args = ['git', 'filter-repo', '--force']
|
||||
# and apply author fixes
|
||||
if args.mailmap:
|
||||
run_args.append('--mailmap')
|
||||
run_args.append(f'{args.mailmap}')
|
||||
subprocess.run(run_args, check=True,
|
||||
cwd=f'{args.destination}.rewrite.git')
|
||||
os.rename(f'{args.destination}.git', f'{args.destination}.git.old')
|
||||
os.rename(f'{args.destination}.rewrite.git', f'{args.destination}.git')
|
|
@ -0,0 +1,117 @@
|
|||
.\" $NetBSD$
|
||||
.\"
|
||||
.\" Copyright (c) 2024 The NetBSD Foundation, Inc.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" This code is derived from software contributed to The NetBSD Foundation
|
||||
.\" by Thomas Klausner.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
.\" POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd April 21, 2024
|
||||
.Dt CVS2GIT 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm cvs2git
|
||||
.Nd convert CVS repository to git
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl f Ar fixup-sql-script
|
||||
.Op Fl m Ar mailmap
|
||||
.Op Fl s Ar merge-limit-seconds
|
||||
.Ar source
|
||||
.Ar destination
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
is a script to convert a
|
||||
.Xr cvs 1
|
||||
repository to
|
||||
.Xr git 1
|
||||
using
|
||||
.Xr cvs2fossil 1
|
||||
and
|
||||
.Xr git 1 .
|
||||
.Pp
|
||||
.Ar source
|
||||
must be a CVS repository (the server side, i.e. the RCS files, not a
|
||||
checkout).
|
||||
.Nm
|
||||
will create
|
||||
.Ar destination Ns Pa .fossil
|
||||
(the fossil conversion created by
|
||||
.Xr cvs2fossil 1 ) .
|
||||
.Xr fossil 1
|
||||
will create a
|
||||
.Xr git 1
|
||||
fast-import file
|
||||
.Ar destination Ns Pa .fossil.export
|
||||
which will be converted into the git repository
|
||||
.Ar destination Ns Pa .git
|
||||
by
|
||||
.Xr git 1.
|
||||
.Xr git 1
|
||||
will also be used to update the author information using a mailmap
|
||||
file, if provided.
|
||||
.Pp
|
||||
.Nm
|
||||
supports the following flags:
|
||||
.Bl -tag -width 10n
|
||||
.It Fl m Ar mailmap
|
||||
Pass a
|
||||
.Xr git 1
|
||||
mailmap file for creating proper author information using
|
||||
.Xr git-filter-repo 1 .
|
||||
The mailmap format is described in
|
||||
.Xr gitmailmap 5 .
|
||||
.It Fl f Ar fixup-sql-script
|
||||
Pass an SQL fixup script for
|
||||
.Xr cvs2fossil 1
|
||||
for its
|
||||
.Fl f
|
||||
flag.
|
||||
.It Fl s Ar merge-limit-seconds
|
||||
Pass a merge time limit in seconds to
|
||||
.Xr cvs2fossil 1 .
|
||||
.El
|
||||
.Sh EXAMPLES
|
||||
To convert the
|
||||
.Nx
|
||||
src repository, if you have developer access, do:
|
||||
.Bd -literal -offset indent
|
||||
export REPO=src
|
||||
export LOGIN=username
|
||||
rsync -aS --delete -e ssh "$LOGIN"@cvs.NetBSD.org::cvsroot/"$REPO" "$REPO"-rsync
|
||||
cvs2git -m mailmap -s 300 "$REPO"-rsync/"$REPO" "$REPO"
|
||||
.Ed
|
||||
.Pp
|
||||
The conversion output is in
|
||||
.Pa src.git .
|
||||
The intermediate fossil directory is
|
||||
.Pa src.fossil
|
||||
and the corresponsing fast-import file
|
||||
.Pa src.fossil.export .
|
||||
If you use
|
||||
.Fl a
|
||||
there will be another
|
||||
.Pa src.git.old
|
||||
directory, respectively.
|
||||
You can delete them after the conversion.
|
|
@ -1 +1 @@
|
|||
Convert a CVS repository to Mercurial (hg) via fossil and git.
|
||||
Convert a CVS repository to Mercurial (hg) via fossil.
|
||||
|
|
Loading…
Reference in New Issue