Merge branch 'maint'
authorJunio C Hamano <gitster@pobox.com>
Mon, 11 Feb 2008 21:23:06 +0000 (13:23 -0800)
committerJunio C Hamano <gitster@pobox.com>
Mon, 11 Feb 2008 21:23:06 +0000 (13:23 -0800)
* maint: (35 commits)
config.c: guard config parser from value=NULL
builtin-log.c: guard config parser from value=NULL
imap-send.c: guard config parser from value=NULL
wt-status.c: guard config parser from value=NULL
setup.c: guard config parser from value=NULL
remote.c: guard config parser from value=NULL
merge-recursive.c: guard config parser from value=NULL
http.c: guard config parser from value=NULL
help.c: guard config parser from value=NULL
git.c: guard config parser from value=NULL
diff.c: guard config parser from value=NULL
convert.c: guard config parser from value=NULL
connect.c: guard config parser from value=NULL
builtin-tag.c: guard config parser from value=NULL
builtin-show-branch.c: guard config parser from value=NULL
builtin-reflog.c: guard config parser from value=NULL
builtin-log.c: guard config parser from value=NULL
builtin-config.c: guard config parser from value=NULL
builtin-commit.c: guard config parser from value=NULL
builtin-branch.c: guard config parser from value=NULL
...

34 files changed:
Documentation/config.txt
Documentation/git-branch.txt
Documentation/git-checkout.txt
Documentation/git-pull.txt
archive-tar.c
builtin-apply.c
builtin-branch.c
builtin-commit.c
builtin-config.c
builtin-gc.c
builtin-log.c
builtin-pack-objects.c
builtin-prune.c
builtin-reflog.c
builtin-show-branch.c
builtin-tag.c
cache.h
config.c
connect.c
convert.c
diff.c
git-bisect.sh
git-rebase--interactive.sh
git.c
help.c
http.c
imap-send.c
merge-recursive.c
remote.c
setup.c
t/t1300-repo-config.sh
t/t5304-prune.sh [new file with mode: 0644]
t/t6030-bisect-porcelain.sh
wt-status.c
index 3e10feb9fbbf44c634c32f30dd23a4534535190d..f9bdb164e054ec2d633baab3da69ddd47e14931f 100644 (file)
@@ -333,7 +333,7 @@ branch.autosetupmerge::
        so that linkgit:git-pull[1] will appropriately merge from that
        remote branch.  Note that even if this option is not set,
        this behavior can be chosen per-branch using the `--track`
-       and `--no-track` options.  This option defaults to false.
+       and `--no-track` options.  This option defaults to true.
 
 branch.<name>.remote::
        When in branch <name>, it tells `git fetch` which remote to fetch.
index f920c04cc01e1d8a8675876adcb747f91ed86f30..7e8874acaacbd6990ccaf66d5bddbff6e4c1e5ba 100644 (file)
@@ -34,11 +34,11 @@ Note that this will create the new branch, but it will not switch the
 working tree to it; use "git checkout <newbranch>" to switch to the
 new branch.
 
-When a local branch is started off a remote branch, git can setup the
+When a local branch is started off a remote branch, git sets up the
 branch so that linkgit:git-pull[1] will appropriately merge from that
-remote branch.  If this behavior is desired, it is possible to make it
-the default using the global `branch.autosetupmerge` configuration
-flag.  Otherwise, it can be chosen per-branch using the `--track`
+remote branch.  If this behavior is not desired, it is possible to
+disable it using the global `branch.autosetupmerge` configuration
+flag.  That setting can be overridden by using the `--track`
 and `--no-track` options.
 
 With a '-m' or '-M' option, <oldbranch> will be renamed to <newbranch>.
@@ -108,10 +108,11 @@ OPTIONS
        Set up configuration so that git-pull will automatically
        retrieve data from the remote branch.  Use this if you always
        pull from the same remote branch into the new branch, or if you
-       don't want to use "git pull <repository> <refspec>" explicitly.  Set the
-       branch.autosetupmerge configuration variable to true if you
+       don't want to use "git pull <repository> <refspec>" explicitly.
+       This behavior is the default.  Set the
+       branch.autosetupmerge configuration variable to false if you
        want git-checkout and git-branch to always behave as if
-       '--track' were given.
+       '--no-track' were given.
 
 --no-track::
        When a branch is created off a remote branch,
