From 8ac65937d032ad3e4bda1d7d6a8b924a65a01fb4 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 26 Jan 2007 02:26:04 -0800 Subject: [PATCH 1/5] Make sure we do not write bogus reflog entries. The file format dictates that entries are LF terminated so the message cannot have one in it. Chomp the message to make sure it only has a single line if necessary, while removing the leading whitespace. Signed-off-by: Junio C Hamano --- builtin-update-ref.c | 2 -- refs.c | 39 +++++++++++++++++++++++---------------- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/builtin-update-ref.c b/builtin-update-ref.c index b34e5987dd..f2506fa976 100644 --- a/builtin-update-ref.c +++ b/builtin-update-ref.c @@ -23,8 +23,6 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix) msg = argv[++i]; if (!*msg) die("Refusing to perform update with empty message."); - if (strchr(msg, '\n')) - die("Refusing to perform update with \\n in message."); continue; } if (!strcmp("-d", argv[i])) { diff --git a/refs.c b/refs.c index 4323e9a41a..0840b3bab8 100644 --- a/refs.c +++ b/refs.c @@ -925,6 +925,7 @@ static int log_ref_write(struct ref_lock *lock, { int logfd, written, oflags = O_APPEND | O_WRONLY; unsigned maxlen, len; + int msglen; char *logrec; const char *committer; @@ -958,24 +959,30 @@ static int log_ref_write(struct ref_lock *lock, lock->log_file, strerror(errno)); } - committer = git_committer_info(-1); + msglen = 0; if (msg) { - maxlen = strlen(committer) + strlen(msg) + 2*40 + 5; - logrec = xmalloc(maxlen); - len = snprintf(logrec, maxlen, "%s %s %s\t%s\n", - sha1_to_hex(lock->old_sha1), - sha1_to_hex(sha1), - committer, - msg); - } - else { - maxlen = strlen(committer) + 2*40 + 4; - logrec = xmalloc(maxlen); - len = snprintf(logrec, maxlen, "%s %s %s\n", - sha1_to_hex(lock->old_sha1), - sha1_to_hex(sha1), - committer); + /* 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); + } } + + committer = git_committer_info(-1); + maxlen = strlen(committer) + msglen + 100; + logrec = xmalloc(maxlen); + len = sprintf(logrec, "%s %s %s\n", + sha1_to_hex(lock->old_sha1), + sha1_to_hex(sha1), + committer); + if (msglen) + len += sprintf(logrec + len - 1, "\t%.*s\n", msglen, msg) - 1; written = len <= maxlen ? write_in_full(logfd, logrec, len) : -1; free(logrec); close(logfd); From 7f9acb2a16473e5ba6d44231d2fc844ca8bb9817 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 26 Jan 2007 15:09:02 -0800 Subject: [PATCH 2/5] git-merge: leave sensible reflog message when used as the first level UI. It used to throw potentially multi-line log message at reflog. Just record the heads that were given to be merged at the command line and the action. Revert the removal of the check in "git-update-ref -m" I made earlier which was only a work-around for this. Signed-off-by: Junio C Hamano --- builtin-update-ref.c | 2 ++ git-merge.sh | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/builtin-update-ref.c b/builtin-update-ref.c index f2506fa976..b34e5987dd 100644 --- a/builtin-update-ref.c +++ b/builtin-update-ref.c @@ -23,6 +23,8 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix) msg = argv[++i]; if (!*msg) die("Refusing to perform update with empty message."); + if (strchr(msg, '\n')) + die("Refusing to perform update with \\n in message."); continue; } if (!strcmp("-d", argv[i])) { diff --git a/git-merge.sh b/git-merge.sh index 7b590268ed..656869101a 100755 --- a/git-merge.sh +++ b/git-merge.sh @@ -7,7 +7,6 @@ USAGE='[-n] [--no-commit] [--squash] [-s ] [-m=] Date: Fri, 26 Jan 2007 11:57:50 +0100 Subject: [PATCH 3/5] vc-git.el: Take into account the destination name in vc-checkout. This is necessary for vc-version-other-window. Based on a patch by Sam Vilain . Currently, the vc-git-checkout function uses `git checkout' to fetch a file from the git repository to the working copy. However, it is completely ignoring the input argument that specifies the destination file. `git-checkout' does not support specifying this, so we have to use `git-cat-file', capture the output in a buffer and then save it. Signed-off-by: Alexandre Julliard Signed-off-by: Junio C Hamano --- contrib/emacs/vc-git.el | 32 ++++++++------------------------ 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/contrib/emacs/vc-git.el b/contrib/emacs/vc-git.el index 65c4550069..e456ab9712 100644 --- a/contrib/emacs/vc-git.el +++ b/contrib/emacs/vc-git.el @@ -53,10 +53,6 @@ (let ((name (file-relative-name file))) (eq 0 (apply #'call-process "git" nil (get-buffer "*Messages") nil (append args (list name)))))) -(defun vc-git--run-command-out (output &rest args) - "Run a git command, output to output." - (eq 0 (apply #'call-process "git" nil output nil (append args)))) - (defun vc-git-registered (file) "Check whether FILE is registered with git." (with-temp-buffer @@ -125,26 +121,14 @@ (defun vc-git-checkout (file &optional editable rev destfile) (if destfile - (let ((mybuff (get-buffer-create "vc-git-checkout-tmp"))) - (let ((rv - (vc-git--run-command-out - mybuff "cat-file" "blob" - (concat (or rev "HEAD") - ":" - (let ((output (vc-git--run-command-string - (file-relative-name file) - "ls-files" "--full-name"))) - (string-match "\\(.*\\)" output) - (match-string 1 output)) - ))) - ) - (if rv - (save-current-buffer - (set-buffer mybuff) - (set-visited-file-name destfile t) - (save-buffer) - ) - rv))) + (let ((fullname (substring + (vc-git--run-command-string file "ls-files" "-z" "--full-name" "--") + 0 -1)) + (coding-system-for-read 'no-conversion) + (coding-system-for-write 'no-conversion)) + (with-temp-file destfile + (eq 0 (call-process "git" nil t nil "cat-file" "blob" + (concat (or rev "HEAD") ":" fullname))))) (vc-git--run-command file "checkout" (or rev "HEAD")))) (defun vc-git-annotate-command (file buf &optional rev) From 8a56da29628997289aa8ec888ba85889962393e4 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 26 Jan 2007 17:00:57 -0800 Subject: [PATCH 4/5] create_symref: check error return from open(). Signed-off-by: Junio C Hamano --- refs.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/refs.c b/refs.c index 0840b3bab8..12e46b8bbe 100644 --- a/refs.c +++ b/refs.c @@ -331,7 +331,11 @@ int create_symref(const char *ref_target, const char *refs_heads_master) return -1; } lockpath = mkpath("%s.lock", git_HEAD); - fd = open(lockpath, O_CREAT | O_EXCL | O_WRONLY, 0666); + fd = open(lockpath, O_CREAT | O_EXCL | O_WRONLY, 0666); + if (fd < 0) { + error("Unable to open %s for writing", lockpath); + return -5; + } written = write_in_full(fd, ref, len); close(fd); if (written != len) { From d848804a895254583095b5c23ebb5d5f5a8891a3 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 26 Jan 2007 17:39:03 -0800 Subject: [PATCH 5/5] write_in_full: size_t is unsigned. It received the return value from xwrite() in a size_t variable 'written' and expected comparison with 0 would catch an error from xwrite(). Signed-off-by: Junio C Hamano --- write_or_die.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/write_or_die.c b/write_or_die.c index 046e79d485..5c4bc8515a 100644 --- a/write_or_die.c +++ b/write_or_die.c @@ -23,7 +23,7 @@ int write_in_full(int fd, const void *buf, size_t count) ssize_t total = 0; while (count > 0) { - size_t written = xwrite(fd, p, count); + ssize_t written = xwrite(fd, p, count); if (written < 0) return -1; if (!written) {