Merge branch 'sp/maint-index-pack' into maint
authorJunio C Hamano <gitster@pobox.com>
Fri, 18 Jul 2008 22:39:51 +0000 (15:39 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 18 Jul 2008 22:39:51 +0000 (15:39 -0700)
* sp/maint-index-pack:
index-pack: Honor core.deltaBaseCacheLimit when resolving deltas
index-pack: Track the object_entry that creates each base_data
index-pack: Chain the struct base_data on the stack for traversal
index-pack: Refactor base arguments of resolve_delta into a struct

30 files changed:
Documentation/RelNotes-1.5.6.4.txt [new file with mode: 0644]
Documentation/git-cherry-pick.txt
Documentation/git-revert.txt
Documentation/pretty-formats.txt
Documentation/technical/api-run-command.txt
RelNotes
attr.c
builtin-fetch-pack.c
builtin-grep.c
builtin-mailinfo.c
builtin-rev-list.c
contrib/completion/git-completion.bash
daemon.c
diff-lib.c
diff.c
diff.h
git-cvsserver.perl
git-rebase--interactive.sh
http-walker.c
pretty.c
revision.c
sha1_file.c
t/t5100-mailinfo.sh
t/t5100/0010 [new file with mode: 0644]
t/t5100/info0010 [new file with mode: 0644]
t/t5100/msg0010 [new file with mode: 0644]
t/t5100/patch0010 [new file with mode: 0644]
t/t5100/sample.mbox
t/t7600-merge.sh
tree-diff.c
diff --git a/Documentation/RelNotes-1.5.6.4.txt b/Documentation/RelNotes-1.5.6.4.txt
new file mode 100644 (file)
index 0000000..1304188
--- /dev/null
@@ -0,0 +1,43 @@
+GIT v1.5.6.4 Release Notes
+==========================
+
+Fixes since v1.5.6.3
+--------------------
+
+* Various commands could overflow its internal buffer on a platform
+  with small PATH_MAX value in a repository that has contents with
+  long pathnames.
+
+* There wasn't a way to make --pretty=format:%<> specifiers to honor
+  .mailmap name rewriting for authors and committers.  Now you can with
+  %aN and %cN.
+
+* Bash completion wasted too many cycles; this has been optimized to be
+  usable again.
+
+* Bash completion lost ref part when completing something like "git show
+  pu:Makefile".
+
+* "git-cvsserver" did not clean up its temporary working area after annotate
+  request.
+
+* "git-daemon" called syslog() from its signal handler, which was a
+  no-no.
+
+* "git-fetch" into an empty repository used to remind that the fetch will
+   be huge by saying "no common commits", but this was an unnecessary
+   noise; it is already known by the user anyway.
+
+* "git-mailinfo" (hence "git-am") did not correctly handle in-body [PATCH]
+  line to override the commit title taken from the mail Subject header.
+
+* "git-rebase -i -p" lost parents that are not involved in the history
+  being rewritten.
+
+Contains other various documentation fixes.
+
+--
+exec >/var/tmp/1
+echo O=$(git describe maint)
+O=v1.5.6.3-21-gebcce31
+git shortlog --no-merges $O..maint
index 5ac9cfb0ef2e2eb26ebe5cce6a5c7ed54d4e39ec..4ef5af4ca9ff31933c14f3d965348d67be9f983f 100644 (file)
@@ -58,14 +58,14 @@ OPTIONS
        Usually the command automatically creates a commit with
        a commit log message stating which commit was
        cherry-picked.  This flag applies the change necessary
-       to cherry-pick the named commit to your working tree,
-       but does not make the commit.  In addition, when this
-       option is used, your working tree does not have to match
+       to cherry-pick the named commit to your working tree
+       and the index, but does not make the commit.  In addition,
+       when this option is used, your index does not have to match
        the HEAD commit.  The cherry-pick is done against the
-       beginning state of your working tree.
+       beginning state of your index.
 +
 This is useful when cherry-picking more than one commits'
-effect to your working tree in a row.
+effect to your index in a row.
 
 -s::
 --signoff::
index 5b49b813862c5318701e40f1a798ca04cd1d3a63..f7f4bd4689a3b160d27bc28e54a8c9a0e12e81cc 100644 (file)
@@ -43,16 +43,16 @@ OPTIONS
 -n::
 --no-commit::
        Usually the command automatically creates a commit with
-       a commit log message stating which commit was reverted.
-       This flag applies the change necessary to revert the
-       named commit to your working tree, but does not make the
-       commit.  In addition, when this option is used, your
-       working tree does not have to match the HEAD commit.
-       The revert is done against the beginning state of your
-       working tree.
+       a commit log message stating which commit was
+       reverted.  This flag applies the change necessary
+       to revert the named commit to your working tree
+       and the index, but does not make the commit.  In addition,
+       when this option is used, your index does not have to match
+       the HEAD commit.  The revert is done against the
+       beginning state of your index.
 +
 This is useful when reverting more than one commits'
-effect to your working tree in a row.
+effect to your index in a row.
 
 -s::
 --signoff::
index 69e6d2fa4459313e4a6bdda77847d74d9219e2e1..c11d4957714db202a012209e2437b9e050a28ae0 100644 (file)
@@ -101,6 +101,7 @@ The placeholders are:
 - '%P': parent hashes
 - '%p': abbreviated parent hashes
 - '%an': author name
+- '%aN': author name (respecting .mailmap)
 - '%ae': author email
 - '%ad': author date
 - '%aD': author date, RFC2822 style
@@ -108,6 +109,7 @@ The placeholders are:
 - '%at': author date, UNIX timestamp
 - '%ai': author date, ISO 8601 format
 - '%cn': committer name
+- '%cN': committer name (respecting .mailmap)
 - '%ce': committer email
 - '%cd': committer date
 - '%cD': committer date, RFC2822 style
index 3e1342acf405adb322054a19123cd98fc12b69a9..75aa5d49234ec36857a7c8d2f3900001af5cbcde 100644 (file)
@@ -30,7 +30,7 @@ Functions
        start_command() followed by finish_command(). Takes a pointer
        to a `struct child_process` that specifies the details.
 
-`run_command_v_opt`, `run_command_v_opt_dir`, `run_command_v_opt_cd_env`::
+`run_command_v_opt`, `run_command_v_opt_cd`, `run_command_v_opt_cd_env`::
 
        Convenience functions that encapsulate a sequence of
        start_command() followed by finish_command(). The argument argv
index a2b8043c8348d785ce3550a9109b785906f370b0..e4bd68a0db00ed18db8199e92e8669919de53706 120000 (symlink)
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes-1.5.6.3.txt
\ No newline at end of file
+Documentation/RelNotes-1.5.6.4.txt
\ No newline at end of file
diff --git a/attr.c b/attr.c
index 0fb47d34346ca96addde5cb3722fa5e586057285..17f6a4dca521d9690377f2e93a0192d8a874d2ad 100644 (file)
--- a/attr.c
+++ b/attr.c
@@ -459,7 +459,9 @@ static void prepare_attr_stack(const char *path, int dirlen)
 {
        struct attr_stack *elem, *info;
        int len;
-       char pathbuf[PATH_MAX];
+       struct strbuf pathbuf;
+
+       strbuf_init(&pathbuf, dirlen+2+strlen(GITATTRIBUTES_FILE));
 
        /*
         * At the bottom of the attribute stack is the built-in
@@ -510,13 +512,14 @@ static void prepare_attr_stack(const char *path, int dirlen)
                        len = strlen(attr_stack->origin);
                        if (dirlen <= len)
                                break;
-                       memcpy(pathbuf, path, dirlen);
-                       memcpy(pathbuf + dirlen, "/", 2);
-                       cp = strchr(pathbuf + len + 1, '/');
+                       strbuf_reset(&pathbuf);
+                       strbuf_add(&pathbuf, path, dirlen);
+                       strbuf_addch(&pathbuf, '/');
+                       cp = strchr(pathbuf.buf + len + 1, '/');
                        strcpy(cp + 1, GITATTRIBUTES_FILE);
-                       elem = read_attr(pathbuf, 0);
+                       elem = read_attr(pathbuf.buf, 0);
                        *cp = '\0';
-                       elem->origin = strdup(pathbuf);
+                       elem->origin = strdup(pathbuf.buf);
                        elem->prev = attr_stack;
                        attr_stack = elem;
                        debug_push(elem);
index de1e8d1365769c7c841749901f705c0b6a78eab3..6e98cafd08ca9fb09d4f860878691db9ec4999ba 100644 (file)
@@ -309,7 +309,8 @@ static int find_common(int fd[2], unsigned char *result_sha1,
                }
                flushes--;
        }
-       return retval;
+       /* it is no error to fetch into a completely empty repo */
+       return count ? retval : 0;
 }
 
 static struct commit_list *complete;
index ef299108f529fa5fa931d765828f04535c3a6351..647535061c350b68f1583fc12b049a37eb17481c 100644 (file)
@@ -427,33 +427,35 @@ static int grep_tree(struct grep_opt *opt, const char **paths,
        struct name_entry entry;
        char *down;
        int tn_len = strlen(tree_name);
-       char *path_buf = xmalloc(PATH_MAX + tn_len + 100);
+       struct strbuf pathbuf;
+
+       strbuf_init(&pathbuf, PATH_MAX + tn_len);
 
        if (tn_len) {
-               tn_len = sprintf(path_buf, "%s:", tree_name);
-               down = path_buf + tn_len;
-               strcat(down, base);
-       }
-       else {
-               down = path_buf;
-               strcpy(down, base);
+               strbuf_add(&pathbuf, tree_name, tn_len);
+               strbuf_addch(&pathbuf, ':');
+               tn_len = pathbuf.len;
        }
-       len = strlen(path_buf);
+       strbuf_addstr(&pathbuf, base);
+       len = pathbuf.len;
 
        while (tree_entry(tree, &entry)) {
-               strcpy(path_buf + len, entry.path);
+               int te_len = tree_entry_len(entry.path, entry.sha1);
+               pathbuf.len = len;
+               strbuf_add(&pathbuf, entry.path, te_len);
 
                if (S_ISDIR(entry.mode))
                        /* Match "abc/" against pathspec to
                         * decide if we want to descend into "abc"
                         * directory.
                         */
-                       strcpy(path_buf + len + tree_entry_len(entry.path, entry.sha1), "/");
+                       strbuf_addch(&pathbuf, '/');
 
+               down = pathbuf.buf + tn_len;
                if (!pathspec_matches(paths, down))
                        ;
                else if (S_ISREG(entry.mode))
-                       hit |= grep_sha1(opt, entry.sha1, path_buf, tn_len);
+                       hit |= grep_sha1(opt, entry.sha1, pathbuf.buf, tn_len);
                else if (S_ISDIR(entry.mode)) {
                        enum object_type type;
                        struct tree_desc sub;
@@ -469,6 +471,7 @@ static int grep_tree(struct grep_opt *opt, const char **paths,
                        free(data);
                }
        }
+       strbuf_release(&pathbuf);
        return hit;
 }
 
index 962aa34c8ea3f603abcbf7f8f94cf6914105cbef..13f0502b9e0bca9e4119896c01786b99cc54441e 100644 (file)
@@ -334,7 +334,9 @@ static int check_header(char *line, unsigned linesize, char **hdr_data, int over
                return 1;
        if (!memcmp("[PATCH]", line, 7) && isspace(line[7])) {
                for (i = 0; header[i]; i++) {
-                       if (!memcmp("Subject: ", header[i], 9)) {
+                       if (!memcmp("Subject", header[i], 7)) {
+                               if (!hdr_data[i])
+                                       hdr_data[i] = xmalloc(linesize + 20);
                                if (! handle_header(line, hdr_data[i], 0)) {
                                        return 1;
                                }
index 83a7b1349e06dbf1a355888272d9b13a7d4c22c4..39ec61c42858c0b1c5306025f0962b3ee3d7f910 100644 (file)
@@ -597,6 +597,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
        revs.commit_format = CMIT_FMT_UNSPECIFIED;
        argc = setup_revisions(argc, argv, &revs, NULL);
 
+       quiet = DIFF_OPT_TST(&revs.diffopt, QUIET);
        for (i = 1 ; i < argc; i++) {
                const char *arg = argv[i];
 
@@ -628,10 +629,6 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
                        read_revisions_from_stdin(&revs);
                        continue;
                }
-               if (!strcmp(arg, "--quiet")) {
-                       quiet = 1;
-                       continue;
-               }
                usage(rev_list_usage);
 
        }
index cff28a88afe3262705acc3d9b47e97be65dbb8d1..72f02f208fad95128d7e2fd3b55fdddd23bf2460 100755 (executable)
 #       git@vger.kernel.org
 #
 
+case "$COMP_WORDBREAKS" in
+*:*) : great ;;
+*)   COMP_WORDBREAKS="$COMP_WORDBREAKS:"
+esac
+
 __gitdir ()
 {
        if [ -z "$1" ]; then
@@ -114,9 +119,20 @@ __git_ps1 ()
        fi
 }
 
+__gitcomp_1 ()
+{
+       local c IFS=' '$'\t'$'\n'
+       for c in $1; do
+               case "$c$2" in
+               --*=*) printf %s$'\n' "$c$2" ;;
+               *.)    printf %s$'\n' "$c$2" ;;
+               *)     printf %s$'\n' "$c$2 " ;;
+               esac
+       done
+}
+
 __gitcomp ()
 {
-       local all c s=$'\n' IFS=' '$'\t'$'\n'
        local cur="${COMP_WORDS[COMP_CWORD]}"
        if [ $# -gt 2 ]; then
                cur="$3"
@@ -124,21 +140,14 @@ __gitcomp ()
        case "$cur" in
        --*=)
                COMPREPLY=()
-               return
                ;;
        *)
-               for c in $1; do
-                       case "$c$4" in
-                       --*=*) all="$all$c$4$s" ;;
-                       *.)    all="$all$c$4$s" ;;
-                       *)     all="$all$c$4 $s" ;;
-                       esac
-               done
+               local IFS=$'\n'
+               COMPREPLY=($(compgen -P "$2" \
+                       -W "$(__gitcomp_1 "$1" "$4")" \
+                       -- "$cur"))
                ;;
        esac
