diff --git a/Documentation/RelNotes-1.5.6.4.txt b/Documentation/RelNotes-1.5.6.4.txt new file mode 100644 index 0000000000..130418864e --- /dev/null +++ b/Documentation/RelNotes-1.5.6.4.txt @@ -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 diff --git a/Documentation/git-cherry-pick.txt b/Documentation/git-cherry-pick.txt index a691173ba1..50fb3d5d54 100644 --- a/Documentation/git-cherry-pick.txt +++ b/Documentation/git-cherry-pick.txt @@ -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:: diff --git a/Documentation/git-revert.txt b/Documentation/git-revert.txt index 5411edca96..271850f511 100644 --- a/Documentation/git-revert.txt +++ b/Documentation/git-revert.txt @@ -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:: diff --git a/attr.c b/attr.c index 0fb47d3434..17f6a4dca5 100644 --- 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); diff --git a/builtin-grep.c b/builtin-grep.c index ef299108f5..647535061c 100644 --- a/builtin-grep.c +++ b/builtin-grep.c @@ -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); + strbuf_add(&pathbuf, tree_name, tn_len); + strbuf_addch(&pathbuf, ':'); + tn_len = pathbuf.len; } - else { - down = path_buf; - strcpy(down, base); - } - 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; } diff --git a/diff-lib.c b/diff-lib.c index b17722d66a..e7eaff9a68 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -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 6a39b393f3..a07812c5c7 100644 --- a/diff.c +++ b/diff.c @@ -3412,9 +3412,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)) @@ -3436,9 +3435,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; @@ -3459,9 +3455,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) @@ -3474,8 +3469,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 5dc0cb595b..50fb5ddb0b 100644 --- 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, diff --git a/git-cvsserver.perl b/git-cvsserver.perl index 920bbe15a3..b00d1c29cd 100755 --- a/git-cvsserver.perl +++ b/git-cvsserver.perl @@ -1884,7 +1884,7 @@ sub req_annotate } # done; get out of the tempdir - cleanupWorkDir(); + cleanupWorkTree(); print "ok\n"; diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index da79a24568..e63a864c7b 100755 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -174,6 +174,8 @@ pick_one_preserving_merges () { new_parents="$new_parents $new_p" ;; esac + else + new_parents="$new_parents $p" fi done case $fast_forward in diff --git a/revision.c b/revision.c index 846af7bd20..3897fec531 100644 --- a/revision.c +++ b/revision.c @@ -260,7 +260,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; @@ -286,7 +286,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); diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh index d4cf6289a4..9ab5bdacc4 100755 --- a/t/t7600-merge.sh +++ b/t/t7600-merge.sh @@ -221,37 +221,13 @@ 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_expect_failure 'test option parsing' ' + 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' ' diff --git a/tree-diff.c b/tree-diff.c index e1e2e6c6ce..bbb126fc46 100644 --- a/tree-diff.c +++ b/tree-diff.c @@ -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); } }