builtin-am: support automatic notes copying
authorPaul Tan <pyokagan@gmail.com>
Tue, 4 Aug 2015 13:51:55 +0000 (21:51 +0800)
committerJunio C Hamano <gitster@pobox.com>
Wed, 5 Aug 2015 05:02:11 +0000 (22:02 -0700)
Since eb2151b (rebase: support automatic notes copying, 2010-03-12),
git-am.sh supported automatic notes copying in --rebasing mode by
invoking "git notes copy" once it has finished applying all the patches.

Re-implement this feature in builtin/am.c.

Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/am.c

index dbec9fc67cb49fa29a2097db6f995ec08e758883..7d7f91df2ccdfd7dd627972b3abd8451eeb83683 100644 (file)
@@ -23,6 +23,7 @@
 #include "merge-recursive.h"
 #include "revision.h"
 #include "log-tree.h"
+#include "notes-utils.h"
 
 /**
  * Returns 1 if the file is empty or does not exist, 0 otherwise.
@@ -478,6 +479,64 @@ static int run_post_rewrite_hook(const struct am_state *state)
        return ret;
 }
 
+/**
+ * Reads the state directory's "rewritten" file, and copies notes from the old
+ * commits listed in the file to their rewritten commits.
+ *
+ * Returns 0 on success, -1 on failure.
+ */
+static int copy_notes_for_rebase(const struct am_state *state)
+{
+       struct notes_rewrite_cfg *c;
+       struct strbuf sb = STRBUF_INIT;
+       const char *invalid_line = _("Malformed input line: '%s'.");
+       const char *msg = "Notes added by 'git rebase'";
+       FILE *fp;
+       int ret = 0;
+
+       assert(state->rebasing);
+
+       c = init_copy_notes_for_rewrite("rebase");
+       if (!c)
+               return 0;
+
+       fp = xfopen(am_path(state, "rewritten"), "r");
+
+       while (!strbuf_getline(&sb, fp, '\n')) {
+               unsigned char from_obj[GIT_SHA1_RAWSZ], to_obj[GIT_SHA1_RAWSZ];
+
+               if (sb.len != GIT_SHA1_HEXSZ * 2 + 1) {
+                       ret = error(invalid_line, sb.buf);
+                       goto finish;
+               }
+
+               if (get_sha1_hex(sb.buf, from_obj)) {
+                       ret = error(invalid_line, sb.buf);
+                       goto finish;
+               }
+
+               if (sb.buf[GIT_SHA1_HEXSZ] != ' ') {
+                       ret = error(invalid_line, sb.buf);
+                       goto finish;
+               }
+
+               if (get_sha1_hex(sb.buf + GIT_SHA1_HEXSZ + 1, to_obj)) {
+                       ret = error(invalid_line, sb.buf);
+                       goto finish;
+               }
+
+               if (copy_note_for_rewrite(c, from_obj, to_obj))
+                       ret = error(_("Failed to copy notes from '%s' to '%s'"),
+                                       sha1_to_hex(from_obj), sha1_to_hex(to_obj));
+       }
+
+finish:
+       finish_copy_notes_for_rewrite(c, msg);
+       fclose(fp);
+       strbuf_release(&sb);
+       return ret;
+}
+
 /**
  * Determines if the file looks like a piece of RFC2822 mail by grabbing all
  * non-indented lines and checking if they look like they begin with valid
@@ -1405,6 +1464,7 @@ next:
 
        if (!is_empty_file(am_path(state, "rewritten"))) {
                assert(state->rebasing);
+               copy_notes_for_rebase(state);
                run_post_rewrite_hook(state);
        }