-       IFS=$s
-       COMPREPLY=($(compgen -P "$2" -W "$all" -- "$cur"))
-       return
 }
 
 __git_heads ()
@@ -290,9 +299,23 @@ __git_complete_file ()
                        ls="$ref"
                        ;;
            esac
+
+               case "$COMP_WORDBREAKS" in
+               *:*) : great ;;
+               *)   pfx="$ref:$pfx" ;;
+               esac
+
+               local IFS=$'\n'
                COMPREPLY=($(compgen -P "$pfx" \
                        -W "$(git --git-dir="$(__gitdir)" ls-tree "$ls" \
-                               | sed '/^100... blob /s,^.*     ,,
+                               | sed '/^100... blob /{
+                                          s,^.*        ,,
+                                          s,$, ,
+                                      }
+                                      /^120000 blob /{
+                                          s,^.*        ,,
+                                          s,$, ,
+                                      }
                                       /^040000 tree /{
                                           s,^.*        ,,
                                           s,$,/,
@@ -320,9 +343,6 @@ __git_complete_revlist ()
                cur="${cur#*..}"
                __gitcomp "$(__git_refs)" "$pfx" "$cur"
                ;;
-       *.)
-               __gitcomp "$cur."
-               ;;
        *)
                __gitcomp "$(__git_refs)"
                ;;
