fmt-patch: Support --attach
authorJohannes Schindelin <Johannes.Schindelin@gmx.de>
Sat, 20 May 2006 13:40:29 +0000 (15:40 +0200)
committerJunio C Hamano <junkio@cox.net>
Sun, 21 May 2006 09:03:09 +0000 (02:03 -0700)
This patch touches a couple of files, because it adds options to print a
custom text just after the subject of a commit, and just after the
diffstat.

[jc: made "many dashes" used as the boundary leader into a single
 variable, to reduce the possibility of later tweaks to miscount the
 number of dashes to break it.]

Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
builtin-log.c
builtin-rev-list.c
commit.c
commit.h
diff.c
diff.h
log-tree.c
revision.h
show-branch.c

index 12a6d19203f054d892c04873fef0f92a5c2ef0c9..c8feb0f7953a4d431c180e33f9f71d4434a4e51a 100644 (file)
@@ -183,7 +183,12 @@ int cmd_format_patch(int argc, const char **argv, char **envp)
                                                argv[i + 1]);
                        output_directory = strdup(argv[i + 1]);
                        i++;
-               } else
+               }
+               else if (!strcmp(argv[i], "--attach"))
+                       rev.mime_boundary = git_version_string;
+               else if (!strncmp(argv[i], "--attach=", 9))
+                       rev.mime_boundary = argv[i] + 9;
+               else
                        argv[j++] = argv[i];
        }
        argc = j;
@@ -224,8 +229,14 @@ int cmd_format_patch(int argc, const char **argv, char **envp)
                shown = log_tree_commit(&rev, commit);
                free(commit->buffer);
                commit->buffer = NULL;
-               if (shown)
-                       printf("-- \n%s\n\n", git_version_string);
+               if (shown) {
+                       if (rev.mime_boundary)
+                               printf("\n--%s%s--\n\n\n",
+                                      mime_boundary_leader,
+                                      rev.mime_boundary);
+                       else
+                               printf("-- \n%s\n\n", git_version_string);
+               }
                if (!use_stdout)
                        fclose(stdout);
        }
index 7942297d137aa3ccd6bf5f6b4bca1afa35ae5450..f11dbd65c14a196f92c98d5c16be0cda74a1edf1 100644 (file)
@@ -85,7 +85,7 @@ static void show_commit(struct commit *commit)
                static char pretty_header[16384];
                pretty_print_commit(revs.commit_format, commit, ~0,
                                    pretty_header, sizeof(pretty_header),
-                                   revs.abbrev, NULL);
+                                   revs.abbrev, NULL, NULL);
                printf("%s%c", pretty_header, hdr_termination);
        }
        fflush(stdout);
index 84558bac29afd64e295a451ad7baa099237ae045..0b163d48570bf8e33d3481f5191b64ed86932f50 100644 (file)
--- a/commit.c
+++ b/commit.c
@@ -498,7 +498,7 @@ static int add_merge_info(enum cmit_fmt fmt, char *buf, const struct commit *com
        return offset;
 }
 
-unsigned long pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit, unsigned long len, char *buf, unsigned long space, int abbrev, const char *subject)
+unsigned long pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit, unsigned long len, char *buf, unsigned long space, int abbrev, const char *subject, const char *after_subject)
 {
        int hdr = 1, body = 0;
        unsigned long offset = 0;
@@ -591,6 +591,14 @@ unsigned long pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit
                buf[offset++] = '\n';
                if (fmt == CMIT_FMT_ONELINE)
                        break;
+               if (after_subject) {
+                       int slen = strlen(after_subject);
+                       if (slen > space - offset - 1)
+                               slen = space - offset - 1;
+                       memcpy(buf + offset, after_subject, slen);
+                       offset += slen;
+                       after_subject = NULL;
+               }
                subject = NULL;
        }
        while (offset && isspace(buf[offset-1]))
index 8d7514cd0012377195ef8a5022e98e887fe6a2e1..c9de1677e903ead414e5133424b722bea907b4d9 100644 (file)
--- a/commit.h
+++ b/commit.h
@@ -51,7 +51,7 @@ enum cmit_fmt {
 };
 
 extern enum cmit_fmt get_commit_format(const char *arg);
