summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 144bde7)
raw | patch | inline | side by side (parent: 144bde7)
author | Linus Torvalds <torvalds@ppc970.osdl.org> | |
Sat, 23 Apr 2005 23:37:31 +0000 (16:37 -0700) | ||
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | |
Sat, 23 Apr 2005 23:37:31 +0000 (16:37 -0700) |
This includes the old-style "flat tree" object, and the old broken
date format. Well, enough of the date format to convert the sparse
archive, at least.
date format. Well, enough of the date format to convert the sparse
archive, at least.
convert-cache.c | patch | blob | history |
diff --git a/convert-cache.c b/convert-cache.c
index 97e9952518120b1f48df6422468d2968d2119132..35191dffa7cba3de5297111c1ffa4253df6124a7 100644 (file)
--- a/convert-cache.c
+++ b/convert-cache.c
+#define _XOPEN_SOURCE /* glibc2 needs this */
+#include <time.h>
+#include <ctype.h>
#include "cache.h"
struct entry {
return insert_new(sha1, low);
}
-static void convert_blob(void *buffer, unsigned long size)
-{
- /* Nothing to do */
-}
-
static void convert_binary_sha1(void *buffer)
{
struct entry *entry = convert_entry(buffer);
memcpy(buffer, sha1_to_hex(entry->new_sha1), 40);
}
-static void convert_tree(void *buffer, unsigned long size)
+#define ORIG_OFFSET (40)
+
+static int prepend_integer(char *buffer, unsigned val, int i)
+{
+ buffer[--i] = '\0';
+ do {
+ buffer[--i] = '0' + (val % 10);
+ val /= 10;
+ } while (val);
+ return i;
+}
+
+
+static int write_subdirectory(void *buffer, unsigned long size, const char *base, int baselen, unsigned char *result_sha1)
{
+ char *new = malloc(size + ORIG_OFFSET);
+ unsigned long newlen = ORIG_OFFSET;
+ unsigned long used;
+ int i;
+
+ used = 0;
+ while (size) {
+ int len = 21 + strlen(buffer);
+ char *path = strchr(buffer, ' ');
+ unsigned char *sha1;
+ unsigned int mode;
+ char *slash, *origpath;
+
+ if (!path || sscanf(buffer, "%o", &mode) != 1)
+ die("bad tree conversion");
+ path++;
+ if (memcmp(path, base, baselen))
+ break;
+ origpath = path;
+ path += baselen;
+ slash = strchr(path, '/');
+ if (!slash) {
+ newlen += sprintf(new + newlen, "%o %s", mode, path);
+ new[newlen++] = '\0';
+ memcpy(new + newlen, buffer + len - 20, 20);
+ newlen += 20;
+
+ used += len;
+ size -= len;
+ buffer += len;
+ continue;
+ }
+
+ newlen += sprintf(new + newlen, "%o %.*s", S_IFDIR, slash - path, path);
+ new[newlen++] = 0;
+ sha1 = (unsigned char *)(new + newlen);
+ newlen += 20;
+
+ len = write_subdirectory(buffer, size, origpath, slash-origpath+1, sha1);
+
+ used += len;
+ size -= len;
+ buffer += len;
+ }
+
+ i = prepend_integer(new, newlen - ORIG_OFFSET, ORIG_OFFSET);
+ i -= 5;
+ memcpy(new + i, "tree ", 5);
+
+ write_sha1_file(new + i, newlen - i, result_sha1);
+ free(new);
+ return used;
+}
+
+static void convert_tree(void *buffer, unsigned long size, unsigned char *result_sha1)
+{
+ void *orig_buffer = buffer;
+ unsigned long orig_size = size;
+
while (size) {
int len = 1+strlen(buffer);
size -= len;
buffer += len;
}
+
+ write_subdirectory(orig_buffer, orig_size, "", 0, result_sha1);
+}
+
+static unsigned long parse_oldstyle_date(const char *buf)
+{
+ char c, *p;
+ char buffer[100];
+ struct tm tm;
+ const char *formats[] = {
+ "%c",
+ "%a %b %d %T",
+ "%Z",
+ "%Y",
+ " %Y",
+ NULL
+ };
+ /* We only ever did two timezones in the bad old format .. */
+ const char *timezones[] = {
+ "PDT", "PST", NULL
+ };
+ const char **fmt = formats;
+
+ p = buffer;
+ while (isspace(c = *buf))
+ buf++;
+ while ((c = *buf++) != '\n')
+ *p++ = c;
+ *p++ = 0;
+ buf = buffer;
+ memset(&tm, 0, sizeof(tm));
+ do {
+ const char *next = strptime(buf, *fmt, &tm);
+ if (next) {
+ if (!*next)
+ return mktime(&tm);
+ buf = next;
+ } else {
+ const char **p = timezones;
+ while (isspace(*buf))
+ buf++;
+ while (*p) {
+ if (!memcmp(buf, *p, strlen(*p))) {
+ buf += strlen(*p);
+ break;
+ }
+ p++;
+ }
+ }
+ fmt++;
+ } while (*buf && *fmt);
+ printf("left: %s\n", buf);
+ return mktime(&tm);
+}
+
+static int convert_date_line(char *dst, void **buf, unsigned long *sp)
+{
+ unsigned long size = *sp;
+ char *line = *buf;
+ char *next = strchr(line, '\n');
+ char *date = strchr(line, '>');
+ int len;
+
+ if (!next || !date)
+ die("missing or bad author/committer line %s", line);
+ next++; date += 2;
+
+ *buf = next;
+ *sp = size - (next - line);
+
+ len = date - line;
+ memcpy(dst, line, len);
+ dst += len;
+
+ /* Is it already in new format? */
+ if (isdigit(*date)) {
+ int datelen = next - date;
+ memcpy(dst, date, datelen);
+ printf("new format date '%.*s'?\n", datelen-1, date);
+ return len + datelen;
+ }
+
+ return len + sprintf(dst, "%lu -0700\n", parse_oldstyle_date(date));
}
-static void convert_commit(void *buffer, unsigned long size)
+static void convert_date(void *buffer, unsigned long size, unsigned char *result_sha1)
{
+ char *new = malloc(size + ORIG_OFFSET + 100);
+ unsigned long newlen = ORIG_OFFSET;
+ int i;
+
+ // "tree <sha1>\n"
+ memcpy(new + newlen, buffer, 46);
+ newlen += 46;
+ buffer += 46;
+ size -= 46;
+
+ // "parent <sha1>\n"
+ while (!memcmp(buffer, "parent ", 7)) {
+ memcpy(new + newlen, buffer, 48);
+ newlen += 48;
+ buffer += 48;
+ size -= 48;
+ }
+
+ // "author xyz <xyz> date"
+ newlen += convert_date_line(new + newlen, &buffer, &size);
+ // "committer xyz <xyz> date"
+ newlen += convert_date_line(new + newlen, &buffer, &size);
+
+ // Rest
+ memcpy(new + newlen, buffer, size);
+ newlen += size;
+
+ i = prepend_integer(new, newlen - ORIG_OFFSET, ORIG_OFFSET);
+ i -= 7;
+ memcpy(new + i, "commit ", 7);
+
+ write_sha1_file(new + i, newlen - i, result_sha1);
+ free(new);
+}
+
+static void convert_commit(void *buffer, unsigned long size, unsigned char *result_sha1)
+{
+ void *orig_buffer = buffer;
+ unsigned long orig_size = size;
+
convert_ascii_sha1(buffer+5);
buffer += 46; /* "tree " + "hex sha1" + "\n" */
while (!memcmp(buffer, "parent ", 7)) {
convert_ascii_sha1(buffer+7);
buffer += 48;
}
+ convert_date(orig_buffer, orig_size, result_sha1);
}
static struct entry * convert_entry(unsigned char *sha1)
offset = sprintf(buffer, "%s %lu", type, size)+1;
memcpy(buffer + offset, data, size);
- if (!strcmp(type, "blob"))
- convert_blob(buffer + offset, size);
- else if (!strcmp(type, "tree"))
- convert_tree(buffer + offset, size);
+ if (!strcmp(type, "blob")) {
+ write_sha1_file(buffer, size + offset, entry->new_sha1);
+ } else if (!strcmp(type, "tree"))
+ convert_tree(buffer + offset, size, entry->new_sha1);
else if (!strcmp(type, "commit"))
- convert_commit(buffer + offset, size);
+ convert_commit(buffer + offset, size, entry->new_sha1);
else
die("unknown object type '%s' in %s", type, sha1_to_hex(sha1));
- write_sha1_file(buffer, size + offset, entry->new_sha1);
entry->converted = 1;
free(buffer);
return entry;