diff options
-rw-r--r-- | Documentation/RelNotes-1.6.3.1.txt | 10 | ||||
-rw-r--r-- | Documentation/git-cat-file.txt | 4 | ||||
-rw-r--r-- | Documentation/git-ls-tree.txt | 4 | ||||
-rw-r--r-- | Documentation/merge-options.txt | 3 | ||||
-rw-r--r-- | Documentation/technical/api-parse-options.txt | 2 | ||||
-rwxr-xr-x | GIT-VERSION-GEN | 2 | ||||
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | builtin-cat-file.c | 4 | ||||
-rw-r--r-- | builtin-checkout.c | 25 | ||||
-rw-r--r-- | builtin-fetch.c | 11 | ||||
-rw-r--r-- | builtin-for-each-ref.c | 7 | ||||
-rw-r--r-- | builtin-show-branch.c | 2 | ||||
-rwxr-xr-x | contrib/completion/git-completion.bash | 38 | ||||
-rw-r--r-- | decorate.c | 4 | ||||
-rw-r--r-- | dir.c | 2 | ||||
-rw-r--r-- | grep.c | 5 | ||||
-rw-r--r-- | http-push.c | 3 | ||||
-rw-r--r-- | object.c | 3 | ||||
-rw-r--r-- | refs.c | 4 | ||||
-rw-r--r-- | sha1_file.c | 6 | ||||
-rwxr-xr-x | t/t2014-switch.sh | 28 | ||||
-rwxr-xr-x | t/t4014-format-patch.sh | 11 | ||||
-rwxr-xr-x | t/t4021-format-patch-numbered.sh | 6 | ||||
-rwxr-xr-x | t/t7201-co.sh | 8 | ||||
-rwxr-xr-x | templates/hooks--pre-commit.sample | 2 |
25 files changed, 140 insertions, 55 deletions
diff --git a/Documentation/RelNotes-1.6.3.1.txt b/Documentation/RelNotes-1.6.3.1.txt index 98c02250bb..2400b72ef7 100644 --- a/Documentation/RelNotes-1.6.3.1.txt +++ b/Documentation/RelNotes-1.6.3.1.txt @@ -4,9 +4,7 @@ GIT v1.6.3.1 Release Notes Fixes since v1.6.3 ------------------ --- -exec >/var/tmp/1 -O=v1.6.3 -echo O=$(git describe maint) -git shortlog $O..maint - +* "git checkout -b new-branch" with a staged change in the index + incorrectly primed the in-index cache-tree, resulting a wrong tree + object to be written out of the index. This is a grave regression + since the last 1.6.2.X maintenance release. diff --git a/Documentation/git-cat-file.txt b/Documentation/git-cat-file.txt index b191276d7a..58c8d65772 100644 --- a/Documentation/git-cat-file.txt +++ b/Documentation/git-cat-file.txt @@ -9,8 +9,8 @@ git-cat-file - Provide content or type and size information for repository objec SYNOPSIS -------- [verse] -'git cat-file' [-t | -s | -e | -p | <type>] <object> -'git cat-file' [--batch | --batch-check] < <list-of-objects> +'git cat-file' (-t | -s | -e | -p | <type>) <object> +'git cat-file' (--batch | --batch-check) < <list-of-objects> DESCRIPTION ----------- diff --git a/Documentation/git-ls-tree.txt b/Documentation/git-ls-tree.txt index f68e5c5c1a..c3fdccb4c2 100644 --- a/Documentation/git-ls-tree.txt +++ b/Documentation/git-ls-tree.txt @@ -82,8 +82,10 @@ Output Format ------------- <mode> SP <type> SP <object> TAB <file> -When the `-z` option is not used, TAB, LF, and backslash characters +Unless the `-z` option is used, TAB, LF, and backslash characters in pathnames are represented as `\t`, `\n`, and `\\`, respectively. +This output format is compatible with what '--index-info --stdin' of +'git update-index' expects. When the `-l` option is used, format changes to diff --git a/Documentation/merge-options.txt b/Documentation/merge-options.txt index 637b53f898..adadf8e4bf 100644 --- a/Documentation/merge-options.txt +++ b/Documentation/merge-options.txt @@ -39,7 +39,8 @@ --squash:: Produce the working tree and index state as if a real - merge happened, but do not actually make a commit or + merge happened (except for the merge information), + but do not actually make a commit or move the `HEAD`, nor record `$GIT_DIR/MERGE_HEAD` to cause the next `git commit` command to create a merge commit. This allows you to create a single commit on diff --git a/Documentation/technical/api-parse-options.txt b/Documentation/technical/api-parse-options.txt index e66ca9f70c..e30c602f47 100644 --- a/Documentation/technical/api-parse-options.txt +++ b/Documentation/technical/api-parse-options.txt @@ -198,7 +198,7 @@ The function must be defined in this form: The callback mechanism is as follows: -* Inside `funct`, the only interesting member of the structure +* Inside `func`, the only interesting member of the structure given by `opt` is the void pointer `opt->value`. `\*opt->value` will be the value that is saved into `var`, if you use `OPT_CALLBACK()`. diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 39cde784c9..d292e3a2d3 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v1.6.3.GIT +DEF_VER=v1.6.3.1 LF=' ' @@ -749,6 +749,7 @@ endif ifeq ($(uname_S),OpenBSD) NO_STRCASESTR = YesPlease NO_MEMMEM = YesPlease + USE_ST_TIMESPEC = YesPlease NEEDS_LIBICONV = YesPlease BASIC_CFLAGS += -I/usr/local/include BASIC_LDFLAGS += -L/usr/local/lib diff --git a/builtin-cat-file.c b/builtin-cat-file.c index 8fad19daed..43ffe7ffae 100644 --- a/builtin-cat-file.c +++ b/builtin-cat-file.c @@ -201,8 +201,8 @@ static int batch_objects(int print_contents) } static const char * const cat_file_usage[] = { - "git cat-file [-t|-s|-e|-p|<type>] <sha1>", - "git cat-file [--batch|--batch-check] < <list_of_sha1s>", + "git cat-file (-t|-s|-e|-p|<type>) <object>", + "git cat-file (--batch|--batch-check) < <list_of_objects>", NULL }; diff --git a/builtin-checkout.c b/builtin-checkout.c index 15f0c32c7a..f2d7ef01b0 100644 --- a/builtin-checkout.c +++ b/builtin-checkout.c @@ -365,17 +365,14 @@ static int merge_working_tree(struct checkout_opts *opts, int ret; struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file)); int newfd = hold_locked_index(lock_file, 1); - int reprime_cache_tree = 0; if (read_cache() < 0) return error("corrupt index file"); - cache_tree_free(&active_cache_tree); if (opts->force) { ret = reset_tree(new->commit->tree, opts, 1); if (ret) return ret; - reprime_cache_tree = 1; } else { struct tree_desc trees[2]; struct tree *tree; @@ -411,9 +408,7 @@ static int merge_working_tree(struct checkout_opts *opts, init_tree_desc(&trees[1], tree->buffer, tree->size); ret = unpack_trees(2, trees, &topts); - if (ret != -1) { - reprime_cache_tree = 1; - } else { + if (ret == -1) { /* * Unpack couldn't do a trivial merge; either * give up or do a real merge, depending on @@ -457,8 +452,6 @@ static int merge_working_tree(struct checkout_opts *opts, } } - if (reprime_cache_tree) - prime_cache_tree(&active_cache_tree, new->commit->tree); if (write_cache(newfd, active_cache, active_nr) || commit_locked_index(lock_file)) die("unable to write new index file"); @@ -548,14 +541,6 @@ static int switch_branches(struct checkout_opts *opts, struct branch_info *new) parse_commit(new->commit); } - /* - * If we were on a detached HEAD, but we are now moving to - * a new commit, we want to mention the old commit once more - * to remind the user that it might be lost. - */ - if (!opts->quiet && !old.path && old.commit && new->commit != old.commit) - describe_detached_head("Previous HEAD position was", old.commit); - if (!old.commit && !opts->force) { if (!opts->quiet) { warning("You appear to be on a branch yet to be born."); @@ -568,6 +553,14 @@ static int switch_branches(struct checkout_opts *opts, struct branch_info *new) if (ret) return ret; + /* + * If we were on a detached HEAD, but have now moved to + * a new commit, we want to mention the old commit once more + * to remind the user that it might be lost. + */ + if (!opts->quiet && !old.path && old.commit && new->commit != old.commit) + describe_detached_head("Previous HEAD position was", old.commit); + update_refs_for_switch(opts, &old, new); ret = post_checkout_hook(old.commit, new->commit, 1); diff --git a/builtin-fetch.c b/builtin-fetch.c index 3c998ea740..1f7a3f1ce6 100644 --- a/builtin-fetch.c +++ b/builtin-fetch.c @@ -167,6 +167,9 @@ static struct ref *get_ref_map(struct transport *transport, return ref_map; } +#define STORE_REF_ERROR_OTHER 1 +#define STORE_REF_ERROR_DF_CONFLICT 2 + static int s_update_ref(const char *action, struct ref *ref, int check_old) @@ -181,9 +184,11 @@ static int s_update_ref(const char *action, lock = lock_any_ref_for_update(ref->name, check_old ? ref->old_sha1 : NULL, 0); if (!lock) - return 2; + return errno == ENOTDIR ? STORE_REF_ERROR_DF_CONFLICT : + STORE_REF_ERROR_OTHER; if (write_ref_sha1(lock, ref->new_sha1, msg) < 0) - return 2; + return errno == ENOTDIR ? STORE_REF_ERROR_DF_CONFLICT : + STORE_REF_ERROR_OTHER; return 0; } @@ -377,7 +382,7 @@ static int store_updated_refs(const char *url, const char *remote_name, } } fclose(fp); - if (rc & 2) + if (rc & STORE_REF_ERROR_DF_CONFLICT) error("some local refs could not be updated; try running\n" " 'git remote prune %s' to remove any old, conflicting " "branches", remote_name); diff --git a/builtin-for-each-ref.c b/builtin-for-each-ref.c index 91e8f95fd2..d091e04af9 100644 --- a/builtin-for-each-ref.c +++ b/builtin-for-each-ref.c @@ -339,8 +339,11 @@ static const char *copy_name(const char *buf) static const char *copy_email(const char *buf) { const char *email = strchr(buf, '<'); - const char *eoemail = strchr(email, '>'); - if (!email || !eoemail) + const char *eoemail; + if (!email) + return ""; + eoemail = strchr(email, '>'); + if (!eoemail) return ""; return xmemdupz(email, eoemail + 1 - email); } diff --git a/builtin-show-branch.c b/builtin-show-branch.c index 828e6f86de..c3afabbe91 100644 --- a/builtin-show-branch.c +++ b/builtin-show-branch.c @@ -576,7 +576,7 @@ static void parse_reflog_param(const char *arg, int *cnt, const char **base) if (*ep == ',') *base = ep + 1; else if (*ep) - die("unrecognized reflog param '%s'", arg + 9); + die("unrecognized reflog param '%s'", arg); else *base = NULL; if (*cnt <= 0) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 1683e6d7b8..f44152c433 100755 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -99,20 +99,32 @@ __git_ps1 () elif [ -d "$g/rebase-merge" ]; then r="|REBASE-m" b="$(cat "$g/rebase-merge/head-name")" - elif [ -f "$g/MERGE_HEAD" ]; then - r="|MERGING" - b="$(git symbolic-ref HEAD 2>/dev/null)" else + if [ -f "$g/MERGE_HEAD" ]; then + r="|MERGING" + fi if [ -f "$g/BISECT_LOG" ]; then r="|BISECTING" fi - if ! b="$(git symbolic-ref HEAD 2>/dev/null)"; then - if ! b="$(git describe --exact-match HEAD 2>/dev/null)"; then - if [ -r "$g/HEAD" ]; then - b="$(cut -c1-7 "$g/HEAD")..." - fi - fi - fi + + b="$(git symbolic-ref HEAD 2>/dev/null)" || { + + b="$( + case "${GIT_PS1_DESCRIBE_STYLE-}" in + (contains) + git describe --contains HEAD ;; + (branch) + git describe --contains --all HEAD ;; + (describe) + git describe HEAD ;; + (* | default) + git describe --exact-match HEAD ;; + esac 2>/dev/null)" || + + b="$(cut -c1-7 "$g/HEAD" 2>/dev/null)..." || + b="unknown" + b="($b)" + } fi local w @@ -120,7 +132,7 @@ __git_ps1 () local c if [ "true" = "$(git rev-parse --is-inside-git-dir 2>/dev/null)" ]; then - if [ "true" = "$(git config --bool core.bare 2>/dev/null)" ]; then + if [ "true" = "$(git rev-parse --is-bare-repository 2>/dev/null)" ]; then c="BARE:" else b="GIT_DIR!" @@ -1792,7 +1804,7 @@ _git_show () return ;; --*) - __gitcomp "--pretty= --format= + __gitcomp "--pretty= --format= --abbrev-commit --oneline $__git_diff_common_options " return @@ -1809,7 +1821,7 @@ _git_show_branch () __gitcomp " --all --remotes --topo-order --current --more= --list --independent --merge-base --no-name - --sha1-name --topics --reflog + --sha1-name --sparse --topics --reflog " return ;; diff --git a/decorate.c b/decorate.c index 82d9e221ea..e6fd8a7441 100644 --- a/decorate.c +++ b/decorate.c @@ -8,7 +8,9 @@ static unsigned int hash_obj(const struct object *obj, unsigned int n) { - unsigned int hash = *(unsigned int *)obj->sha1; + unsigned int hash; + + memcpy(&hash, obj->sha1, sizeof(unsigned int)); return hash % n; } @@ -576,7 +576,7 @@ static int get_dtype(struct dirent *de, const char *path) */ static int read_directory_recursive(struct dir_struct *dir, const char *path, const char *base, int baselen, int check_only, const struct path_simplify *simplify) { - DIR *fdir = opendir(path); + DIR *fdir = opendir(*path ? path : "."); int contents = 0; if (fdir) { @@ -305,6 +305,7 @@ static int match_one_pattern(struct grep_pat *p, char *bol, char *eol, { int hit = 0; int saved_ch = 0; + const char *start = bol; if ((p->token != GREP_PATTERN) && ((p->token == GREP_PATTERN_HEAD) != (ctx == GREP_CONTEXT_HEAD))) @@ -365,6 +366,10 @@ static int match_one_pattern(struct grep_pat *p, char *bol, char *eol, } if (p->token == GREP_PATTERN_HEAD && saved_ch) *eol = saved_ch; + if (hit) { + pmatch[0].rm_so += bol - start; + pmatch[0].rm_eo += bol - start; + } return hit; } diff --git a/http-push.c b/http-push.c index 5138224cc3..9da14201b1 100644 --- a/http-push.c +++ b/http-push.c @@ -1415,8 +1415,9 @@ static void remove_locks(void) fprintf(stderr, "Removing remote locks...\n"); while (lock) { + struct remote_lock *next = lock->next; unlock_remote(lock); - lock = lock->next; + lock = next; } } @@ -45,7 +45,8 @@ int type_from_string(const char *str) static unsigned int hash_obj(struct object *obj, unsigned int n) { - unsigned int hash = *(unsigned int *)obj->sha1; + unsigned int hash; + memcpy(&hash, obj->sha1, sizeof(unsigned int)); return hash % n; } @@ -893,8 +893,10 @@ static struct ref_lock *lock_ref_sha1_basic(const char *ref, const unsigned char * name is a proper prefix of our refname. */ if (missing && - !is_refname_available(ref, NULL, get_packed_refs(), 0)) + !is_refname_available(ref, NULL, get_packed_refs(), 0)) { + last_errno = ENOTDIR; goto error_return; + } lock->lk = xcalloc(1, sizeof(struct lock_file)); diff --git a/sha1_file.c b/sha1_file.c index 28bd9082fc..bd5edd8e65 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -720,6 +720,8 @@ static int open_packed_git_1(struct packed_git *p) return error("packfile %s index unavailable", p->pack_name); p->pack_fd = open(p->pack_name, O_RDONLY); + while (p->pack_fd < 0 && errno == EMFILE && unuse_one_window(p, -1)) + p->pack_fd = open(p->pack_name, O_RDONLY); if (p->pack_fd < 0 || fstat(p->pack_fd, &st)) return -1; @@ -937,6 +939,8 @@ static void prepare_packed_git_one(char *objdir, int local) sprintf(path, "%s/pack", objdir); len = strlen(path); dir = opendir(path); + while (!dir && errno == EMFILE && unuse_one_window(packed_git, -1)) + dir = opendir(path); if (!dir) { if (errno != ENOENT) error("unable to open object pack directory: %s: %s", @@ -2339,6 +2343,8 @@ static int write_loose_object(const unsigned char *sha1, char *hdr, int hdrlen, filename = sha1_file_name(sha1); fd = create_tmpfile(tmpfile, sizeof(tmpfile), filename); + while (fd < 0 && errno == EMFILE && unuse_one_window(packed_git, -1)) + fd = create_tmpfile(tmpfile, sizeof(tmpfile), filename); if (fd < 0) { if (errno == EACCES) return error("insufficient permission for adding an object to repository database %s\n", get_object_directory()); diff --git a/t/t2014-switch.sh b/t/t2014-switch.sh new file mode 100755 index 0000000000..ccfb147113 --- /dev/null +++ b/t/t2014-switch.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +test_description='Peter MacMillan' +. ./test-lib.sh + +test_expect_success setup ' + echo Hello >file && + git add file && + test_tick && + git commit -m V1 && + echo Hello world >file && + git add file && + git checkout -b other +' + +test_expect_success 'check all changes are staged' ' + git diff --exit-code +' + +test_expect_success 'second commit' ' + git commit -m V2 +' + +test_expect_success 'check' ' + git diff --cached --exit-code +' + +test_done diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh index 11061ddd5b..922a8941ed 100755 --- a/t/t4014-format-patch.sh +++ b/t/t4014-format-patch.sh @@ -505,4 +505,15 @@ test_expect_success 'format-patch from a subdirectory (3)' ' test -f "$basename" ' +test_expect_success 'format-patch --in-reply-to' ' + git format-patch -1 --stdout --in-reply-to "baz@foo.bar" > patch8 && + grep "^In-Reply-To: <baz@foo.bar>" patch8 && + grep "^References: <baz@foo.bar>" patch8 +' + +test_expect_success 'format-patch --signoff' ' + git format-patch -1 --signoff --stdout | + grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" +' + test_done diff --git a/t/t4021-format-patch-numbered.sh b/t/t4021-format-patch-numbered.sh index 390af2389f..3c27f0dc19 100755 --- a/t/t4021-format-patch-numbered.sh +++ b/t/t4021-format-patch-numbered.sh @@ -108,4 +108,10 @@ test_expect_success 'format.numbered = auto && --no-numbered' ' ' +test_expect_success '--start-number && --numbered' ' + + git format-patch --start-number 3 --numbered --stdout HEAD~1 > patch8 && + grep "^Subject: \[PATCH 3/3\]" patch8 +' + test_done diff --git a/t/t7201-co.sh b/t/t7201-co.sh index bdb808af1a..ebfd34df36 100755 --- a/t/t7201-co.sh +++ b/t/t7201-co.sh @@ -534,4 +534,12 @@ test_expect_success 'failing checkout -b should not break working tree' ' ' +test_expect_success 'switch out of non-branch' ' + git reset --hard master && + git checkout master^0 && + echo modified >one && + test_must_fail git checkout renamer 2>error.log && + ! grep "^Previous HEAD" error.log +' + test_done diff --git a/templates/hooks--pre-commit.sample b/templates/hooks--pre-commit.sample index 0e49279c7f..0ba62076fb 100755 --- a/templates/hooks--pre-commit.sample +++ b/templates/hooks--pre-commit.sample @@ -7,7 +7,7 @@ # # To enable this hook, rename this file to "pre-commit". -if git-rev-parse --verify HEAD 2>/dev/null +if git-rev-parse --verify HEAD >/dev/null 2>&1 then against=HEAD else |