@@ -691,7 +711,12 @@ _git_fetch ()
        *)
                case "$cur" in
                *:*)
-                       __gitcomp "$(__git_refs)" "" "${cur#*:}"
+                       local pfx=""
+                       case "$COMP_WORDBREAKS" in
+                       *:*) : great ;;
+                       *)   pfx="${cur%%:*}:" ;;
+                       esac
+                       __gitcomp "$(__git_refs)" "$pfx" "${cur#*:}"
                        ;;
                *)
                        local remote
@@ -864,7 +889,14 @@ _git_push ()
                        git-push)  remote="${COMP_WORDS[1]}" ;;
                        git)       remote="${COMP_WORDS[2]}" ;;
                        esac
-                       __gitcomp "$(__git_refs "$remote")" "" "${cur#*:}"
+
+                       local pfx=""
+                       case "$COMP_WORDBREAKS" in
+                       *:*) : great ;;
+                       *)   pfx="${cur%%:*}:" ;;
+                       esac
+
+                       __gitcomp "$(__git_refs "$remote")" "$pfx" "${cur#*:}"
                        ;;
                +*)
                        __gitcomp "$(__git_refs)" + "${cur#+}"
index 63cd12cd9c1909edbaab49aea066ff6fe03c3542..ce3a6f58f3c5c6bb88617510422c4053e0d545a2 100644 (file)
--- a/daemon.c
+++ b/daemon.c
@@ -694,23 +694,47 @@ static void kill_some_children(int signo, unsigned start, unsigned stop)
        }
 }
 