index 584359ff3fdc4167b4af404ab92d34d3a057033c..b4cfa044bbb969add6f434070a8666fc0c325d15 100644 (file)
@@ -52,10 +52,11 @@ OPTIONS
        set up configuration so that git-pull will automatically
        retrieve data from the remote branch.  Use this if you always
        pull from the same remote branch into the new branch, or if you
-       don't want to use "git pull <repository> <refspec>" explicitly.  Set the
-       branch.autosetupmerge configuration variable to true if you
+       don't want to use "git pull <repository> <refspec>" explicitly.
+       This behavior is the default.  Set the
+       branch.autosetupmerge configuration variable to false if you
        want git-checkout and git-branch to always behave as if
-       '--track' were given.
+       '--no-track' were given.
 
 --no-track::
        When -b is given and a branch is created off a remote branch,
index 4cc633a5ec4c449e98ac9cb16fd125da6d336798..179bdfc69ddfeff9d272ec309721e4098f3b051e 100644 (file)
@@ -39,11 +39,11 @@ include::merge-strategies.txt[]
        there is a remote ref for the upstream branch, and this branch
        was rebased since last fetched, the rebase uses that information
        to avoid rebasing non-local changes.
-
-       *NOTE:* This is a potentially _dangerous_ mode of operation.
-       It rewrites history, which does not bode well when you
-       published that history already.  Do *not* use this option
-       unless you have read linkgit:git-rebase[1] carefully.
++
+*NOTE:* This is a potentially _dangerous_ mode of operation.
+It rewrites history, which does not bode well when you
+published that history already.  Do *not* use this option
+unless you have read linkgit:git-rebase[1] carefully.
 
 \--no-rebase::
        Override earlier \--rebase.
