From: Jacob Kroon <jacob.kroon@gmail.com>
To: Jon Nelson <jnelson-git@jamponi.net>
Cc: git@vger.kernel.org
Subject: Re: Fixing author/email fields in commit messages
Date: Mon, 20 Feb 2006 02:21:25 +0100 [thread overview]
Message-ID: <43F91995.10304@gmail.com> (raw)
In-Reply-To: <Pine.LNX.4.63.0602191729100.6352@gheavc.wnzcbav.cig>
[-- Attachment #1: Type: text/plain, Size: 783 bytes --]
After some more private discussion (I forgot to CC the mailing list)
with Jon Nelson,
he came up with this strategy for fixing the author/email part of commit
messages:
0. Make a backup copy of the repository, just in case.
1. Setup your GIT_AUTHOR_xxx/GIT_COMMITTER_xxx env. variables correctly.
2. Apply the attached patch to recent git sources. (patch made by Jon
Nelson).
3. Run the patched git-convert-objects, passing HEAD as argument.
4. Run "git-update-ref HEAD 'newsha1'", where 'newsha1' is the output
from the previous command.
5. Run "git-prune" to get rid of the old stale object files.
This worked for me, but I guess there are no warranties 8)
In case you have multiple branches you might need to repeat the
procedure for each branch.
thanks Jon
//Jacob
[-- Attachment #2: convert-objects.diff --]
[-- Type: text/x-patch, Size: 9372 bytes --]
diff --git a/convert-objects.c b/convert-objects.c
index b49bce2..109bfb0 100644
--- a/convert-objects.c
+++ b/convert-objects.c
@@ -263,7 +263,156 @@ static void convert_date(void *buffer, u
newlen += size;
write_sha1_file(new, newlen, "commit", result_sha1);
- free(new);
+ free(new);
+}
+
+static int convert_email_line(char *dst, void **buf, unsigned long *sp, const char *name, const char *new_email)
+{
+ unsigned long size = *sp;
+ char *line = *buf;
+ char *space = strchr(line, ' ');
+ char *next = strchr(line, '\n');
+ char *email_start = strchr(line, '<');
+ char *email_end = strchr(line, '>');
+ int len, total = 0;
+
+ // "author|committer xyz <xyz> date"
+ // "committer xyz <xyz> date"
+ if (!space || !next || !email_start || !email_end)
+ die("missing or bad author/committer line %s", line);
+
+ ++space;
+ ++email_start;
+ ++next;
+
+ //fprintf(stderr, "yikes: size; %lu \"%s\"\n", size, line);
+
+ *buf = next;
+ *sp = size - (next - line);
+
+ /* copy the stuff from before the name */
+ len = space - line;
+ memcpy(dst, line, len);
+ dst += len;
+ total += len;
+ size -= len;
+
+ /* copy the new name */
+ len = strlen(name);
+ memcpy(dst, name, len);
+ dst += len;
+ total += len;
+ size -= len;
+
+ /* put a space in there */
+ *dst = ' ';
+ ++dst;
+ ++total;
+ --size;
+
+ /* put a '<' in there */
+ *dst = '<';
+ ++dst;
+ ++total;
+ --size;
+
+ /* copy the new email */
+ len = strlen(new_email);
+ memcpy(dst, new_email, len);
+ dst += len;
+ total += len;
+ size -= len;
+
+ /* copy the rest of the line */
+ len = next - email_end;
+ memcpy(dst, email_end, len);
+ dst += len;
+ total += len;
+ size -= len;
+
+ return total;
+}
+
+static void convert_authorcommitter(void *buffer, unsigned long size, unsigned char *result_sha1)
+{
+ char *new = xmalloc(size + 100);
+ unsigned long newlen = 0;
+ char *author_info = strdup(git_author_info());
+ char *committer_info = strdup(git_committer_info());
+ char *author_name, *author_email;
+ char *committer_name, *committer_email;
+ char *temp;
+
+//#define TESTING
+#ifdef TESTING
+ fprintf(stderr, "author_info: \"%s\"\n",
+ author_info);
+ fprintf(stderr, "committer_info: \"%s\"\n",
+ committer_info);
+#endif
+ author_name = author_info;
+ temp = strchr(author_name, '<');
+ if (!temp)
+ die("Unable to find valid name address.");
+ --temp;
+ *temp = '\0';
+ temp += 2;
+
+ author_email = temp;
+ temp = strrchr(author_email, '>');
+ if (!temp)
+ die("Unable to find valid email address.");
+ *temp = '\0';
+
+ committer_name = committer_info;
+ temp = strchr(committer_name, '<');
+ if (!temp)
+ die("Unable to find valid name address.");
+ --temp;
+ *temp = '\0';
+ temp += 2;
+
+ committer_email = temp;
+ temp = strrchr(committer_email, '>');
+ if (!temp)
+ die("Unable to find valid email address.");
+ *temp = '\0';
+
+#ifdef TESTING
+ fprintf(stderr, "author_name: \"%s\"\n", author_name);
+ fprintf(stderr, "author_email: \"%s\"\n", author_email);
+ fprintf(stderr, "committer_name: \"%s\"\n", committer_name);
+ fprintf(stderr, "committer_email: \"%s\"\n", committer_email);
+ exit(0);
+#endif
+
+ // "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"
+ // "committer xyz <xyz> date"
+ newlen += convert_email_line(new + newlen, &buffer, &size, author_name, author_email);
+ newlen += convert_email_line(new + newlen, &buffer, &size, committer_name, committer_email);
+
+ // Rest
+ memcpy(new + newlen, buffer, size);
+ newlen += size;
+
+ write_sha1_file(new, newlen, "commit", result_sha1);
+ free(new);
+ free(author_info);
+ free(committer_info);
}
static void convert_commit(void *buffer, unsigned long size, unsigned char *result_sha1)
@@ -279,7 +428,117 @@ static void convert_commit(void *buffer,
convert_ascii_sha1(buffer+7);
buffer += 48;
}
- convert_date(orig_buffer, orig_size, result_sha1);
+ convert_authorcommitter(orig_buffer, orig_size, result_sha1);
+}
+
+static void convert_tag(void *buffer, unsigned long size, unsigned char *result_sha1)
+{
+ void *orig_buffer = buffer;
+
+ char *new = xmalloc(size + 100);
+ unsigned long newlen = 0;
+
+ char *author_info = strdup(git_author_info());
+ char *committer_info = strdup(git_committer_info());
+ char *author_name, *author_email;
+ char *committer_name, *committer_email;
+ char *temp;
+ unsigned long len = 0;
+ char *email_start;
+ char *email_end;
+ char *author_start;
+ int has_author = 1;
+
+ author_name = author_info;
+ temp = strchr(author_name, '<');
+ if (!temp)
+ die("Unable to find valid name address.");
+ --temp;
+ *temp = '\0';
+ temp += 2;
+
+ author_email = temp;
+ temp = strrchr(author_email, '>');
+ if (!temp)
+ die("Unable to find valid email address.");
+ *temp = '\0';
+
+ committer_name = committer_info;
+ temp = strchr(committer_name, '<');
+ if (!temp)
+ die("Unable to find valid name address.");
+ --temp;
+ *temp = '\0';
+ temp += 2;
+
+ committer_email = temp;
+ temp = strrchr(committer_email, '>');
+ if (!temp)
+ die("Unable to find valid email address.");
+ *temp = '\0';
+
+ //* START *//
+
+ if (memcmp(buffer, "object ", 7))
+ die("Bad tag '%s'", (char*) buffer);
+ convert_ascii_sha1(buffer+7);
+// fprintf(stderr, "converting %s", (char *) (buffer + 7));
+ buffer += 7 + 40 + 1; /* "object " + "hex sha1" + "\n" */
+ /* type commit
+ tag boa-0.94.14rc6
+ tagger...
+ */
+ /* with tagger, we check for tagger author_name <author_email>
+ * and if so, we convert that, too
+ */
+ temp = strchr(buffer, '\n'); /* end of commit line */
+ if (!temp) {
+ die("Bad tag '%s'", (char *) buffer);
+ }
+ ++temp;
+ temp = strchr(temp, '\n'); /* end of tag line */
+ if (!temp) {
+ die("Bad tag '%s'", (char *) buffer);
+ }
+ ++temp;
+ if (memcmp(temp, "tagger ", 7))
+ die("Bad tag '%s'", (char *) buffer);
+ temp += 7; /* just after 'tagger ' */
+
+ len = (temp - (char *) orig_buffer);
+ memcpy(new, orig_buffer, len);
+ newlen += len;
+ ++temp;
+
+ /* check to see if the next item looks like an name + email */
+ email_start = strchr(temp, '<');
+ if (email_start) {
+ email_end = strchr(email_start, '>');
+ if (email_end) {
+ author_start = strchr(temp, ' ');
+ if (author_start && author_start < email_start) {
+ has_author = 1;
+ newlen += sprintf(new + newlen,
+ "%s <%s>\n",
+ author_name,
+ author_email);
+ len = (email_end - (char *) buffer) + 2;
+ }
+
+ }
+ }
+
+ if (len > size) {
+ memcpy(new + newlen, orig_buffer + len, size - len);
+ newlen += (size - len);
+ }
+// fprintf(stderr, "About to write: %s", new);
+// exit(0);
+
+ write_sha1_file(new, newlen, "tag", result_sha1);
+ free(new);
+ free(author_info);
+ free(committer_info);
}
static struct entry * convert_entry(unsigned char *sha1)
@@ -297,13 +556,15 @@ static struct entry * convert_entry(unsi
buffer = xmalloc(size);
memcpy(buffer, data, size);
-
+
if (!strcmp(type, "blob")) {
write_sha1_file(buffer, size, "blob", entry->new_sha1);
- } else if (!strcmp(type, "tree"))
- convert_tree(buffer, size, entry->new_sha1);
- else if (!strcmp(type, "commit"))
- convert_commit(buffer, size, entry->new_sha1);
+ } else if (!strcmp(type, "tree"))
+ convert_tree(buffer, size, entry->new_sha1);
+ else if (!strcmp(type, "commit"))
+ convert_commit(buffer, size, entry->new_sha1);
+ else if (!strcmp(type, "tag"))
+ convert_tag(buffer, size, entry->new_sha1);
else
die("unknown object type '%s' in %s", type, sha1_to_hex(sha1));
entry->converted = 1;
@@ -318,6 +579,7 @@ int main(int argc, char **argv)
struct entry *entry;
setup_git_directory();
+ setup_ident();
if (argc != 2 || get_sha1(argv[1], sha1))
usage("git-convert-objects <sha1>");
prev parent reply other threads:[~2006-02-20 1:15 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-02-19 18:45 Fixing author/email fields in commit messages Jacob Kroon
2006-02-19 19:27 ` Johannes Schindelin
2006-02-19 21:24 ` Sam Vilain
2006-02-19 22:35 ` Jon Nelson
2006-02-19 23:01 ` Jon Nelson
2006-02-19 23:33 ` Jacob Kroon
2006-02-19 23:34 ` Jon Nelson
2006-02-20 1:21 ` Jacob Kroon [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=43F91995.10304@gmail.com \
--to=jacob.kroon@gmail.com \
--cc=git@vger.kernel.org \
--cc=jnelson-git@jamponi.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).