@@ -24,7 +24,8 @@ git-export-filter \- Filter fast\-export data with optional rewrites
\fIgit export\-filter\fR [\-\-verbose|\-v] [\-h|\-\-help] [\-\-version|\-V] [\-\-debug|\-d]
[\-\-authors\-file=<authors_file> [\-\-require\-authors]]
[\-\-branches\-file=<branches_file>] [\-\-trunk\-is\-master]
- [\-\-convert\-tagger=<email>] [\-\-strip\-at\-suffix] [\-\-]
+ [\-\-convert\-tagger=<email>] [\-\-strip\-at\-suffix]
+ [\-\-expand\-renames] [\-\-]
<input_file>|< <input_file> > <output_file>
.fi
.sp
@@ -142,6 +143,17 @@ suffixes to the email addresses it generates in the fast\-export data and will n
authors file\&.
.RE
.PP
+\-\-expand\-renames
+.RS 4
+Some importers of fast\-export data cannot handle renames but can handle copies\&. If \-\-expand\-renames is given then any instances of filerename
+\fIR\fR
+are replaced with a filecopy
+\fIC\fR
+followed by a filedelete
+\fID\fR
+instead\&.
+.RE
+.PP
<input_file>
.RS 4
The fast\-export stream to read\&. If
/*
git-export-filter.c -- filter/transform git fast-export data streams
-Copyright (c) 2013 Kyle J. McKay. All rights reserved.
+Copyright (C) 2013,2014 Kyle J. McKay. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -43,11 +43,11 @@ static const char *const gHelp =
static const char *const gUsage =
"git-export-filter [--authors-file file] [--branches-file file]\n"
" [--convert-tagger id] [--require-authors] [--trunk-is-master]\n"
-" [--strip-at-suffix] (in | < in) > out\n"
+" [--strip-at-suffix] [--expand-renames] (in | < in) > out\n"
"(use git-export-filter -v -h for detailed help)\n";
static const char *const gVersion =
-"git-export-filter version 1.3\n";
+"git-export-filter version 1.4\n";
static const char *me = "git-export-filter";
@@ -61,6 +61,7 @@ static int opt_help = 0;
static int opt_require = 0;
static int opt_trunk_is_master = 0;
static int opt_strip_at = 0;
+static int opt_no_renames = 0;
static char *pushline = NULL;
static char *copybuff;
@@ -250,6 +251,10 @@ int main(int argc, char *argv[])
opt_strip_at = 1;
continue;
}
+ if (!strcmp(A, "--expand-renames")) {
+ opt_no_renames = 1;
+ continue;
+ }
if (!strcmp(A, "-V") || !strcmp(A, "--version")) {
opt_version = 1;
continue;
@@ -596,6 +601,27 @@ static void processtag(FILE *in, FILE *out, const char *tag,
copydata(in, out, 0, "tag missing data line");
}
+static const char *find_second_space(const char *line)
+{
+ if (!line || !*line || *line == ' ' || line[1] != ' ' || line[2] == ' ')
+ return NULL;
+ if (line[2] != '"')
+ return strchr(line + 2, ' ');
+ line += 3;
+ for (;;) {
+ line += strcspn(line, "\\\"");
+ if (!*line)
+ return NULL;
+ if (*line == '\\') {
+ if (!line[1])
+ return NULL;
+ line += 2;
+ continue;
+ }
+ return line[1] == ' ' ? line + 1 : NULL;
+ }
+}
+
static int is_inline_modify(const char *line)
{
if (strncmp(line, "M ", 2) != 0)
@@ -670,7 +696,16 @@ static void processcommit(FILE *in, FILE *out, const char *ref,
!strncmp(line, "D ", 2) || !strncmp(line, "C ", 2) ||
!strncmp(line, "R ", 2) || !strncmp(line, "N ", 2) ||
!strncmp(line, "cat-blob ", 9) || !strncmp(line, "ls ", 3)) {
- fprintf(out, "%s\n", line);
+ if (!opt_no_renames || strncmp(line, "R ", 2)) {
+ fprintf(out, "%s\n", line);
+ } else {
+ /* expand rename into copy + delete */
+ const char *space2 = find_second_space(line);
+ if (!space2)
+ die("error reading 'R' line");
+ fprintf(out, "C %s\n", line+2);
+ fprintf(out, "D %.*s\n", (int)(space2 - line) - 2, line+2);
+ }
if (strncmp(line, "N inline", 8) == 0 || is_inline_modify(line))
copydata(in, out, 1, "inline N or M missing data line");
line = nextline(in);
@@ -12,7 +12,8 @@ SYNOPSIS
'git export-filter' [--verbose|-v] [-h|--help] [--version|-V] [--debug|-d]
[--authors-file=<authors_file> [--require-authors]]
[--branches-file=<branches_file>] [--trunk-is-master]
- [--convert-tagger=<email>] [--strip-at-suffix] [--]
+ [--convert-tagger=<email>] [--strip-at-suffix]
+ [--expand-renames] [--]
<input_file>|< <input_file> > <output_file>
@@ -103,6 +104,12 @@ The 'svn-fe' utility appends '@...' suffixes to the email addresses it
generates in the fast-export data and will need this option to use a standard
'git svn' authors file.
+--expand-renames::
+ Some importers of fast-export data cannot handle renames but can
+ handle copies. If --expand-renames is given then any instances of
+ filerename 'R' are replaced with a filecopy 'C' followed by a
+ filedelete 'D' instead.
+
<input_file>::
The fast-export stream to read. If `<input_file>` is omitted, then
standard input will be read.
git export-filter [--verbose|-v] [-h|--help] [--version|-V] [--debug|-d]
[--authors-file=<authors_file> [--require-authors]]
[--branches-file=<branches_file>] [--trunk-is-master]
- [--convert-tagger=<email>] [--strip-at-suffix] [--]
+ [--convert-tagger=<email>] [--strip-at-suffix]
+ [--expand-renames] [--]
<input_file>|< <input_file> > <output_file>
@@ -95,6 +96,12 @@ OPTIONS
generates in the fast-export data and will need this option to use
a standard git svn authors file.
+ --expand-renames
+ Some importers of fast-export data cannot handle renames but can
+ handle copies. If --expand-renames is given then any instances of
+ filerename 'R' are replaced with a filecopy 'C' followed by a
+ filedelete 'D' instead.
+
<input_file>
The fast-export stream to read. If <input_file> is omitted, then
standard input will be read.