+static void check_dead_children(void)
+{
+       unsigned spawned, reaped, deleted;
+
+       spawned = children_spawned;
+       reaped = children_reaped;
+       deleted = children_deleted;
+
+       while (deleted < reaped) {
+               pid_t pid = dead_child[deleted % MAX_CHILDREN];
+               const char *dead = pid < 0 ? " (with error)" : "";
+
+               if (pid < 0)
+                       pid = -pid;
+
+               /* XXX: Custom logging, since we don't wanna getpid() */
+               if (verbose) {
+                       if (log_syslog)
+                               syslog(LOG_INFO, "[%d] Disconnected%s",
+                                               pid, dead);
+                       else
+                               fprintf(stderr, "[%d] Disconnected%s\n",
+                                               pid, dead);
+               }
+               remove_child(pid, deleted, spawned);
+               deleted++;
+       }
+       children_deleted = deleted;
+}
+
 static void check_max_connections(void)
 {
        for (;;) {
                int active;
-               unsigned spawned, reaped, deleted;
+               unsigned spawned, deleted;
+
+               check_dead_children();
 
                spawned = children_spawned;
-               reaped = children_reaped;
                deleted = children_deleted;
 
-               while (deleted < reaped) {
-                       pid_t pid = dead_child[deleted % MAX_CHILDREN];
-                       remove_child(pid, deleted, spawned);
-                       deleted++;
-               }
-               children_deleted = deleted;
-
                active = spawned - deleted;
                if (active <= max_connections)
                        break;
@@ -760,18 +784,10 @@ static void child_handler(int signo)
 
                if (pid > 0) {
                        unsigned reaped = children_reaped;
+                       if (!WIFEXITED(status) || WEXITSTATUS(status) > 0)
+                               pid = -pid;
                        dead_child[reaped % MAX_CHILDREN] = pid;
                        children_reaped = reaped + 1;
-                       /* XXX: Custom logging, since we don't wanna getpid() */
-                       if (verbose) {
-                               const char *dead = "";
-                               if (!WIFEXITED(status) || WEXITSTATUS(status) > 0)
-                                       dead = " (with error)";
-                               if (log_syslog)
-                                       syslog(LOG_INFO, "[%d] Disconnected%s", pid, dead);
-                               else
-                                       fprintf(stderr, "[%d] Disconnected%s\n", pid, dead);
-                       }
                        continue;
                }
                break;
@@ -928,8 +944,18 @@ static int service_loop(int socknum, int *socklist)
 
        for (;;) {
                int i;
+               int timeout;
 
-               if (poll(pfd, socknum, -1) < 0) {
+               /*
+                * This 1-sec timeout could lead to idly looping but it is
+                * here so that children culled in child_handler() are reported
+                * without too much delay.  We could probably set up a pipe
+                * to ourselves that we poll, and write to the fd from child_handler()
+                * to wake us up (and consume it when the poll() returns...
+                */
+               timeout = (children_spawned != children_deleted) ? 1000 : -1;
+               i = poll(pfd, socknum, timeout);
+               if (i < 0) {
                        if (errno != EINTR) {
                                error("poll failed, resuming: %s",
                                      strerror(errno));
@@ -937,6 +963,10 @@ static int service_loop(int socknum, int *socklist)
                        }
                        continue;
                }
+               if (i == 0) {
+                       check_dead_children();
+                       continue;
+               }
 
                for (i = 0; i < socknum; i++) {
                        if (pfd[i].revents & POLLIN) {
index b17722d66a7008b822125bb96ab1b7921e8b627b..e7eaff9a68ccbcc692522c9956f0dae9af45f3f1 100644 (file)
@@ -171,7 +171,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
                        if (silent_on_removed)
                                continue;
                        diff_addremove(&revs->diffopt, '-', ce->ce_mode,
-                                      ce->sha1, ce->name, NULL);
+                                      ce->sha1, ce->name);
                        continue;
                }
                changed = ce_match_stat(ce, &st, ce_option);
@@ -184,7 +184,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
                newmode = ce_mode_from_stat(ce, st.st_mode);
                diff_change(&revs->diffopt, oldmode, newmode,
                            ce->sha1, (changed ? null_sha1 : ce->sha1),
-                           ce->name, NULL);
+                           ce->name);
 
        }
        diffcore_std(&revs->diffopt);
@@ -208,7 +208,7 @@ static void diff_index_show_file(struct rev_info *revs,
                                 const unsigned char *sha1, unsigned int mode)
 {
        diff_addremove(&revs->diffopt, prefix[0], mode,
-                      sha1, ce->name, NULL);
+                      sha1, ce->name);
 }
 
 static int get_stat_data(struct cache_entry *ce,
@@ -312,7 +312,7 @@ static int show_modified(struct oneway_unpack_data *cbdata,
                return 0;
 
        diff_change(&revs->diffopt, oldmode, mode,
-                   old->sha1, sha1, old->name, NULL);
+                   old->sha1, sha1, old->name);
        return 0;
 }
 
diff --git a/diff.c b/diff.c
index 78c4d3a35a975d0ffef51dbe999d14938d0a90e3..386de826d3a050e5dfce55636fc2e65129b6da2b 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -3356,9 +3356,8 @@ int diff_result_code(struct diff_options *opt, int status)
 void diff_addremove(struct diff_options *options,
                    int addremove, unsigned mode,
                    const unsigned char *sha1,
-                   const char *base, const char *path)
+                   const char *concatpath)
 {
-       char concatpath[PATH_MAX];
        struct diff_filespec *one, *two;
 
        if (DIFF_OPT_TST(options, IGNORE_SUBMODULES) && S_ISGITLINK(mode))
@@ -3380,9 +3379,6 @@ void diff_addremove(struct diff_options *options,
                addremove = (addremove == '+' ? '-' :
                             addremove == '-' ? '+' : addremove);
 
-       if (!path) path = "";
-       sprintf(concatpath, "%s%s", base, path);
-
        if (options->prefix &&
            strncmp(concatpath, options->prefix, options->prefix_length))
                return;
@@ -3403,9 +3399,8 @@ void diff_change(struct diff_options *options,
                 unsigned old_mode, unsigned new_mode,
                 const unsigned char *old_sha1,
                 const unsigned char *new_sha1,
-                const char *base, const char *path)
+                const char *concatpath)
 {
-       char concatpath[PATH_MAX];
        struct diff_filespec *one, *two;
 
        if (DIFF_OPT_TST(options, IGNORE_SUBMODULES) && S_ISGITLINK(old_mode)
@@ -3418,8 +3413,6 @@ void diff_change(struct diff_options *options,
                tmp = old_mode; old_mode = new_mode; new_mode = tmp;
                tmp_c = old_sha1; old_sha1 = new_sha1; new_sha1 = tmp_c;
        }
-       if (!path) path = "";
-       sprintf(concatpath, "%s%s", base, path);
 
        if (options->prefix &&
            strncmp(concatpath, options->prefix, options->prefix_length))
diff --git a/diff.h b/diff.h
index 5dc0cb595b64868ca8b8e26e5311d2df102c89e0..50fb5ddb0bec02b0cd5498d6ecc37d44bf874476 100644 (file)
--- a/diff.h
+++ b/diff.h
@@ -14,12 +14,12 @@ typedef void (*change_fn_t)(struct diff_options *options,
                 unsigned old_mode, unsigned new_mode,
                 const unsigned char *old_sha1,
                 const unsigned char *new_sha1,
-                const char *base, const char *path);
+                const char *fullpath);
 
 typedef void (*add_remove_fn_t)(struct diff_options *options,
                    int addremove, unsigned mode,
                    const unsigned char *sha1,
-                   const char *base, const char *path);
+                   const char *fullpath);
 
 typedef void (*diff_format_fn_t)(struct diff_queue_struct *q,
                struct diff_options *options, void *data);
@@ -164,14 +164,13 @@ extern void diff_addremove(struct diff_options *,
                           int addremove,
                           unsigned mode,
                           const unsigned char *sha1,
-                          const char *base,
-                          const char *path);
+                          const char *fullpath);
 
 extern void diff_change(struct diff_options *,
                        unsigned mode1, unsigned mode2,
                        const unsigned char *sha1,
                        const unsigned char *sha2,
-                       const char *base, const char *path);
+                       const char *fullpath);
 
 extern void diff_unmerge(struct diff_options *,
                         const char *path,
index 920bbe15a3bbc7768d47a2adbc84aa81264e2226..b00d1c29cd3a7d2cd8bbcd7ea4f531e050fcfcb9 100755 (executable)
@@ -1884,7 +1884,7 @@ sub req_annotate
     }
 
     # done; get out of the tempdir
