Merge branch 'maint'
authorJunio C Hamano <gitster@pobox.com>
Sat, 16 Feb 2008 08:20:37 +0000 (00:20 -0800)
committerJunio C Hamano <gitster@pobox.com>
Sat, 16 Feb 2008 08:20:37 +0000 (00:20 -0800)
* maint:
commit: discard index after setting up partial commit
filter-branch: handle filenames that need quoting
diff: Fix miscounting of --check output
hg-to-git: fix parent analysis
mailinfo: feed only one line to handle_filter() for QP input
diff.c: add "const" qualifier to "char *cmd" member of "struct ll_diff_driver"
Add "const" qualifier to "char *excludes_file".
Add "const" qualifier to "char *editor_program".
Add "const" qualifier to "char *pager_program".
config: add 'git_config_string' to refactor string config variables.
diff.c: remove useless check for value != NULL
fast-import: check return value from unpack_entry()
Validate nicknames of remote branches to prohibit confusing ones
diff.c: replace a 'strdup' with 'xstrdup'.
diff.c: fixup garding of config parser from value=NULL

18 files changed:
builtin-commit.c
builtin-mailinfo.c
cache.h
config.c
contrib/hg-to-git/hg-to-git.py
diff.c
environment.c
fast-import.c
git-filter-branch.sh
remote.c
t/t4015-diff-whitespace.sh
t/t5100-mailinfo.sh
t/t5100/info0009 [new file with mode: 0644]
t/t5100/msg0009 [new file with mode: 0644]
t/t5100/patch0009 [new file with mode: 0644]
t/t5100/sample.mbox
t/t7003-filter-branch.sh
t/t7502-status.sh
index 717eb18da0e0cbe901dd8a660649388ccc0a24e1..ff6ea0d85eebdd0b815f33b9b1ef0df8d1885988 100644 (file)
@@ -317,6 +317,10 @@ static char *prepare_index(int argc, const char **argv, const char *prefix)
        if (write_cache(fd, active_cache, active_nr) ||
            close_lock_file(&false_lock))
                die("unable to write temporary index file");
+
+       discard_cache();
+       read_cache_from(false_lock.filename);
+
        return false_lock.filename;
 }
 
