7e11902c99
Current svn-fe produces output like this: blob mark :7382321 data 5 hello blob mark :7382322 data 5 Hello commit mark :3 [...] M 100644 :7382321 hello.c M 100644 :7382322 hello2.c This means svn-fe has to keep track of the paths modified in each commit and the corresponding marks, instead of dealing with each file as it arrives in input and then forgetting about it. A better strategy would be to use inline blobs: commit mark :3 [...] M 100644 inline hello.c data 5 hello [...] As a first step towards that, teach svn-fe to notice when the collection of blobs for each commit starts and write a comment ("# commit 3.") there. Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
111 lines
2.7 KiB
C
111 lines
2.7 KiB
C
/*
|
|
* Licensed under a two-clause BSD-style license.
|
|
* See LICENSE for details.
|
|
*/
|
|
|
|
#include "git-compat-util.h"
|
|
#include "fast_export.h"
|
|
#include "line_buffer.h"
|
|
#include "repo_tree.h"
|
|
#include "string_pool.h"
|
|
|
|
#define MAX_GITSVN_LINE_LEN 4096
|
|
|
|
static uint32_t first_commit_done;
|
|
static struct line_buffer report_buffer = LINE_BUFFER_INIT;
|
|
|
|
void fast_export_init(int fd)
|
|
{
|
|
if (buffer_fdinit(&report_buffer, fd))
|
|
die_errno("cannot read from file descriptor %d", fd);
|
|
}
|
|
|
|
void fast_export_deinit(void)
|
|
{
|
|
if (buffer_deinit(&report_buffer))
|
|
die_errno("error closing fast-import feedback stream");
|
|
}
|
|
|
|
void fast_export_reset(void)
|
|
{
|
|
buffer_reset(&report_buffer);
|
|
}
|
|
|
|
void fast_export_delete(uint32_t depth, uint32_t *path)
|
|
{
|
|
putchar('D');
|
|
putchar(' ');
|
|
pool_print_seq(depth, path, '/', stdout);
|
|
putchar('\n');
|
|
}
|
|
|
|
void fast_export_modify(uint32_t depth, uint32_t *path, uint32_t mode,
|
|
uint32_t mark)
|
|
{
|
|
/* Mode must be 100644, 100755, 120000, or 160000. */
|
|
printf("M %06"PRIo32" :%"PRIu32" ", mode, mark);
|
|
pool_print_seq(depth, path, '/', stdout);
|
|
putchar('\n');
|
|
}
|
|
|
|
void fast_export_begin_commit(uint32_t revision)
|
|
{
|
|
printf("# commit %"PRIu32".\n", revision);
|
|
}
|
|
|
|
static char gitsvnline[MAX_GITSVN_LINE_LEN];
|
|
void fast_export_commit(uint32_t revision, uint32_t author, char *log,
|
|
uint32_t uuid, uint32_t url,
|
|
unsigned long timestamp)
|
|
{
|
|
if (!log)
|
|
log = "";
|
|
if (~uuid && ~url) {
|
|
snprintf(gitsvnline, MAX_GITSVN_LINE_LEN,
|
|
"\n\ngit-svn-id: %s@%"PRIu32" %s\n",
|
|
pool_fetch(url), revision, pool_fetch(uuid));
|
|
} else {
|
|
*gitsvnline = '\0';
|
|
}
|
|
printf("commit refs/heads/master\n");
|
|
printf("mark :%"PRIu32"\n", revision);
|
|
printf("committer %s <%s@%s> %ld +0000\n",
|
|
~author ? pool_fetch(author) : "nobody",
|
|
~author ? pool_fetch(author) : "nobody",
|
|
~uuid ? pool_fetch(uuid) : "local", timestamp);
|
|
printf("data %"PRIu32"\n%s%s\n",
|
|
(uint32_t) (strlen(log) + strlen(gitsvnline)),
|
|
log, gitsvnline);
|
|
if (!first_commit_done) {
|
|
if (revision > 1)
|
|
printf("from refs/heads/master^0\n");
|
|
first_commit_done = 1;
|
|
}
|
|
repo_diff(revision - 1, revision);
|
|
fputc('\n', stdout);
|
|
|
|
printf("progress Imported commit %"PRIu32".\n\n", revision);
|
|
}
|
|
|
|
static const char *get_response_line(void)
|
|
{
|
|
const char *line = buffer_read_line(&report_buffer);
|
|
if (line)
|
|
return line;
|
|
if (buffer_ferror(&report_buffer))
|
|
die_errno("error reading from fast-import");
|
|
die("unexpected end of fast-import feedback");
|
|
}
|
|
|
|
void fast_export_blob(uint32_t mode, uint32_t mark, uint32_t len, struct line_buffer *input)
|
|
{
|
|
if (mode == REPO_MODE_LNK) {
|
|
/* svn symlink blobs start with "link " */
|
|
buffer_skip_bytes(input, 5);
|
|
len -= 5;
|
|
}
|
|
printf("blob\nmark :%"PRIu32"\ndata %"PRIu32"\n", mark, len);
|
|
buffer_copy_bytes(input, len);
|
|
fputc('\n', stdout);
|
|
}
|