-    cleanupWorkDir();
+    cleanupWorkTree();
 
     print "ok\n";
 
index a64d9d57ab5943ac4e065866ce0ccd7de5364a9a..e3f65bd8808112aebf98f554bd24df38a5e6408c 100755 (executable)
@@ -162,6 +162,8 @@ pick_one_preserving_merges () {
                                new_parents="$new_parents $new_p"
                                ;;
                        esac
+               else
+                       new_parents="$new_parents $p"
                fi
        done
        case $fast_forward in
index 99f397e32b673e289c2f9d298b1287a97cb7a49e..74033060c4e85b23a947ea5799d8ea96e6040da0 100644 (file)
@@ -442,6 +442,8 @@ static int setup_index(struct walker *walker, struct alt_base *repo, unsigned ch
                return -1;
 
        new_pack = parse_pack_index(sha1);
+       if (!new_pack)
+               return -1; /* parse_pack_index() already issued error message */
        new_pack->next = repo->packs;
        repo->packs = new_pack;
        return 0;
index 8eb39e915e730ff5039247695adc1e25c14773f4..628a5201c1e8aa3b985bf0b382e5511e17d953d4 100644 (file)
--- a/pretty.c
+++ b/pretty.c
@@ -3,6 +3,8 @@
 #include "utf8.h"
 #include "diff.h"
 #include "revision.h"
+#include "path-list.h"
+#include "mailmap.h"
 
 static char *user_format;
 
@@ -288,6 +290,25 @@ static char *logmsg_reencode(const struct commit *commit,
        return out;
 }
 
+static int mailmap_name(struct strbuf *sb, const char *email)
+{
+       static struct path_list *mail_map;
+       char buffer[1024];
+
+       if (!mail_map) {
+               mail_map = xcalloc(1, sizeof(*mail_map));
+               read_mailmap(mail_map, ".mailmap", NULL);
+       }
+
+       if (!mail_map->nr)
+               return -1;
+
+       if (!map_email(mail_map, email, buffer, sizeof(buffer)))
+               return -1;
+       strbuf_addstr(sb, buffer);
+       return 0;
+}
+
 static size_t format_person_part(struct strbuf *sb, char part,
                                const char *msg, int len)
 {
@@ -309,10 +330,12 @@ static size_t format_person_part(struct strbuf *sb, char part,
        if (end >= len - 2)
                goto skip;
 
-       if (part == 'n') {      /* name */
+       if (part == 'n' || part == 'N') {       /* name */
                while (end > 0 && isspace(msg[end - 1]))
                        end--;
-               strbuf_add(sb, msg, end);
+               if (part != 'N' || !msg[end] || !msg[end + 1] ||
+                   mailmap_name(sb, msg + end + 2) < 0)
+                       strbuf_add(sb, msg, end);
                return placeholder_len;
        }
        start = ++end; /* save email start position */
index fc667552592daa3c894d0df4e97469d1809dbf27..8dc3ca7bf696c14ad73f4ebe0fe845cba298c20e 100644 (file)
@@ -259,7 +259,7 @@ static int tree_difference = REV_TREE_SAME;
 static void file_add_remove(struct diff_options *options,
                    int addremove, unsigned mode,
                    const unsigned char *sha1,
-                   const char *base, const char *path)
+                   const char *fullpath)
 {
        int diff = REV_TREE_DIFFERENT;
 
@@ -285,7 +285,7 @@ static void file_change(struct diff_options *options,
                 unsigned old_mode, unsigned new_mode,
                 const unsigned char *old_sha1,
                 const unsigned char *new_sha1,
-                const char *base, const char *path)
+                const char *fullpath)
 {
        tree_difference = REV_TREE_DIFFERENT;
        DIFF_OPT_SET(options, HAS_CHANGES);
index d1c406081e29eab9843a5268b611af1a3e014227..10346b681e3575d17945f64513e2b0fecbcc01fc 100644 (file)
@@ -1609,6 +1609,7 @@ static void *unpack_delta_entry(struct packed_git *p,
        off_t base_offset;
 
        base_offset = get_delta_base(p, w_curs, &curpos, *type, obj_offset);
+       unuse_pack(w_curs);
        base = cache_or_unpack_entry(p, base_offset, &base_size, type, 0);
        if (!base)
                die("failed to read delta base object"
index 577ecc210a55a5da10552a4415c4cbb5e321039b..e9f3e72c7ee5584d956d46126956c641a7d53905 100755 (executable)
@@ -11,7 +11,7 @@ test_expect_success 'split sample box' \
        'git mailsplit -o. ../t5100/sample.mbox >last &&
        last=`cat last` &&
        echo total is $last &&
-       test `cat last` = 9'
+       test `cat last` = 10'
 
 for mail in `echo 00*`
 do
diff --git a/t/t5100/0010 b/t/t5100/0010
new file mode 100644 (file)
index 0000000..f5892c9
--- /dev/null
@@ -0,0 +1,35 @@
+From b9704a518e21158433baa2cc2d591fea687967f6 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Lukas=20Sandstr=C3=B6m?= <lukass@etek.chalmers.se>
+Date: Thu, 10 Jul 2008 23:41:33 +0200
+Subject: Re: discussion that lead to this patch
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+[PATCH] git-mailinfo: Fix getting the subject from the body
+
+"Subject: " isn't in the static array "header", and thus
+memcmp("Subject: ", header[i], 7) will never match.
+
+Signed-off-by: Lukas Sandström <lukass@etek.chalmers.se>
+Signed-off-by: Junio C Hamano <gitster@pobox.com>
+---
+ builtin-mailinfo.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
+index 962aa34..2d1520f 100644
+--- a/builtin-mailinfo.c
++++ b/builtin-mailinfo.c
+@@ -334,7 +334,7 @@ static int check_header(char *line, unsigned linesize, char **hdr_data, int over
+               return 1;
+       if (!memcmp("[PATCH]", line, 7) && isspace(line[7])) {
+               for (i = 0; header[i]; i++) {
+-                      if (!memcmp("Subject: ", header[i], 9)) {
++                      if (!memcmp("Subject", header[i], 7)) {
+                               if (! handle_header(line, hdr_data[i], 0)) {
+                                       return 1;
+                               }
+-- 
+1.5.6.2.455.g1efb2
+
diff --git a/t/t5100/info0010 b/t/t5100/info0010
new file mode 100644 (file)
index 0000000..1791241
--- /dev/null
@@ -0,0 +1,5 @@
+Author: Lukas Sandström
+Email: lukass@etek.chalmers.se
+Subject: git-mailinfo: Fix getting the subject from the body
+Date: Thu, 10 Jul 2008 23:41:33 +0200
+
diff --git a/t/t5100/msg0010 b/t/t5100/msg0010
new file mode 100644 (file)
index 0000000..a96c230
--- /dev/null
@@ -0,0 +1,5 @@
+"Subject: " isn't in the static array "header", and thus
+memcmp("Subject: ", header[i], 7) will never match.
+
+Signed-off-by: Lukas Sandström <lukass@etek.chalmers.se>
+Signed-off-by: Junio C Hamano <gitster@pobox.com>
diff --git a/t/t5100/patch0010 b/t/t5100/patch0010
new file mode 100644 (file)
index 0000000..f055481
--- /dev/null
@@ -0,0 +1,20 @@
+---
+ builtin-mailinfo.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
+index 962aa34..2d1520f 100644
+--- a/builtin-mailinfo.c
++++ b/builtin-mailinfo.c
+@@ -334,7 +334,7 @@ static int check_header(char *line, unsigned linesize, char **hdr_data, int over
+               return 1;
+       if (!memcmp("[PATCH]", line, 7) && isspace(line[7])) {
+               for (i = 0; header[i]; i++) {
+-                      if (!memcmp("Subject: ", header[i], 9)) {
++                      if (!memcmp("Subject", header[i], 7)) {
+                               if (! handle_header(line, hdr_data[i], 0)) {
+                                       return 1;
+                               }
+-- 
+1.5.6.2.455.g1efb2
+
index 0476b96c33de8bbc6c4b3bc4f510e9fc50aa6440..aba57f922b33b6ab708afbbf82c7e56f6e37bb8d 100644 (file)
@@ -430,3 +430,38 @@ index b426a14..97756ec 100644
 =20
 =20
  2. When the environment variable 'GIT_EXTERNAL_DIFF' is set, the
+From b9704a518e21158433baa2cc2d591fea687967f6 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Lukas=20Sandstr=C3=B6m?= <lukass@etek.chalmers.se>
+Date: Thu, 10 Jul 2008 23:41:33 +0200
+Subject: Re: discussion that lead to this patch
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+[PATCH] git-mailinfo: Fix getting the subject from the body
+
+"Subject: " isn't in the static array "header", and thus
+memcmp("Subject: ", header[i], 7) will never match.
+
+Signed-off-by: Lukas Sandström <lukass@etek.chalmers.se>
+Signed-off-by: Junio C Hamano <gitster@pobox.com>
+---
+ builtin-mailinfo.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
+index 962aa34..2d1520f 100644
+--- a/builtin-mailinfo.c
++++ b/builtin-mailinfo.c
+@@ -334,7 +334,7 @@ static int check_header(char *line, unsigned linesize, char **hdr_data, int over
+               return 1;
+       if (!memcmp("[PATCH]", line, 7) && isspace(line[7])) {
+               for (i = 0; header[i]; i++) {
+-                      if (!memcmp("Subject: ", header[i], 9)) {
++                      if (!memcmp("Subject", header[i], 7)) {
+                               if (! handle_header(line, hdr_data[i], 0)) {
+                                       return 1;
+                               }
+-- 
+1.5.6.2.455.g1efb2
+
index d21cd290d3d8e3d912b94045f3d3d9db8bdd7e7d..daf45b7ffa5bc80a4129a7f4b48dce36711d4c87 100755 (executable)
@@ -222,36 +222,12 @@ test_expect_success 'setup' '
 test_debug 'gitk --all'
 
 test_expect_success 'test option parsing' '
-       if git merge -$ c1
-       then
-               echo "[OOPS] -$ accepted"
-               false
-       fi &&
-       if git merge --no-such c1
-       then
-               echo "[OOPS] --no-such accepted"
-               false
-       fi &&
-       if git merge -s foobar c1
-       then
-               echo "[OOPS] -s foobar accepted"
-               false
-       fi &&
-       if git merge -s=foobar c1
-       then
-               echo "[OOPS] -s=foobar accepted"
-               false
-       fi &&
-       if git merge -m
-       then
-               echo "[OOPS] missing commit msg accepted"
-               false
-       fi &&
-       if git merge
-       then
-               echo "[OOPS] missing commit references accepted"
-               false
-       fi
+       test_must_fail git merge -$ c1 &&
+       test_must_fail git merge --no-such c1 &&
+       test_must_fail git merge -s foobar c1 &&
+       test_must_fail git merge -s=foobar c1 &&
+       test_must_fail git merge -m &&
+       test_must_fail git merge
 '
 
 test_expect_success 'merge c0 with c1' '
index e1e2e6c6ce3c4effffb26e9aed7c6bdd2b00a5ae..bbb126fc46cfb28a0bc92cc0842c0dc72017751d 100644 (file)
@@ -15,6 +15,15 @@ static char *malloc_base(const char *base, int baselen, const char *path, int pa
        return newbase;
 }
 
+static char *malloc_fullname(const char *base, int baselen, const char *path, int pathlen)
+{
+       char *fullname = xmalloc(baselen + pathlen + 1);
+       memcpy(fullname, base, baselen);
+       memcpy(fullname + baselen, path, pathlen);
+       fullname[baselen + pathlen] = 0;
+       return fullname;
+}
+
 static void show_entry(struct diff_options *opt, const char *prefix, struct tree_desc *desc,
                       const char *base, int baselen);
 
@@ -24,6 +33,7 @@ static int compare_tree_entry(struct tree_desc *t1, struct tree_desc *t2, const
        const char *path1, *path2;
        const unsigned char *sha1, *sha2;
        int cmp, pathlen1, pathlen2;
+       char *fullname;
 
        sha1 = tree_entry_extract(t1, &path1, &mode1);
        sha2 = tree_entry_extract(t2, &path2, &mode2);
@@ -55,15 +65,20 @@ static int compare_tree_entry(struct tree_desc *t1, struct tree_desc *t2, const
        if (DIFF_OPT_TST(opt, RECURSIVE) && S_ISDIR(mode1)) {
                int retval;
                char *newbase = malloc_base(base, baselen, path1, pathlen1);
-               if (DIFF_OPT_TST(opt, TREE_IN_RECURSIVE))
+               if (DIFF_OPT_TST(opt, TREE_IN_RECURSIVE)) {
+                       newbase[baselen + pathlen1] = 0;
                        opt->change(opt, mode1, mode2,
-                                   sha1, sha2, base, path1);
+                                   sha1, sha2, newbase);
+                       newbase[baselen + pathlen1] = '/';
+               }
                retval = diff_tree_sha1(sha1, sha2, newbase, opt);
                free(newbase);
                return retval;
        }
 
-       opt->change(opt, mode1, mode2, sha1, sha2, base, path1);
+       fullname = malloc_fullname(base, baselen, path1, pathlen1);
+       opt->change(opt, mode1, mode2, sha1, sha2, fullname);
+       free(fullname);
        return 0;
 }
 
@@ -205,10 +220,10 @@ static void show_entry(struct diff_options *opt, const char *prefix, struct tree
        unsigned mode;
        const char *path;
        const unsigned char *sha1 = tree_entry_extract(desc, &path, &mode);
+       int pathlen = tree_entry_len(path, sha1);
 
        if (DIFF_OPT_TST(opt, RECURSIVE) && S_ISDIR(mode)) {
                enum object_type type;
-               int pathlen = tree_entry_len(path, sha1);
                char *newbase = malloc_base(base, baselen, path, pathlen);
                struct tree_desc inner;
                void *tree;
@@ -224,7 +239,9 @@ static void show_entry(struct diff_options *opt, const char *prefix, struct tree
                free(tree);
                free(newbase);
        } else {
-               opt->add_remove(opt, prefix[0], mode, sha1, base, path);
+               char *fullname = malloc_fullname(base, baselen, path, pathlen);
+               opt->add_remove(opt, prefix[0], mode, sha1, fullname);
+               free(fullname);
        }
 }