index e1bced56093dc08bbc260736637af3356b8598bb..30aa2e23fdbb1630dffb27db4509bc529bbd884a 100644 (file)
@@ -222,7 +222,7 @@ static void write_global_extended_header(const unsigned char *sha1)
 static int git_tar_config(const char *var, const char *value)
 {
        if (!strcmp(var, "tar.umask")) {
-               if (!strcmp(value, "user")) {
+               if (value && !strcmp(value, "user")) {
                        tar_umask = umask(0);
                        umask(tar_umask);
                } else {
index 15432b6782400b556333ee4117c7daaff20412ab..a11b1bbeee9568adbf8a3e32f77d14b132985061 100644 (file)
@@ -2746,6 +2746,8 @@ static int apply_patch(int fd, const char *filename, int inaccurate_eof)
 static int git_apply_config(const char *var, const char *value)
 {
        if (!strcmp(var, "apply.whitespace")) {
+               if (!value)
+                       return config_error_nonbool(var);
                apply_default_whitespace = xstrdup(value);
                return 0;
        }
index 089cae59299659b20359b7249e57ddc3a43ded06..e414c8898317736d632064d6c0545d7d128c6bc8 100644 (file)
@@ -70,12 +70,15 @@ static int git_branch_config(const char *var, const char *value)
        }
        if (!prefixcmp(var, "color.branch.")) {
                int slot = parse_branch_color_slot(var, 13);
+               if (!value)
+                       return config_error_nonbool(var);
                color_parse(value, var, branch_colors[slot]);
                return 0;
        }
-       if (!strcmp(var, "branch.autosetupmerge"))
-                       branch_track = git_config_bool(var, value);
-
+       if (!strcmp(var, "branch.autosetupmerge")) {
+               branch_track = git_config_bool(var, value);
+               return 0;
+       }
        return git_default_config(var, value);
 }
 
index c787bed696591f58d1336a701e57414c9d5c8cbf..a43f2019959a950639f013ff534610e228d8c149 100644 (file)
@@ -743,6 +743,8 @@ static void print_summary(const char *prefix, const unsigned char *sha1)
 int git_commit_config(const char *k, const char *v)
 {
        if (!strcmp(k, "commit.template")) {
+               if (!v)
+                       return config_error_nonbool(v);
                template_file = xstrdup(v);
                return 0;
        }
@@ -929,6 +931,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
 
        unlink(git_path("MERGE_HEAD"));
        unlink(git_path("MERGE_MSG"));
+       unlink(git_path("SQUASH_MSG"));
 
        if (commit_index_files())
                die ("Repository has been updated, but unable to write\n"
index e4a12e316648e6b0ab1ee0b424773f3c672c751e..077d8ef2df4ae38d668293cc35810b39e0488f6b 100644 (file)
@@ -168,6 +168,8 @@ static char parsed_color[COLOR_MAXLEN];
 static int git_get_color_config(const char *var, const char *value)
 {
        if (!strcmp(var, get_color_slot)) {
+               if (!value)
+                       config_error_nonbool(var);
                color_parse(value, var, parsed_color);
                get_color_found = 1;
        }
index ac34788c89c315d036ab041afbac91a0302e6d6a..ad4a75eedddb1dfc0ecef2b536727970335673f9 100644 (file)
@@ -37,7 +37,7 @@ static const char *argv_rerere[] = {"rerere", "gc", NULL};
 static int gc_config(const char *var, const char *value)
 {
        if (!strcmp(var, "gc.packrefs")) {
-               if (!strcmp(value, "notbare"))
+               if (value && !strcmp(value, "notbare"))
                        pack_refs = -1;
                else
                        pack_refs = git_config_bool(var, value);
index dcc9f817930a3caf8d434dfd54fe476501bcdda2..99d69f079132ed67e2d5bc83bf95e6e60ba22f6f 100644 (file)
@@ -219,7 +219,7 @@ static int git_log_config(const char *var, const char *value)
 {
        if (!strcmp(var, "format.subjectprefix")) {
                if (!value)
-                       die("format.subjectprefix without value");
+                       config_error_nonbool(var);
                fmt_patch_subject_prefix = xstrdup(value);
                return 0;
        }
@@ -432,7 +432,7 @@ static int git_format_config(const char *var, const char *value)
        }
        if (!strcmp(var, "format.suffix")) {
                if (!value)
-                       die("format.suffix without value");
+                       return config_error_nonbool(var);
                fmt_patch_suffix = xstrdup(value);
                return 0;
        }
@@ -440,11 +440,10 @@ static int git_format_config(const char *var, const char *value)
                return 0;
        }
        if (!strcmp(var, "format.numbered")) {
-               if (!strcasecmp(value, "auto")) {
+               if (value && !strcasecmp(value, "auto")) {
                        auto_number = 1;
                        return 0;
                }
-
                numbered = git_config_bool(var, value);
                return 0;
        }
index 692a76126b027133fd046f03003fe8e49218f192..acb05554d499598677bc1f0cec3b6ff37e796d88 100644 (file)
@@ -1464,7 +1464,7 @@ static unsigned int check_delta_limit(struct object_entry *me, unsigned int n)
        return m;
 }
 
-static unsigned long free_unpacked(struct unpacked *n)
+static unsigned long free_unpacked_data(struct unpacked *n)
 {
        unsigned long freed_mem = sizeof_delta_index(n->index);
        free_delta_index(n->index);
@@ -1474,6 +1474,12 @@ static unsigned long free_unpacked(struct unpacked *n)
                free(n->data);
                n->data = NULL;
        }
+       return freed_mem;
+}
+
+static unsigned long free_unpacked(struct unpacked *n)
+{
+       unsigned long freed_mem = free_unpacked_data(n);
        n->entry = NULL;
        n->depth = 0;
        return freed_mem;
@@ -1514,7 +1520,7 @@ static void find_deltas(struct object_entry **list, unsigned *list_size,
                       mem_usage > window_memory_limit &&
                       count > 1) {
                        uint32_t tail = (idx + window - count) % window;
-                       mem_usage -= free_unpacked(array + tail);
+                       mem_usage -= free_unpacked_data(array + tail);
                        count--;
                }
 
@@ -1547,6 +1553,9 @@ static void find_deltas(struct object_entry **list, unsigned *list_size,
                        if (!m->entry)
                                break;
                        ret = try_delta(n, m, max_depth, &mem_usage);
+                       if (window_memory_limit &&
+                           mem_usage > window_memory_limit)
+                               mem_usage -= free_unpacked_data(m);
                        if (ret < 0)
                                break;
                        else if (ret > 0)
index b5e768421ba548efaf0dd62ca876c15911df55d2..bb8ead92cf41c3cbdbc421a1490fb40ce19f11c3 100644 (file)
@@ -83,6 +83,44 @@ static void prune_object_dir(const char *path)
        }
 }
 
+/*
+ * Write errors (particularly out of space) can result in
+ * failed temporary packs (and more rarely indexes and other
+ * files begining with "tmp_") accumulating in the
+ * object directory.
+ */
+static void remove_temporary_files(void)
+{
+       DIR *dir;
+       struct dirent *de;
+       char* dirname=get_object_directory();
+
+       dir = opendir(dirname);
+       if (!dir) {
+               fprintf(stderr, "Unable to open object directory %s\n",
+                       dirname);
+               return;
+       }
+       while ((de = readdir(dir)) != NULL) {
+               if (!prefixcmp(de->d_name, "tmp_")) {
+                       char name[PATH_MAX];
+                       int c = snprintf(name, PATH_MAX, "%s/%s",
+                                        dirname, de->d_name);
+                       if (c < 0 || c >= PATH_MAX)
+                               continue;
+                       if (expire) {
+                               struct stat st;
+                               if (stat(name, &st) != 0 || st.st_mtime >= expire)
+                                       continue;
+                       }
+                       printf("Removing stale temporary file %s\n", name);
+                       if (!show_only)
+                               unlink(name);
+               }
+       }
+       closedir(dir);
+}
+
 int cmd_prune(int argc, const char **argv, const char *prefix)
 {
        int i;
@@ -115,5 +153,6 @@ int cmd_prune(int argc, const char **argv, const char *prefix)
 
        sync();
        prune_packed_objects(show_only);
+       remove_temporary_files();
        return 0;
 }
index e6834dd831e59b9a076305b0b7088ecdc9a2b3f1..4836ec951be727512bcd550dd3604c43c39aa557 100644 (file)
@@ -307,13 +307,19 @@ static int collect_reflog(const char *ref, const unsigned char *sha1, int unused
 
 static int reflog_expire_config(const char *var, const char *value)
 {
-       if (!strcmp(var, "gc.reflogexpire"))
+       if (!strcmp(var, "gc.reflogexpire")) {
+               if (!value)
+                       config_error_nonbool(var);
                default_reflog_expire = approxidate(value);
-       else if (!strcmp(var, "gc.reflogexpireunreachable"))
+               return 0;
+       }
+       if (!strcmp(var, "gc.reflogexpireunreachable")) {
+               if (!value)
+                       config_error_nonbool(var);
                default_reflog_expire_unreachable = approxidate(value);
-       else
-               return git_default_config(var, value);
-       return 0;
+               return 0;
+       }
+       return git_default_config(var, value);
 }
 
 static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
index 6dc835d30a6a726c3dd40d23564b0dc32d20b7db..019abd3527e7c573c69900a58313749e2ef2280a 100644 (file)
@@ -536,6 +536,8 @@ static void append_one_rev(const char *av)
 static int git_show_branch_config(const char *var, const char *value)
 {
        if (!strcmp(var, "showbranch.default")) {
+               if (!value)
+                       return config_error_nonbool(var);
                if (default_alloc <= default_num + 1) {
                        default_alloc = default_alloc * 3 / 2 + 20;
                        default_arg = xrealloc(default_arg, sizeof *default_arg * default_alloc);
index 03e70155fc676a8dd38ca5cef800ed4a446e921a..4a4a88c10b4b2f9e55662bd4c1c17051ae7e6aac 100644 (file)
@@ -258,7 +258,7 @@ static int git_tag_config(const char *var, const char *value)
 {
        if (!strcmp(var, "user.signingkey")) {
                if (!value)
-                       die("user.signingkey without value");
+                       return config_error_nonbool(value);
                set_signingkey(value);
                return 0;
        }
diff --git a/cache.h b/cache.h
index 549f4bbac7242714283e58dd576460ca86015d52..6abcee437238ccc2b46e7d7d74f79db3a4b682a1 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -589,6 +589,7 @@ extern int git_config_set_multivar(const char *, const char *, const char *, int
 extern int git_config_rename_section(const char *, const char *);
 extern const char *git_etc_gitconfig(void);
 extern int check_repository_format_version(const char *var, const char *value);
+extern int config_error_nonbool(const char *);
 
 #define MAX_GITNAME (1000)
 extern char git_default_email[MAX_GITNAME];
index 498259ebefb3ba61a75aa5a5ca03d75576a501c0..3e72778e94267044780a180145eae0a6a229e3a3 100644 (file)
--- a/config.c
+++ b/config.c
@@ -408,21 +408,29 @@ int git_default_config(const char *var, const char *value)
        }
 
        if (!strcmp(var, "user.name")) {
+               if (!value)
+                       return config_error_nonbool(var);
                strlcpy(git_default_name, value, sizeof(git_default_name));
                return 0;
        }
 
        if (!strcmp(var, "user.email")) {
+               if (!value)
+                       return config_error_nonbool(var);
                strlcpy(git_default_email, value, sizeof(git_default_email));
                return 0;
        }
 
        if (!strcmp(var, "i18n.commitencoding")) {
+               if (!value)
+                       return config_error_nonbool(var);
                git_commit_encoding = xstrdup(value);
                return 0;
        }
 
        if (!strcmp(var, "i18n.logoutputencoding")) {
+               if (!value)
+                       return config_error_nonbool(var);
                git_log_output_encoding = xstrdup(value);
                return 0;
        }
@@ -434,23 +442,29 @@ int git_default_config(const char *var, const char *value)
        }
 
        if (!strcmp(var, "core.pager")) {
+               if (!value)
+                       return config_error_nonbool(var);
                pager_program = xstrdup(value);
                return 0;
        }
 
        if (!strcmp(var, "core.editor")) {
+               if (!value)
+                       return config_error_nonbool(var);
                editor_program = xstrdup(value);
                return 0;
        }
 
        if (!strcmp(var, "core.excludesfile")) {
                if (!value)
-                       die("core.excludesfile without value");
+                       return config_error_nonbool(var);
                excludes_file = xstrdup(value);
                return 0;
        }
 
        if (!strcmp(var, "core.whitespace")) {
+               if (!value)
+                       return config_error_nonbool(var);
                whitespace_rule_cfg = parse_whitespace_rule(value);
                return 0;
        }
@@ -701,12 +715,17 @@ static ssize_t find_beginning_of_line(const char* contents, size_t size,
        size_t equal_offset = size, bracket_offset = size;
        ssize_t offset;
 
+contline:
        for (offset = offset_-2; offset > 0
                        && contents[offset] != '\n'; offset--)
                switch (contents[offset]) {
                        case '=': equal_offset = offset; break;
                        case ']': bracket_offset = offset; break;
                }
+       if (offset > 0 && contents[offset-1] == '\\') {
+               offset_ = offset;
+               goto contline;
+       }
        if (bracket_offset < equal_offset) {
                *found_bracket = 1;
                offset = bracket_offset+1;
@@ -1074,3 +1093,12 @@ int git_config_rename_section(const char *old_name, const char *new_name)
        free(config_filename);
        return ret;
 }
+
+/*
+ * Call this to report error for your variable that should not
+ * get a boolean value (i.e. "[my] var" means "true").
+ */
+int config_error_nonbool(const char *var)
+{
+       return error("Missing value for '%s'", var);
+}
index 3aefd4ace590082b85bd3c4b9b41b8d1f1c72268..71597d4920ff11ed474be1a8bd39b4791611e422 100644 (file)
--- a/connect.c
+++ b/connect.c
@@ -370,6 +370,8 @@ static int git_proxy_command_options(const char *var, const char *value)
 
                if (git_proxy_command)
                        return 0;
+               if (!value)
+                       return config_error_nonbool(var);
                /* [core]
                 * ;# matches www.kernel.org as well
                 * gitproxy = netcatter-1 for kernel.org
index 80f114b2e2d169eef2a046d112d7e8729f2c1880..552707e8e65997ebfc2120887783c4fc5698e19f 100644 (file)
--- a/convert.c
+++ b/convert.c
@@ -326,14 +326,14 @@ static int read_convert_config(const char *var, const char *value)
 
        if (!strcmp("smudge", ep)) {
                if (!value)
-                       return error("%s: lacks value", var);
+                       return config_error_nonbool(var);
                drv->smudge = strdup(value);
                return 0;
        }
 
        if (!strcmp("clean", ep)) {
                if (!value)
-                       return error("%s: lacks value", var);
+                       return config_error_nonbool(var);
                drv->clean = strdup(value);
                return 0;
        }
diff --git a/diff.c b/diff.c
index 5b8afdcb05abd4f634b49adb2f521fc75e220647..4d2e23ae1b7dd4bd43d5c03871ce8ab519272115 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -158,6 +158,8 @@ int git_diff_ui_config(const char *var, const char *value)
                return 0;
        }
        if (!strcmp(var, "diff.external")) {
+               if (!value)
+                       return config_error_nonbool(var);
                external_diff_cmd_cfg = xstrdup(value);
                return 0;
        }
@@ -165,8 +167,11 @@ int git_diff_ui_config(const char *var, const char *value)
                const char *ep = strrchr(var, '.');
 
                if (ep != var + 4) {
-                       if (!strcmp(ep, ".command"))
+                       if (!strcmp(ep, ".command")) {
+                               if (!value)
+                                       return config_error_nonbool(var);
                                return parse_lldiff_command(var, ep, value);
+                       }
                }
        }
 
@@ -177,6 +182,8 @@ int git_diff_basic_config(const char *var, const char *value)
 {
        if (!prefixcmp(var, "diff.color.") || !prefixcmp(var, "color.diff.")) {
                int slot = parse_diff_color_slot(var, 11);
+               if (!value)
+                       return config_error_nonbool(var);
                color_parse(value, var, diff_colors[slot]);
                return 0;
        }
@@ -184,8 +191,11 @@ int git_diff_basic_config(const char *var, const char *value)
        if (!prefixcmp(var, "diff.")) {
                const char *ep = strrchr(var, '.');
                if (ep != var + 4) {
-                       if (!strcmp(ep, ".funcname"))
+                       if (!strcmp(ep, ".funcname")) {
+                               if (!value)
+                                       return config_error_nonbool(var);
                                return parse_funcname_pattern(var, ep, value);
+                       }
                }
        }
 
index 5385249890698632dedcaf8dda03d865f66abca9..393fa355849f88d6c5227f90cbf6cbb45b39631e 100755 (executable)
@@ -26,6 +26,9 @@ OPTIONS_SPEC=
 . git-sh-setup
 require_work_tree
 
+_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
+_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
+
 sq() {
        @@PERL@@ -e '
                for (@ARGV) {
@@ -60,7 +63,8 @@ bisect_start() {
        # top-of-line master first!
        #
        head=$(GIT_DIR="$GIT_DIR" git symbolic-ref HEAD) ||
-       die "Bad HEAD - I need a symbolic ref"
+       head=$(GIT_DIR="$GIT_DIR" git rev-parse --verify HEAD) ||
+       die "Bad HEAD - I need a HEAD"
        case "$head" in
        refs/heads/bisect)
                if [ -s "$GIT_DIR/head-name" ]; then
@@ -70,7 +74,7 @@ bisect_start() {
                fi
                git checkout $branch || exit
                ;;
-       refs/heads/*)
+       refs/heads/*|$_x40)
                [ -s "$GIT_DIR/head-name" ] && die "won't bisect on seeked tree"
                echo "${head#refs/heads/}" >"$GIT_DIR/head-name"
                ;;
index 402ff3782c0aaa472a2013ff3a9bef44a6cd8550..fb12b03b201836bb4c3b43a5d1120b3305d1ccf0 100755 (executable)
@@ -432,7 +432,7 @@ do
                        shift ;;
                esac
                ;;
-       --merge)
+       -m|--merge)
                # we use merge anyway
                ;;
        -C*)
diff --git a/git.c b/git.c
index 15fec8974ad5361a2308b3c46424e896bc8e3246..0cb86884d738a8314f164c82e4cc619a9998f3db 100644 (file)
--- a/git.c
+++ b/git.c
@@ -93,6 +93,8 @@ static char *alias_string;
 static int git_alias_config(const char *var, const char *value)
 {
        if (!prefixcmp(var, "alias.") && !strcmp(var + 6, alias_command)) {
+               if (!value)
+                       return config_error_nonbool(var);
                alias_string = xstrdup(value);
        }
        return 0;
diff --git a/help.c b/help.c
index 1302a61c83c524099e7d39257daa273a09edad4f..95e7640fedebb1574a4259d85d7b95d5220f0e6f 100644 (file)
--- a/help.c
+++ b/help.c
@@ -40,6 +40,8 @@ static void parse_help_format(const char *format)
 static int git_help_config(const char *var, const char *value)
 {
        if (!strcmp(var, "help.format")) {
+               if (!value)
+                       return config_error_nonbool(var);
                help_default_format = xstrdup(value);
                return 0;
        }
diff --git a/http.c b/http.c
index d2c11aee9077e0834c5c56b1284df478eb8debbc..5925d07478b763ee9f91d7b273f64f0ae956219b 100644 (file)
--- a/http.c
+++ b/http.c
@@ -101,16 +101,18 @@ static int http_options(const char *var, const char *value)
 
        if (!strcmp("http.sslcert", var)) {
                if (ssl_cert == NULL) {
-                       ssl_cert = xmalloc(strlen(value)+1);
-                       strcpy(ssl_cert, value);
+                       if (!value)
+                               return config_error_nonbool(var);
+                       ssl_cert = xstrdup(value);
                }
                return 0;
        }
 #if LIBCURL_VERSION_NUM >= 0x070902
        if (!strcmp("http.sslkey", var)) {
                if (ssl_key == NULL) {
-                       ssl_key = xmalloc(strlen(value)+1);
-                       strcpy(ssl_key, value);
+                       if (!value)
+                               return config_error_nonbool(var);
+                       ssl_key = xstrdup(value);
                }
                return 0;
        }
@@ -118,16 +120,18 @@ static int http_options(const char *var, const char *value)
 #if LIBCURL_VERSION_NUM >= 0x070908
        if (!strcmp("http.sslcapath", var)) {
                if (ssl_capath == NULL) {
-                       ssl_capath = xmalloc(strlen(value)+1);
-                       strcpy(ssl_capath, value);
+                       if (!value)
+                               return config_error_nonbool(var);
+                       ssl_capath = xstrdup(value);
                }
                return 0;
        }
 #endif
        if (!strcmp("http.sslcainfo", var)) {
                if (ssl_cainfo == NULL) {
-                       ssl_cainfo = xmalloc(strlen(value)+1);
-                       strcpy(ssl_cainfo, value);
+                       if (!value)
+                               return config_error_nonbool(var);
+                       ssl_cainfo = xstrdup(value);
                }
                return 0;
        }
@@ -157,8 +161,9 @@ static int http_options(const char *var, const char *value)
        }
        if (!strcmp("http.proxy", var)) {
                if (curl_http_proxy == NULL) {
-                       curl_http_proxy = xmalloc(strlen(value)+1);
-                       strcpy(curl_http_proxy, value);
+                       if (!value)
+                               return config_error_nonbool(var);
+                       curl_http_proxy = xstrdup(value);
                }
                return 0;
        }
index a429a76a6385bb7d7935cfaddec9cfc8508c77e5..9025d9aa3ef37b1a1ce4ae5d4b447e3b0918cb7e 100644 (file)
@@ -1254,6 +1254,10 @@ git_imap_config(const char *key, const char *val)
 
        if (strncmp( key, imap_key, sizeof imap_key - 1 ))
                return 0;
+
+       if (!val)
+               return config_error_nonbool(key);
+
        key += sizeof imap_key - 1;
 
        if (!strcmp( "folder", key )) {
index c292a77a81d137a3ee73111162c9aa515c975d70..34e3167cafc3d09e1a2b32bc9a5c64b4de1e442d 100644 (file)
@@ -844,8 +844,9 @@ static int read_merge_config(const char *var, const char *value)
        int namelen;
 
        if (!strcmp(var, "merge.default")) {
-               if (value)
-                       default_ll_merge = strdup(value);
+               if (!value)
+                       return config_error_nonbool(var);
+               default_ll_merge = strdup(value);
                return 0;
        }
 
@@ -878,14 +879,14 @@ static int read_merge_config(const char *var, const char *value)
 
        if (!strcmp("name", ep)) {
                if (!value)
-                       return error("%s: lacks value", var);
+                       return config_error_nonbool(var);
                fn->description = strdup(value);
                return 0;
        }
 
        if (!strcmp("driver", ep)) {
                if (!value)
-                       return error("%s: lacks value", var);
+                       return config_error_nonbool(var);
                /*
                 * merge.<name>.driver specifies the command line:
                 *
@@ -908,7 +909,7 @@ static int read_merge_config(const char *var, const char *value)
 
        if (!strcmp("recursive", ep)) {
                if (!value)
-                       return error("%s: lacks value", var);
+                       return config_error_nonbool(var);
                fn->recursive = strdup(value);
                return 0;
        }
index 0e006804ef3cc190fa286c85e2de034a33791886..20abbc07acb2e48aefb2129683b5dc159661211e 100644 (file)
--- a/remote.c
+++ b/remote.c
@@ -222,15 +222,18 @@ static int handle_config(const char *key, const char *value)
                subkey = strrchr(name, '.');
                if (!subkey)
                        return 0;
-               if (!value)
-                       return 0;
                branch = make_branch(name, subkey - name);
                if (!strcmp(subkey, ".remote")) {
+                       if (!value)
+                               return config_error_nonbool(key);
                        branch->remote_name = xstrdup(value);
                        if (branch == current_branch)
                                default_remote_name = branch->remote_name;
-               } else if (!strcmp(subkey, ".merge"))
+               } else if (!strcmp(subkey, ".merge")) {
+                       if (!value)
+                               return config_error_nonbool(key);
                        add_merge(branch, xstrdup(value));
+               }
                return 0;
        }
        if (prefixcmp(key,  "remote."))
diff --git a/setup.c b/setup.c
index adede16a4deea1423f52c3b736de735d27f7172a..4509598d577baba8b1d7e8782d8e6ff8e74f9556 100644 (file)
--- a/setup.c
+++ b/setup.c
@@ -372,6 +372,8 @@ int check_repository_format_version(const char *var, const char *value)
                if (is_bare_repository_cfg == 1)
                        inside_work_tree = -1;
        } else if (strcmp(var, "core.worktree") == 0) {
+               if (!value)
+                       return config_error_nonbool(var);
                if (git_work_tree_cfg)
                        free(git_work_tree_cfg);
                git_work_tree_cfg = xstrdup(value);
index 66aeb88db8f809cec4fd2916e6dbf86979b4598a..4928a571144b3fb9ec38312d917e9f95e40ceb99 100755 (executable)
@@ -71,6 +71,25 @@ EOF
 
 test_expect_success 'non-match result' 'cmp .git/config expect'
 
+cat > .git/config <<\EOF
+[alpha]
+bar = foo
+[beta]
+baz = multiple \
+lines
+EOF
+
+test_expect_success 'unset with cont. lines' \
+       'git config --unset beta.baz'
+
+cat > expect <<\EOF
+[alpha]
+bar = foo
+[beta]
+EOF
+
+test_expect_success 'unset with cont. lines is correct' 'cmp .git/config expect'
+
 cat > .git/config << EOF
 [beta] ; silly comment # another comment
 noIndent= sillyValue ; 'nother silly comment
diff --git a/t/t5304-prune.sh b/t/t5304-prune.sh
new file mode 100644 (file)
index 0000000..6560af7
--- /dev/null
@@ -0,0 +1,32 @@
+#!/bin/sh
+#
+# Copyright (c) 2008 Johannes E. Schindelin
+#
+
+test_description='prune'
+. ./test-lib.sh
+
+test_expect_success setup '
+
+       : > file &&
+       git add file &&
+       test_tick &&
+       git commit -m initial &&
+       git gc
+
+'
+
+test_expect_success 'prune stale packs' '
+
+       orig_pack=$(echo .git/objects/pack/*.pack) &&
+       : > .git/objects/tmp_1.pack &&
+       : > .git/objects/tmp_2.pack &&
+       test-chmtime -86501 .git/objects/tmp_1.pack &&
+       git prune --expire 1.day &&
+       test -f $orig_pack &&
+       test -f .git/objects/tmp_2.pack &&
+       ! test -f .git/objects/tmp_1.pack
+
+'
+
+test_done
index 2ba4b00e526eb00c5d236777f896772c6cad538b..ec71123f4be187c1399c90dc806dbae53cda5b7f 100755 (executable)
@@ -254,6 +254,18 @@ test_expect_success 'bisect run & skip: find first bad' '
        grep "$HASH6 is first bad commit" my_bisect_log.txt
 '
 
+test_expect_success 'bisect starting with a detached HEAD' '
+
+       git bisect reset &&
+       git checkout master^ &&
+       HEAD=$(git rev-parse --verify HEAD) &&
+       git bisect start &&
+       test $HEAD = $(cat .git/head-name) &&
+       git bisect reset &&
+       test $HEAD = $(git rev-parse --verify HEAD)
+
+'
+
 #
 #
 test_done
index c0c247243b562a7579ff780b80dffef4774b60a9..bfd1b0fcc612a827adc7416626895b89e8504d90 100644 (file)
@@ -402,6 +402,8 @@ int git_status_config(const char *k, const char *v)
        }
        if (!prefixcmp(k, "status.color.") || !prefixcmp(k, "color.status.")) {
                int slot = parse_status_slot(k, 13);
+               if (!v)
+                       return config_error_nonbool(k);
                color_parse(v, k, wt_status_colors[slot]);
                return 0;
        }