log_ref_write() -- do not chomp reflog message at the first LF
authorJunio C Hamano <gitster@pobox.com>
Sun, 29 Jul 2007 00:17:17 +0000 (17:17 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 30 Jul 2007 06:28:55 +0000 (23:28 -0700)
A reflog file is organized as one-line-per-entry records, and we
enforced the file format integrity by chomping the given message
at the first LF.  This changes it to convert them to SP, which
is more in line with the --pretty=oneline format.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
refs.c

diff --git a/refs.c b/refs.c
index 2694e7066d2dfdb155016ac3cd0104913b475c79..fac6548001068b15739065d04e343c8730e8c3de 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -1036,6 +1036,32 @@ void unlock_ref(struct ref_lock *lock)
        free(lock);
 }
 
+/*
+ * copy the reflog message msg to buf, which has been allocated sufficiently
+ * large, while cleaning up the whitespaces.  Especially, convert LF to space,
+ * because reflog file is one line per entry.
+ */
+static int copy_msg(char *buf, const char *msg)
+{
+       char *cp = buf;
+       char c;
+       int wasspace = 1;
+
+       *cp++ = '\t';
+       while ((c = *msg++)) {
+               if (wasspace && isspace(c))
+                       continue;
+               wasspace = isspace(c);
+               if (wasspace)
+                       c = ' ';
+               *cp++ = c;
+       }
+       while (buf < cp && isspace(cp[-1]))
+               cp--;
+       *cp++ = '\n';
+       return cp - buf;
+}
+
 static int log_ref_write(const char *ref_name, const unsigned char *old_sha1,
                         const unsigned char *new_sha1, const char *msg)
 {
@@ -1080,21 +1106,7 @@ static int log_ref_write(const char *ref_name, const unsigned char *old_sha1,
 
        adjust_shared_perm(log_file);
 
-       msglen = 0;
-       if (msg) {
-               /* clean up the message and make sure it is a single line */
-               for ( ; *msg; msg++)
-                       if (!isspace(*msg))
-                               break;
-               if (*msg) {
-                       const char *ep = strchr(msg, '\n');
-                       if (ep)
-                               msglen = ep - msg;
-                       else
-                               msglen = strlen(msg);
-               }
-       }
-
+       msglen = msg ? strlen(msg) : 0;
        committer = git_committer_info(-1);
        maxlen = strlen(committer) + msglen + 100;
        logrec = xmalloc(maxlen);
@@ -1103,7 +1115,7 @@ static int log_ref_write(const char *ref_name, const unsigned char *old_sha1,
                      sha1_to_hex(new_sha1),
                      committer);
        if (msglen)
-               len += sprintf(logrec + len - 1, "\t%.*s\n", msglen, msg) - 1;
+               len += copy_msg(logrec + len - 1, msg) - 1;
        written = len <= maxlen ? write_in_full(logfd, logrec, len) : -1;
        free(logrec);
        if (close(logfd) != 0 || written != len)