-extern unsigned long pretty_print_commit(enum cmit_fmt fmt, const struct commit *, unsigned long len, char *buf, unsigned long space, int abbrev, const char *subject);
+extern unsigned long pretty_print_commit(enum cmit_fmt fmt, const struct commit *, unsigned long len, char *buf, unsigned long space, int abbrev, const char *subject, const char *after_subject);
 
 /** Removes the first commit from a list sorted by date, and adds all
  * of its parents.
diff --git a/diff.c b/diff.c
index af5db0ec12817a259c8c4f4c1482aa90ace03f17..be459cac6946fffeba71301416dd9443c1d44eff 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -299,6 +299,7 @@ static void diffstat_consume(void *priv, char *line, unsigned long len)
 
 static const char pluses[] = "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++";
 static const char minuses[]= "----------------------------------------------------------------------";
+const char mime_boundary_leader[] = "------------";
 
 static void show_stats(struct diffstat_t* data)
 {
@@ -1980,7 +1981,10 @@ void diff_flush(struct diff_options *options)
                show_stats(diffstat);
                free(diffstat);
                diffstat = NULL;
-               putchar(options->line_termination);
+               if (options->stat_sep)
+                       fputs(options->stat_sep, stdout);
+               else
+                       putchar(options->line_termination);
        }
        for (i = 0; i < q->nr; i++) {
                struct diff_filepair *p = q->queue[i];
diff --git a/diff.h b/diff.h
index c672277df25a6855e09e642cdf6341841b4dd5a3..4fc597c59421b7558e0beb0f2994e15950592aaa 100644 (file)
--- a/diff.h
+++ b/diff.h
@@ -44,6 +44,7 @@ struct diff_options {
        int rename_limit;
        int setup;
        int abbrev;
+       const char *stat_sep;
 
        int nr_paths;
        const char **paths;
@@ -52,6 +53,8 @@ struct diff_options {
        add_remove_fn_t add_remove;
 };
 
+extern const char mime_boundary_leader[];
+
 extern void diff_tree_setup_paths(const char **paths, struct diff_options *);
 extern void diff_tree_release_paths(struct diff_options *);
 extern int diff_tree(struct tree_desc *t1, struct tree_desc *t2,
index 526d578e98eef5a099be43bf39a300b33ac1991c..7e23e42788986257b9c108bcd340460a60a0cf88 100644 (file)
@@ -20,7 +20,7 @@ void show_log(struct rev_info *opt, struct log_info *log, const char *sep)
        int abbrev_commit = opt->abbrev_commit ? opt->abbrev : 40;
        const char *extra;
        int len;
-       charsubject = NULL;
+       char *subject = NULL, *after_subject = NULL;
 
        opt->loginfo = NULL;
        if (!opt->verbose_header) {
@@ -52,6 +52,7 @@ void show_log(struct rev_info *opt, struct log_info *log, const char *sep)
         */
 
        if (opt->commit_format == CMIT_FMT_EMAIL) {
+               char *sha1 = sha1_to_hex(commit->object.sha1);
                if (opt->total > 0) {
                        static char buffer[64];
                        snprintf(buffer, sizeof(buffer),
@@ -63,8 +64,36 @@ void show_log(struct rev_info *opt, struct log_info *log, const char *sep)
                else
                        subject = "Subject: ";
 
-               printf("From %s  Thu Apr 7 15:13:13 2005\n",
-                      sha1_to_hex(commit->object.sha1));
+               printf("From %s Mon Sep 17 00:00:00 2001\n", sha1);
+               if (opt->mime_boundary) {
+                       static char subject_buffer[1024];
+                       static char buffer[1024];
+                       snprintf(subject_buffer, sizeof(subject_buffer) - 1,
+                                "MIME-Version: 1.0\n"
+                                "Content-Type: multipart/mixed;\n"
+                                " boundary=\"%s%s\"\n"
+                                "\n"
+                                "This is a multi-part message in MIME "
+                                "format.\n"
+                                "--%s%s\n"
+                                "Content-Type: text/plain; "
+                                "charset=UTF-8; format=fixed\n"
+                                "Content-Transfer-Encoding: 8bit\n\n",
+                                mime_boundary_leader, opt->mime_boundary,
+                                mime_boundary_leader, opt->mime_boundary);
+                       after_subject = subject_buffer;
+
+                       snprintf(buffer, sizeof(buffer) - 1,
+                                "--%s%s\n"
+                                "Content-Type: text/x-patch;\n"
+                                " name=\"%s.diff\"\n"
+                                "Content-Transfer-Encoding: 8bit\n"
+                                "Content-Disposition: inline;\n"
+                                " filename=\"%s.diff\"\n\n",
+                                mime_boundary_leader, opt->mime_boundary,
+                                sha1, sha1);
+                       opt->diffopt.stat_sep = buffer;
+               }
        } else {
                printf("%s%s",
                       opt->commit_format == CMIT_FMT_ONELINE ? "" : "commit ",
@@ -81,7 +110,7 @@ void show_log(struct rev_info *opt, struct log_info *log, const char *sep)
        /*
         * And then the pretty-printed message itself
         */
-       len = pretty_print_commit(opt->commit_format, commit, ~0u, this_header, sizeof(this_header), abbrev, subject);
+       len = pretty_print_commit(opt->commit_format, commit, ~0u, this_header, sizeof(this_header), abbrev, subject, after_subject);
        printf("%s%s%s", this_header, extra, sep);
 }
 
index 62759f7bc05c0133fd900bca15f01c4d17487589..bdbdd235d821eff10eae42d32933152f2d22bd74 100644 (file)
@@ -59,6 +59,7 @@ struct rev_info {
        enum cmit_fmt   commit_format;
        struct log_info *loginfo;
        int             nr, total;
+       const char      *mime_boundary;
 
        /* special limits */
        int max_count;
index bbe26c2e7af7515d07af990a4db67c62ee14eb36..684ffd187c4e95f4ff16091856dcd5497ced3891 100644 (file)
@@ -259,7 +259,7 @@ static void show_one_commit(struct commit *commit, int no_name)
        struct commit_name *name = commit->object.util;
        if (commit->object.parsed)
                pretty_print_commit(CMIT_FMT_ONELINE, commit, ~0,
-                                   pretty, sizeof(pretty), 0, NULL);
+                                   pretty, sizeof(pretty), 0, NULL, NULL);
        else
                strcpy(pretty, "(unavailable)");
        if (!strncmp(pretty, "[PATCH] ", 8))