index 2600847974f8a44bdd2148da6ff82ecf761fb193..11f154b31fcbd5c788299855e7d69f54ae8c7e70 100644 (file)
@@ -818,6 +818,7 @@ static void handle_body(void)
 
                switch (transfer_encoding) {
                case TE_BASE64:
+               case TE_QP:
                {
                        char *op = line;
 
diff --git a/cache.h b/cache.h
index 3867ba7ff5c3946e0449c78b26880a71107730a0..cdcabe92b6e51fcda60ec68cd0ab21ae11cca66f 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -625,6 +625,7 @@ extern int git_parse_ulong(const char *, unsigned long *);
 extern int git_config_int(const char *, const char *);
 extern unsigned long git_config_ulong(const char *, const char *);
 extern int git_config_bool(const char *, const char *);
+extern int git_config_string(const char **, const char *, const char *);
 extern int git_config_set(const char *, const char *);
 extern int git_config_set_multivar(const char *, const char *, const char *, int);
 extern int git_config_rename_section(const char *, const char *);
@@ -650,12 +651,12 @@ extern int write_or_whine_pipe(int fd, const void *buf, size_t count, const char
 
 /* pager.c */
 extern void setup_pager(void);
-extern char *pager_program;
+extern const char *pager_program;
 extern int pager_in_use(void);
 extern int pager_use_color;
 
-extern char *editor_program;
-extern char *excludes_file;
+extern const char *editor_program;
+extern const char *excludes_file;
 
 /* base85 */
 int decode_85(char *dst, const char *line, int linelen);
index 3e72778e94267044780a180145eae0a6a229e3a3..ad47dc34f05c6cb7e8fb25a2975de487c2a484d3 100644 (file)
--- a/config.c
+++ b/config.c
@@ -309,6 +309,14 @@ int git_config_bool(const char *name, const char *value)
        return git_config_int(name, value) != 0;
 }
 
+int git_config_string(const char **dest, const char *var, const char *value)
+{
+       if (!value)
+               return config_error_nonbool(var);
+       *dest = xstrdup(value);
+       return 0;
+}
+
 int git_default_config(const char *var, const char *value)
 {
        /* This needs a better name */
@@ -421,46 +429,25 @@ int git_default_config(const char *var, const char *value)
                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;
-       }
+       if (!strcmp(var, "i18n.commitencoding"))
+               return git_config_string(&git_commit_encoding, var, value);
 
+       if (!strcmp(var, "i18n.logoutputencoding"))
+               return git_config_string(&git_log_output_encoding, var, value);
 
        if (!strcmp(var, "pager.color") || !strcmp(var, "color.pager")) {
                pager_use_color = git_config_bool(var,value);
                return 0;
        }
 
-       if (!strcmp(var, "core.pager")) {
-               if (!value)
-                       return config_error_nonbool(var);
-               pager_program = xstrdup(value);
-               return 0;
-       }
+       if (!strcmp(var, "core.pager"))
+               return git_config_string(&pager_program, var, value);
 
-       if (!strcmp(var, "core.editor")) {
-               if (!value)
-                       return config_error_nonbool(var);
-               editor_program = xstrdup(value);
-               return 0;
-       }
+       if (!strcmp(var, "core.editor"))
+               return git_config_string(&editor_program, var, value);
 
-       if (!strcmp(var, "core.excludesfile")) {
-               if (!value)
-                       return config_error_nonbool(var);
-               excludes_file = xstrdup(value);
-               return 0;
-       }
+       if (!strcmp(var, "core.excludesfile"))
+               return git_config_string(&excludes_file, var, value);
 
        if (!strcmp(var, "core.whitespace")) {
                if (!value)
index c35b15860d3a4edcf2cd93d082308ec7ce80e5f5..d72ffbb7773268514d8de29c5d5c33fdaf31f339 100755 (executable)
@@ -111,7 +111,7 @@ def getgitenv(user, date):
 hgbranch["0"] = "master"
 for cset in range(1, int(tip) + 1):
     hgchildren[str(cset)] = ()
-    prnts = os.popen('hg log -r %d --template "{parents}"' % cset).read().split(' ')
+    prnts = os.popen('hg log -r %d --template "{parents}"' % cset).read().strip().split(' ')
     prnts = map(lambda x: x[:x.find(':')], prnts)
     if prnts[0] != '':
         parent = prnts[0].strip()
diff --git a/diff.c b/diff.c
index cd8bc4dcc32757dfed9374fa8769599a6a7857ad..41ec2ced78d7f0d8fe86eea0285b76f70843a3a8 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -57,7 +57,7 @@ static int parse_diff_color_slot(const char *var, int ofs)
 static struct ll_diff_driver {
        const char *name;
        struct ll_diff_driver *next;
-       char *cmd;
+       const char *cmd;
 } *user_diff, **user_diff_tail;
 
 /*
@@ -86,10 +86,7 @@ static int parse_lldiff_command(const char *var, const char *ep, const char *val
                user_diff_tail = &(drv->next);
        }
 
-       if (!value)
-               return error("%s: lacks value", var);
-       drv->cmd = strdup(value);
-       return 0;
+       return git_config_string(&(drv->cmd), var, value);
 }
 
 /*
@@ -166,13 +163,8 @@ int git_diff_ui_config(const char *var, const char *value)
        if (!prefixcmp(var, "diff.")) {
                const char *ep = strrchr(var, '.');
 
-               if (ep != var + 4) {
-                       if (!strcmp(ep, ".command")) {
-                               if (!value)
-                                       return config_error_nonbool(var);
-                               return parse_lldiff_command(var, ep, value);
-                       }
-               }
+               if (ep != var + 4 && !strcmp(ep, ".command"))
+                       return parse_lldiff_command(var, ep, value);
        }
 
        return git_diff_basic_config(var, value);
@@ -1021,6 +1013,7 @@ static void checkdiff_consume(void *priv, char *line, unsigned long len)
        char *err;
 
        if (line[0] == '+') {
+               data->lineno++;
                data->status = check_and_emit_line(line + 1, len - 1,
                    data->ws_rule, NULL, NULL, NULL, NULL);
                if (!data->status)
@@ -1031,13 +1024,12 @@ static void checkdiff_consume(void *priv, char *line, unsigned long len)
                emit_line(set, reset, line, 1);
                (void)check_and_emit_line(line + 1, len - 1, data->ws_rule,
                    stdout, set, reset, ws);
-               data->lineno++;
        } else if (line[0] == ' ')
                data->lineno++;
        else if (line[0] == '@') {
                char *plus = strchr(line, '+');
                if (plus)
-                       data->lineno = strtol(plus, NULL, 10);
+                       data->lineno = strtol(plus, NULL, 10) - 1;
                else
                        die("invalid diff");
        }
index 18a1c4eec49bfddcb81d6669c83f8f97a218d7bf..fa3633372b8249899ff1e57a2f1431de029b211d 100644 (file)
@@ -30,10 +30,10 @@ int core_compression_seen;
 size_t packed_git_window_size = DEFAULT_PACKED_GIT_WINDOW_SIZE;
 size_t packed_git_limit = DEFAULT_PACKED_GIT_LIMIT;
 size_t delta_base_cache_limit = 16 * 1024 * 1024;
-char *pager_program;
+const char *pager_program;
 int pager_use_color = 1;
-char *editor_program;
-char *excludes_file;
+const char *editor_program;
+const char *excludes_file;
 int auto_crlf = 0;     /* 1: both ways, -1: only when adding git objects */
 unsigned whitespace_rule_cfg = WS_DEFAULT_RULE;
 
index a523b171e22f83d6a656b372cf20afe52d27d1b2..9b71ccc479352c6a37b9b9652f1cb1793fdbb01b 100644 (file)
@@ -1204,6 +1204,8 @@ static void load_tree(struct tree_entry *root)
                        die("Not a tree: %s", sha1_to_hex(sha1));
                t->delta_depth = myoe->depth;
                buf = gfi_unpack_entry(myoe, &size);
+               if (!buf)
+                       die("Can't load tree %s", sha1_to_hex(sha1));
        } else {
                enum object_type type;
                buf = read_sha1_file(sha1, &type, &size);
index ff716cabb084526ddb5655c3b7c6dd02f4ed1b39..49e13f0bb1ed2bcb6e85455f24dffa912927d67a 100755 (executable)
@@ -276,10 +276,11 @@ while read commit parents; do
                eval "$filter_tree" < /dev/null ||
                        die "tree filter failed: $filter_tree"
 
-               git diff-index -r $commit | cut -f 2- | tr '\012' '\000' | \
-                       xargs -0 git update-index --add --replace --remove
-               git ls-files -z --others | \
-                       xargs -0 git update-index --add --replace --remove
+               (
+                       git diff-index -r --name-only $commit
+                       git ls-files --others
+               ) |
+               git update-index --add --replace --remove --stdin
        fi
 
        eval "$filter_index" < /dev/null ||
index 20abbc07acb2e48aefb2129683b5dc159661211e..6b56473f5bb7d8ab2226ed83805f30c9e21ba773 100644 (file)
--- a/remote.c
+++ b/remote.c
@@ -343,6 +343,16 @@ struct refspec *parse_ref_spec(int nr_refspec, const char **refspec)
        return rs;
 }
 
+static int valid_remote_nick(const char *name)
+{
+       if (!name[0] || /* not empty */
+           (name[0] == '.' && /* not "." */
+            (!name[1] || /* not ".." */
+             (name[1] == '.' && !name[2]))))
+               return 0;
+       return !strchr(name, '/'); /* no slash */
+}
+
 struct remote *remote_get(const char *name)
 {
        struct remote *ret;
@@ -351,7 +361,7 @@ struct remote *remote_get(const char *name)
        if (!name)
                name = default_remote_name;
        ret = make_remote(name, 0);
-       if (name[0] != '/') {
+       if (valid_remote_nick(name)) {
                if (!ret->url)
                        read_remotes_file(ret);
                if (!ret->url)
index d30169fbdcafdf51561f024e887f05aa800fc9d4..83c54b747f4efe1f99b67284a7ba72b89df07a6d 100755 (executable)
@@ -326,4 +326,13 @@ test_expect_success 'check tabs and spaces as indentation (indent-with-non-tab:
        ! git diff --check
 
 '
+
+test_expect_success 'line numbers in --check output are correct' '
+
+       echo "" > x &&
+       echo "foo(); " >> x &&
+       git diff --check | grep "x:2:"
+
+'
+
 test_done
index 9b1a74542a848ef702c1e6208d6ff2537b0f6ac0..d6c55c115779730fdef8d05fbdb039fe90e3fad7 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` = 8'
+       test `cat last` = 9'
 
 for mail in `echo 00*`
 do
diff --git a/t/t5100/info0009 b/t/t5100/info0009
new file mode 100644 (file)
index 0000000..2a66321
--- /dev/null
@@ -0,0 +1,5 @@
+Author: F U Bar
+Email: f.u.bar@example.com
+Subject: updates
+Date: Mon, 17 Sep 2001 00:00:00 +0900
+
diff --git a/t/t5100/msg0009 b/t/t5100/msg0009
new file mode 100644 (file)
index 0000000..9ffe131
--- /dev/null
@@ -0,0 +1,2 @@
+This is to fix diff-format documentation.
+
diff --git a/t/t5100/patch0009 b/t/t5100/patch0009
new file mode 100644 (file)
index 0000000..65615c3
--- /dev/null
@@ -0,0 +1,13 @@
+diff --git a/Documentation/diff-format.txt b/Documentation/diff-format.txt
+index b426a14..97756ec 100644
+--- a/Documentation/diff-format.txt
++++ b/Documentation/diff-format.txt
+@@ -81,7 +81,7 @@ The "diff" formatting options can be customized via the
+ environment variable 'GIT_DIFF_OPTS'.  For example, if you
+ prefer context diff:
+-      GIT_DIFF_OPTS=-c git-diff-index -p $(cat .git/HEAD)
++      GIT_DIFF_OPTS=-c git-diff-index -p HEAD
+ 2. When the environment variable 'GIT_EXTERNAL_DIFF' is set, the
index 070c1661b9be8530e619cd0c297673d1e5e958a3..0476b96c33de8bbc6c4b3bc4f510e9fc50aa6440 100644 (file)
@@ -407,3 +407,26 @@ Subject: [PATCH] another patch
 
 Hey you forgot the patch!
 
+From nobody Mon Sep 17 00:00:00 2001
+From: A U Thor <a.u.thor@example.com>
+Date: Mon, 17 Sep 2001 00:00:00 +0900
+Mime-Version: 1.0
+Content-Type: Text/Plain; charset=us-ascii
+Content-Transfer-Encoding: Quoted-Printable
+
+=0A=0AFrom: F U Bar <f.u.bar@example.com>
+Subject: [PATCH] updates=0A=0AThis is to fix diff-format documentation.
+
+diff --git a/Documentation/diff-format.txt b/Documentation/diff-format.txt
+index b426a14..97756ec 100644
+--- a/Documentation/diff-format.txt
++++ b/Documentation/diff-format.txt
+@@ -81,7 +81,7 @@ The "diff" formatting options can be customized via the
+ environment variable 'GIT_DIFF_OPTS'.  For example, if you
+ prefer context diff:
+=20
+-      GIT_DIFF_OPTS=3D-c git-diff-index -p $(cat .git/HEAD)
++      GIT_DIFF_OPTS=3D-c git-diff-index -p HEAD
+=20
+=20
+ 2. When the environment variable 'GIT_EXTERNAL_DIFF' is set, the
index 5f60b22d872b5d034e137e0c6c7c5a9d664e57ee..868babc4b2350526192a8df53f6cbec3f81c644e 100755 (executable)
@@ -165,4 +165,18 @@ test_expect_success '"map" works in commit filter' '
        git rev-parse --verify master
 '
 
+test_expect_success 'Name needing quotes' '
+
+       git checkout -b rerere A &&
+       mkdir foo &&
+       name="れれれ" &&
+       >foo/$name &&
+       git add foo &&
+       git commit -m "Adding a file" &&
+       git filter-branch --tree-filter "rm -fr foo" &&
+       ! git ls-files --error-unmatch "foo/$name" &&
+       test $(git rev-parse --verify rerere) != $(git rev-parse --verify A)
+
+'
+
 test_done
index b64ce30ff1c28a44b24eb6dd07a2cd9e260e0326..e00607490bcb0439c6557003a3419d84823a8f00 100755 (executable)
@@ -128,4 +128,25 @@ test_expect_success 'status without relative paths' '
 
 '
 
+cat <<EOF >expect
+# On branch master
+# Changes to be committed:
+#   (use "git reset HEAD <file>..." to unstage)
+#
+#      modified:   dir1/modified
+#
+# Untracked files:
+#   (use "git add <file>..." to include in what will be committed)
+#
+#      dir1/untracked
+#      dir2/
+#      expect
+#      output
+#      untracked
+EOF
+test_expect_success 'status of partial commit excluding new file in index' '
+       git status dir1/modified >output &&
+       diff -u expect output
+'
+
 test_done