Prepare git-tools for merging into the main git archive
Rename into a "tools" subdirectory, and change name of "dotest" to "applymbox". Remove stripspace (which was already copied into git) and cvs2git (which was likewise already copied into git, and then replaced by a much better perl version). All of this was brought on by Ryan Anderson shaming me into it. Thanks. I guess.
This commit is contained in:
parent
fc7ef1e8ae
commit
c5f7674a97
307
cvs2git.c
307
cvs2git.c
@ -1,307 +0,0 @@
|
|||||||
/*
|
|
||||||
* cvs2git
|
|
||||||
*
|
|
||||||
* Copyright (C) Linus Torvalds 2005
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
static int verbose = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is a really stupid program that takes cvsps output, and
|
|
||||||
* generates a a long _shell_script_ that will create the GIT archive
|
|
||||||
* from it.
|
|
||||||
*
|
|
||||||
* You've been warned. I told you it was stupid.
|
|
||||||
*
|
|
||||||
* NOTE NOTE NOTE! In order to do branches correctly, this needs
|
|
||||||
* the fixed cvsps that has the "Ancestor branch" tag output.
|
|
||||||
* Hopefully David Mansfield will update his distribution soon
|
|
||||||
* enough (he's the one who wrote the patch, so at least we don't
|
|
||||||
* have to figt maintainer issues ;)
|
|
||||||
*
|
|
||||||
* Usage:
|
|
||||||
*
|
|
||||||
* TZ=UTC cvsps -A |
|
|
||||||
* cvs2git --cvsroot=[root] --module=[module] > script
|
|
||||||
*
|
|
||||||
* Creates a shell script that will generate the .git archive of
|
|
||||||
* the names CVS repository.
|
|
||||||
*
|
|
||||||
* IMPORTANT NOTE ABOUT "cvsps"! This requires version 2.1 or better,
|
|
||||||
* and the "TZ=UTC" and the "-A" flag is required for sane results!
|
|
||||||
*/
|
|
||||||
enum state {
|
|
||||||
Header,
|
|
||||||
Log,
|
|
||||||
Members
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char *cvsroot;
|
|
||||||
static const char *cvsmodule;
|
|
||||||
|
|
||||||
static char date[100];
|
|
||||||
static char author[100];
|
|
||||||
static char branch[100];
|
|
||||||
static char ancestor[100];
|
|
||||||
static char tag[100];
|
|
||||||
static char log[32768];
|
|
||||||
static int loglen = 0;
|
|
||||||
static int initial_commit = 1;
|
|
||||||
|
|
||||||
static void lookup_author(char *n, char **name, char **email)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* FIXME!!! I'm lazy and stupid.
|
|
||||||
*
|
|
||||||
* This could be something like
|
|
||||||
*
|
|
||||||
* printf("lookup_author '%s'\n", n);
|
|
||||||
* *name = "$author_name";
|
|
||||||
* *email = "$author_email";
|
|
||||||
*
|
|
||||||
* and that would allow the script to do its own
|
|
||||||
* lookups at run-time.
|
|
||||||
*/
|
|
||||||
*name = n;
|
|
||||||
*email = n;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void prepare_commit(void)
|
|
||||||
{
|
|
||||||
char *author_name, *author_email;
|
|
||||||
char *src_branch;
|
|
||||||
|
|
||||||
lookup_author(author, &author_name, &author_email);
|
|
||||||
|
|
||||||
printf("export GIT_COMMITTER_NAME=%s\n", author_name);
|
|
||||||
printf("export GIT_COMMITTER_EMAIL=%s\n", author_email);
|
|
||||||
printf("export GIT_COMMITTER_DATE='+0000 %s'\n", date);
|
|
||||||
|
|
||||||
printf("export GIT_AUTHOR_NAME=%s\n", author_name);
|
|
||||||
printf("export GIT_AUTHOR_EMAIL=%s\n", author_email);
|
|
||||||
printf("export GIT_AUTHOR_DATE='+0000 %s'\n", date);
|
|
||||||
|
|
||||||
if (initial_commit)
|
|
||||||
return;
|
|
||||||
|
|
||||||
src_branch = *ancestor ? ancestor : branch;
|
|
||||||
if (!strcmp(src_branch, "HEAD"))
|
|
||||||
src_branch = "master";
|
|
||||||
printf("ln -sf refs/heads/'%s' .git/HEAD\n", src_branch);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Even if cvsps claims an ancestor, we'll let the new
|
|
||||||
* branch name take precedence if it already exists
|
|
||||||
*/
|
|
||||||
if (*ancestor) {
|
|
||||||
src_branch = branch;
|
|
||||||
if (!strcmp(src_branch, "HEAD"))
|
|
||||||
src_branch = "master";
|
|
||||||
printf("[ -e .git/refs/heads/'%s' ] && ln -sf refs/heads/'%s' .git/HEAD\n",
|
|
||||||
src_branch, src_branch);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("git-read-tree -m HEAD || exit 1\n");
|
|
||||||
printf("git-checkout-cache -f -u -a\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void commit(void)
|
|
||||||
{
|
|
||||||
const char *cmit_parent = initial_commit ? "" : "-p HEAD";
|
|
||||||
const char *dst_branch;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
printf("tree=$(git-write-tree)\n");
|
|
||||||
printf("cat > .cmitmsg <<EOFMSG\n");
|
|
||||||
|
|
||||||
/* Escape $ characters, and remove control characters */
|
|
||||||
for (i = 0; i < loglen; i++) {
|
|
||||||
unsigned char c = log[i];
|
|
||||||
|
|
||||||
switch (c) {
|
|
||||||
case '$':
|
|
||||||
case '\\':
|
|
||||||
case '`':
|
|
||||||
putchar('\\');
|
|
||||||
break;
|
|
||||||
case 0 ... 31:
|
|
||||||
if (c == '\n' || c == '\t')
|
|
||||||
break;
|
|
||||||
case 128 ... 159:
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
putchar(c);
|
|
||||||
}
|
|
||||||
printf("\nEOFMSG\n");
|
|
||||||
printf("commit=$(cat .cmitmsg | git-commit-tree $tree %s)\n", cmit_parent);
|
|
||||||
|
|
||||||
dst_branch = branch;
|
|
||||||
if (!strcmp(dst_branch, "HEAD"))
|
|
||||||
dst_branch = "master";
|
|
||||||
|
|
||||||
printf("echo $commit > .git/refs/heads/'%s'\n", dst_branch);
|
|
||||||
|
|
||||||
printf("echo 'Committed (to %s):' ; cat .cmitmsg; echo\n", dst_branch);
|
|
||||||
|
|
||||||
*date = 0;
|
|
||||||
*author = 0;
|
|
||||||
*branch = 0;
|
|
||||||
*ancestor = 0;
|
|
||||||
*tag = 0;
|
|
||||||
loglen = 0;
|
|
||||||
|
|
||||||
initial_commit = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void update_file(char *line)
|
|
||||||
{
|
|
||||||
char *name, *version;
|
|
||||||
char *dir;
|
|
||||||
|
|
||||||
while (isspace(*line))
|
|
||||||
line++;
|
|
||||||
name = line;
|
|
||||||
line = strchr(line, ':');
|
|
||||||
if (!line)
|
|
||||||
return;
|
|
||||||
*line++ = 0;
|
|
||||||
line = strchr(line, '>');
|
|
||||||
if (!line)
|
|
||||||
return;
|
|
||||||
*line++ = 0;
|
|
||||||
version = line;
|
|
||||||
line = strchr(line, '(');
|
|
||||||
if (line) { /* "(DEAD)" */
|
|
||||||
printf("git-update-cache --force-remove '%s'\n", name);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dir = strrchr(name, '/');
|
|
||||||
if (dir)
|
|
||||||
printf("mkdir -p %.*s\n", (int)(dir - name), name);
|
|
||||||
|
|
||||||
printf("cvs -q -d %s checkout -r%s -p '%s/%s' > '%s'\n", cvsroot, version, cvsmodule, name, name);
|
|
||||||
printf("git-update-cache --add -- '%s'\n", name);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct hdrentry {
|
|
||||||
const char *name;
|
|
||||||
char *dest;
|
|
||||||
} hdrs[] = {
|
|
||||||
{ "Date:", date },
|
|
||||||
{ "Author:", author },
|
|
||||||
{ "Branch:", branch },
|
|
||||||
{ "Ancestor branch:", ancestor },
|
|
||||||
{ "Tag:", tag },
|
|
||||||
{ "Log:", NULL },
|
|
||||||
{ NULL, NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
static char line[1000];
|
|
||||||
enum state state = Header;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 1; i < argc; i++) {
|
|
||||||
const char *arg = argv[i];
|
|
||||||
if (!memcmp(arg, "--cvsroot=", 10)) {
|
|
||||||
cvsroot = arg + 10;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!memcmp(arg, "--module=", 9)) {
|
|
||||||
cvsmodule = arg+9;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!strcmp(arg, "-v")) {
|
|
||||||
verbose = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (!cvsroot)
|
|
||||||
cvsroot = getenv("CVSROOT");
|
|
||||||
|
|
||||||
if (!cvsmodule || !cvsroot) {
|
|
||||||
fprintf(stderr, "I need a CVSROOT and module name\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("[ -d .git ] && exit 1\n");
|
|
||||||
printf("git-init-db\n");
|
|
||||||
printf("mkdir -p .git/refs/heads\n");
|
|
||||||
printf("mkdir -p .git/refs/tags\n");
|
|
||||||
printf("ln -sf refs/heads/master .git/HEAD\n");
|
|
||||||
|
|
||||||
while (fgets(line, sizeof(line), stdin) != NULL) {
|
|
||||||
int linelen = strlen(line);
|
|
||||||
|
|
||||||
while (linelen && isspace(line[linelen-1]))
|
|
||||||
line[--linelen] = 0;
|
|
||||||
|
|
||||||
switch (state) {
|
|
||||||
struct hdrentry *entry;
|
|
||||||
|
|
||||||
case Header:
|
|
||||||
if (verbose)
|
|
||||||
printf("# H: %s\n", line);
|
|
||||||
for (entry = hdrs ; entry->name ; entry++) {
|
|
||||||
int len = strlen(entry->name);
|
|
||||||
char *val;
|
|
||||||
|
|
||||||
if (memcmp(entry->name, line, len))
|
|
||||||
continue;
|
|
||||||
if (!entry->dest) {
|
|
||||||
state = Log;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
val = line + len;
|
|
||||||
linelen -= len;
|
|
||||||
while (isspace(*val)) {
|
|
||||||
val++;
|
|
||||||
linelen--;
|
|
||||||
}
|
|
||||||
memcpy(entry->dest, val, linelen+1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Log:
|
|
||||||
if (verbose)
|
|
||||||
printf("# L: %s\n", line);
|
|
||||||
if (!strcmp(line, "Members:")) {
|
|
||||||
while (loglen && isspace(log[loglen-1]))
|
|
||||||
log[--loglen] = 0;
|
|
||||||
prepare_commit();
|
|
||||||
state = Members;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (loglen + linelen + 5 > sizeof(log))
|
|
||||||
continue;
|
|
||||||
memcpy(log + loglen, line, linelen);
|
|
||||||
loglen += linelen;
|
|
||||||
log[loglen++] = '\n';
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Members:
|
|
||||||
if (verbose)
|
|
||||||
printf("# M: %s\n", line);
|
|
||||||
if (!linelen) {
|
|
||||||
commit();
|
|
||||||
state = Header;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
update_file(line);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
48
stripspace.c
48
stripspace.c
@ -1,48 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Remove empty lines from the beginning and end.
|
|
||||||
*
|
|
||||||
* Turn multiple consecutive empty lines into just one
|
|
||||||
* empty line.
|
|
||||||
*/
|
|
||||||
static void cleanup(char *line)
|
|
||||||
{
|
|
||||||
int len = strlen(line);
|
|
||||||
|
|
||||||
if (len > 1 && line[len-1] == '\n') {
|
|
||||||
do {
|
|
||||||
unsigned char c = line[len-2];
|
|
||||||
if (!isspace(c))
|
|
||||||
break;
|
|
||||||
line[len-2] = '\n';
|
|
||||||
len--;
|
|
||||||
line[len] = 0;
|
|
||||||
} while (len > 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
int empties = -1;
|
|
||||||
char line[1024];
|
|
||||||
|
|
||||||
while (fgets(line, sizeof(line), stdin)) {
|
|
||||||
cleanup(line);
|
|
||||||
|
|
||||||
/* Not just an empty line? */
|
|
||||||
if (line[0] != '\n') {
|
|
||||||
if (empties > 0)
|
|
||||||
putchar('\n');
|
|
||||||
empties = 0;
|
|
||||||
fputs(line, stdout);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (empties < 0)
|
|
||||||
continue;
|
|
||||||
empties++;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -2,8 +2,8 @@ CC=gcc
|
|||||||
CFLAGS=-Wall -O2
|
CFLAGS=-Wall -O2
|
||||||
HOME=$(shell echo $$HOME)
|
HOME=$(shell echo $$HOME)
|
||||||
|
|
||||||
PROGRAMS=mailsplit mailinfo stripspace cvs2git
|
PROGRAMS=mailsplit mailinfo
|
||||||
SCRIPTS=dotest applypatch
|
SCRIPTS=applymbox applypatch
|
||||||
|
|
||||||
all: $(PROGRAMS)
|
all: $(PROGRAMS)
|
||||||
|
|
@ -4,6 +4,8 @@
|
|||||||
## I never got around to renaming after I tested it. We're now on the
|
## I never got around to renaming after I tested it. We're now on the
|
||||||
## second generation of scripts, still called "dotest".
|
## second generation of scripts, still called "dotest".
|
||||||
##
|
##
|
||||||
|
## Update: Ryan Anderson finally shamed me into naming this "applymbox".
|
||||||
|
##
|
||||||
## You give it a mbox-format collection of emails, and it will try to
|
## You give it a mbox-format collection of emails, and it will try to
|
||||||
## apply them to the kernel using "applypatch"
|
## apply them to the kernel using "applypatch"
|
||||||
##
|
##
|
||||||
@ -20,7 +22,7 @@ mailsplit $1 .dotest || exit 1
|
|||||||
for i in .dotest/*
|
for i in .dotest/*
|
||||||
do
|
do
|
||||||
mailinfo .dotest/msg .dotest/patch < $i > .dotest/info || exit 1
|
mailinfo .dotest/msg .dotest/patch < $i > .dotest/info || exit 1
|
||||||
stripspace < .dotest/msg > .dotest/msg-clean
|
git-stripspace < .dotest/msg > .dotest/msg-clean
|
||||||
applypatch .dotest/msg-clean .dotest/patch .dotest/info "$2"
|
applypatch .dotest/msg-clean .dotest/patch .dotest/info "$2"
|
||||||
ret=$?
|
ret=$?
|
||||||
if [ $ret -ne 0 ]; then
|
if [ $ret -ne 0 ]; then
|
Loading…
Reference in New Issue
Block a user