diff options
33 files changed, 303 insertions, 98 deletions
diff --git a/Documentation/Makefile b/Documentation/Makefile index c34c1cae20..5cd8b63ac5 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -187,17 +187,18 @@ git.info: user-manual.texi user-manual.texi: user-manual.xml $(RM) $@+ $@ - $(DOCBOOK2X_TEXI) user-manual.xml --to-stdout | $(PERL_PATH) fix-texi.perl >$@+ + $(DOCBOOK2X_TEXI) user-manual.xml --encoding=UTF-8 --to-stdout | \ + $(PERL_PATH) fix-texi.perl >$@+ mv $@+ $@ gitman.texi: $(MAN_XML) cat-texi.perl $(RM) $@+ $@ - ($(foreach xml,$(MAN_XML),$(DOCBOOK2X_TEXI) --to-stdout $(xml);)) | \ - $(PERL_PATH) cat-texi.perl $@ >$@+ + ($(foreach xml,$(MAN_XML),$(DOCBOOK2X_TEXI) --encoding=UTF-8 \ + --to-stdout $(xml);)) | $(PERL_PATH) cat-texi.perl $@ >$@+ mv $@+ $@ gitman.info: gitman.texi - $(MAKEINFO) --no-split $*.texi + $(MAKEINFO) --no-split --no-validate $*.texi $(patsubst %.txt,%.texi,$(MAN_TXT)): %.texi : %.xml $(RM) $@+ $@ diff --git a/Documentation/RelNotes-1.6.2.txt b/Documentation/RelNotes-1.6.2.txt new file mode 100644 index 0000000000..1a80626781 --- /dev/null +++ b/Documentation/RelNotes-1.6.2.txt @@ -0,0 +1,28 @@ +GIT v1.6.2 Release Notes +======================== + +Updates since v1.6.1 +-------------------- + +(subsystems) + +(portability) + +(performance) + +(usability, bells and whistles) + +(internal) + + +Fixes since v1.6.1 +------------------ + +All of the fixes in v1.6.1.X maintenance series are included in this +release, unless otherwise noted. + +-- +exec >/var/tmp/1 +O=v1.6.1 +echo O=$(git describe master) +git shortlog --no-merges $O..master ^maint diff --git a/Documentation/cat-texi.perl b/Documentation/cat-texi.perl index dbc133cd3c..828ec62554 100755 --- a/Documentation/cat-texi.perl +++ b/Documentation/cat-texi.perl @@ -18,8 +18,12 @@ close TMP; printf '\input texinfo @setfilename gitman.info -@documentencoding us-ascii -@node Top,,%s +@documentencoding UTF-8 +@dircategory Development +@direntry +* Git Man Pages: (gitman). Manual pages for Git revision control system +@end direntry +@node Top,,, (dir) @top Git Manual Pages @documentlanguage en @menu diff --git a/Documentation/config.txt b/Documentation/config.txt index 52786c7df5..7408bb2d34 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -1044,6 +1044,16 @@ mergetool.keepBackup:: is set to `false` then this file is not preserved. Defaults to `true` (i.e. keep the backup files). +mergetool.keepTemporaries:: + When invoking a custom merge tool, git uses a set of temporary + files to pass to the tool. If the tool returns an error and this + variable is set to `true`, then these temporary files will be + preserved, otherwise they will be removed after the tool has + exited. Defaults to `false`. + +mergetool.prompt:: + Prompt before each invocation of the merge resolution program. + pack.window:: The size of the window used by linkgit:git-pack-objects[1] when no window size is given on the command line. Defaults to 10. diff --git a/Documentation/git-mergetool.txt b/Documentation/git-mergetool.txt index 602e7c6d3b..4c0ffec507 100644 --- a/Documentation/git-mergetool.txt +++ b/Documentation/git-mergetool.txt @@ -7,7 +7,7 @@ git-mergetool - Run merge conflict resolution tools to resolve merge conflicts SYNOPSIS -------- -'git mergetool' [--tool=<tool>] [<file>]... +'git mergetool' [--tool=<tool>] [-y|--no-prompt|--prompt] [<file>]... DESCRIPTION ----------- @@ -60,6 +60,15 @@ variable `mergetool.<tool>.trustExitCode` can be set to `true`. Otherwise, 'git-mergetool' will prompt the user to indicate the success of the resolution after the custom tool has exited. +-y or --no-prompt:: + Don't prompt before each invocation of the merge resolution + program. + +--prompt:: + Prompt before each invocation of the merge resolution program. + This is the default behaviour; the option is provided to + override any configuration settings. + Author ------ Written by Theodore Y Ts'o <tytso@mit.edu> diff --git a/Documentation/git-reset.txt b/Documentation/git-reset.txt index 2049f3d97b..abb25d1c00 100644 --- a/Documentation/git-reset.txt +++ b/Documentation/git-reset.txt @@ -8,7 +8,7 @@ git-reset - Reset current HEAD to the specified state SYNOPSIS -------- [verse] -'git reset' [--mixed | --soft | --hard] [-q] [<commit>] +'git reset' [--mixed | --soft | --hard | --merge] [-q] [<commit>] 'git reset' [-q] [<commit>] [--] <paths>... DESCRIPTION @@ -45,6 +45,11 @@ OPTIONS switched to. Any changes to tracked files in the working tree since <commit> are lost. +--merge:: + Resets the index to match the tree recorded by the named commit, + and updates the files that are different between the named commit + and the current commit in the working tree. + -q:: Be quiet, only report errors. @@ -152,6 +157,28 @@ tip of the current branch in ORIG_HEAD, so resetting hard to it brings your index file and the working tree back to that state, and resets the tip of the branch to that commit. +Undo a merge or pull inside a dirty work tree:: ++ +------------ +$ git pull <1> +Auto-merging nitfol +Merge made by recursive. + nitfol | 20 +++++---- + ... +$ git reset --merge ORIG_HEAD <2> +------------ ++ +<1> Even if you may have local modifications in your +working tree, you can safely say "git pull" when you know +that the change in the other branch does not overlap with +them. +<2> After inspecting the result of the merge, you may find +that the change in the other branch is unsatisfactory. Running +"git reset --hard ORIG_HEAD" will let you go back to where you +were, but it will discard your local changes, which you do not +want. "git reset --merge" keeps your local changes. + + Interrupted workflow:: + Suppose you are interrupted by an urgent fix request while you @@ -1 +1 @@ -Documentation/RelNotes-1.6.1.1.txt
\ No newline at end of file +Documentation/RelNotes-1.6.2.txt
\ No newline at end of file diff --git a/builtin-apply.c b/builtin-apply.c index 07244b0736..a8f75ed3ed 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -630,7 +630,7 @@ static int gitdiff_index(const char *line, struct patch *patch) memcpy(patch->new_sha1_prefix, line, len); patch->new_sha1_prefix[len] = 0; if (*ptr == ' ') - patch->new_mode = patch->old_mode = strtoul(ptr+1, NULL, 8); + patch->old_mode = strtoul(ptr+1, NULL, 8); return 0; } @@ -2447,6 +2447,8 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s if (st_mode != patch->old_mode) fprintf(stderr, "warning: %s has type %o, expected %o\n", old_name, st_mode, patch->old_mode); + if (!patch->new_mode) + patch->new_mode = st_mode; return 0; is_new: diff --git a/builtin-cat-file.c b/builtin-cat-file.c index 30d00a6664..8fad19daed 100644 --- a/builtin-cat-file.c +++ b/builtin-cat-file.c @@ -137,7 +137,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name) break; default: - die("git cat-file: unknown option: %s\n", exp_type); + die("git cat-file: unknown option: %s", exp_type); } if (!buf) diff --git a/builtin-checkout.c b/builtin-checkout.c index c2c05613b6..b5dd9c07b4 100644 --- a/builtin-checkout.c +++ b/builtin-checkout.c @@ -681,8 +681,8 @@ int cmd_checkout(int argc, const char **argv, const char *prefix) argv++; argc--; + new.name = arg; if ((new.commit = lookup_commit_reference_gently(rev, 1))) { - new.name = arg; setup_branch_path(&new); if (resolve_ref(new.path, rev, 1, NULL)) new.commit = lookup_commit_reference(rev); diff --git a/builtin-clone.c b/builtin-clone.c index 2feac9c5cb..f1a1a0c365 100644 --- a/builtin-clone.c +++ b/builtin-clone.c @@ -192,15 +192,15 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest) dir = opendir(src->buf); if (!dir) - die("failed to open %s\n", src->buf); + die("failed to open %s", src->buf); if (mkdir(dest->buf, 0777)) { if (errno != EEXIST) - die("failed to create directory %s\n", dest->buf); + die("failed to create directory %s", dest->buf); else if (stat(dest->buf, &buf)) - die("failed to stat %s\n", dest->buf); + die("failed to stat %s", dest->buf); else if (!S_ISDIR(buf.st_mode)) - die("%s exists and is not a directory\n", dest->buf); + die("%s exists and is not a directory", dest->buf); } strbuf_addch(src, '/'); @@ -224,16 +224,16 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest) } if (unlink(dest->buf) && errno != ENOENT) - die("failed to unlink %s\n", dest->buf); + die("failed to unlink %s", dest->buf); if (!option_no_hardlinks) { if (!link(src->buf, dest->buf)) continue; if (option_local) - die("failed to create link %s\n", dest->buf); + die("failed to create link %s", dest->buf); option_no_hardlinks = 1; } if (copy_file(dest->buf, src->buf, 0666)) - die("failed to copy file to %s\n", dest->buf); + die("failed to copy file to %s", dest->buf); } closedir(dir); } diff --git a/builtin-fetch.c b/builtin-fetch.c index 7568163af2..de6f3074b1 100644 --- a/builtin-fetch.c +++ b/builtin-fetch.c @@ -607,7 +607,7 @@ static void set_option(const char *name, const char *value) { int r = transport_set_option(transport, name, value); if (r < 0) - die("Option \"%s\" value \"%s\" is not valid for %s\n", + die("Option \"%s\" value \"%s\" is not valid for %s", name, value, transport->url); if (r > 0) warning("Option \"%s\" is ignored for %s\n", diff --git a/builtin-init-db.c b/builtin-init-db.c index d30c3fe2ca..ee3911f8ee 100644 --- a/builtin-init-db.c +++ b/builtin-init-db.c @@ -29,7 +29,7 @@ static void safe_create_dir(const char *dir, int share) } } else if (share && adjust_shared_perm(dir)) - die("Could not make %s writable by group\n", dir); + die("Could not make %s writable by group", dir); } static void copy_templates_1(char *path, int baselen, diff --git a/builtin-log.c b/builtin-log.c index 99d1137b08..4a02ee987a 100644 --- a/builtin-log.c +++ b/builtin-log.c @@ -249,22 +249,13 @@ int cmd_whatchanged(int argc, const char **argv, const char *prefix) static void show_tagger(char *buf, int len, struct rev_info *rev) { - char *email_end, *p; - unsigned long date; - int tz; + struct strbuf out = STRBUF_INIT; - email_end = memchr(buf, '>', len); - if (!email_end) - return; - p = ++email_end; - while (isspace(*p)) - p++; - date = strtoul(p, &p, 10); - while (isspace(*p)) - p++; - tz = (int)strtol(p, NULL, 10); - printf("Tagger: %.*s\nDate: %s\n", (int)(email_end - buf), buf, - show_date(date, tz, rev->date_mode)); + pp_user_info("Tagger", rev->commit_format, &out, buf, rev->date_mode, + git_log_output_encoding ? + git_log_output_encoding: git_commit_encoding); + printf("%s\n", out.buf); + strbuf_release(&out); } static int show_object(const unsigned char *sha1, int show_tag_object, @@ -824,7 +815,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) committer = git_committer_info(IDENT_ERROR_ON_NO_NAME); endpos = strchr(committer, '>'); if (!endpos) - die("bogus committer info %s\n", committer); + die("bogus committer info %s", committer); add_signoff = xmemdupz(committer, endpos - committer + 1); } else if (!strcmp(argv[i], "--attach")) { diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c index e890f7a6d1..f7c8c08b32 100644 --- a/builtin-mailinfo.c +++ b/builtin-mailinfo.c @@ -494,7 +494,7 @@ static void convert_to_utf8(struct strbuf *line, const char *charset) return; out = reencode_string(line->buf, metainfo_charset, charset); if (!out) - die("cannot convert from %s to %s\n", + die("cannot convert from %s to %s", charset, metainfo_charset); strbuf_attach(line, out, strlen(out), strlen(out)); } diff --git a/builtin-merge-recursive.c b/builtin-merge-recursive.c index 6b534c1a66..703045bfc8 100644 --- a/builtin-merge-recursive.c +++ b/builtin-merge-recursive.c @@ -33,7 +33,7 @@ int cmd_merge_recursive(int argc, const char **argv, const char *prefix) } if (argc < 4) - die("Usage: %s <base>... -- <head> <remote> ...\n", argv[0]); + die("Usage: %s <base>... -- <head> <remote> ...", argv[0]); for (i = 1; i < argc; ++i) { if (!strcmp(argv[i], "--")) diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c index cedef52fd3..e8515348be 100644 --- a/builtin-pack-objects.c +++ b/builtin-pack-objects.c @@ -78,7 +78,7 @@ static int progress = 1; static int window = 10; static uint32_t pack_size_limit, pack_size_limit_cfg; static int depth = 50; -static int delta_search_threads = 1; +static int delta_search_threads; static int pack_to_stdout; static int num_preferred_base; static struct progress *progress_state; @@ -1612,11 +1612,18 @@ static void ll_find_deltas(struct object_entry **list, unsigned list_size, find_deltas(list, &list_size, window, depth, processed); return; } + if (progress > pack_to_stdout) + fprintf(stderr, "Delta compression using %d threads.\n", + delta_search_threads); /* Partition the work amongst work threads. */ for (i = 0; i < delta_search_threads; i++) { unsigned sub_size = list_size / (delta_search_threads - i); + /* don't use too small segments or no deltas will be found */ + if (sub_size < 2*window && i+1 < delta_search_threads) + sub_size = 0; + p[i].window = window; p[i].depth = depth; p[i].processed = processed; diff --git a/builtin-reset.c b/builtin-reset.c index 9514b77f8c..c0cb915c26 100644 --- a/builtin-reset.c +++ b/builtin-reset.c @@ -20,11 +20,14 @@ #include "parse-options.h" static const char * const git_reset_usage[] = { - "git reset [--mixed | --soft | --hard] [-q] [<commit>]", + "git reset [--mixed | --soft | --hard | --merge] [-q] [<commit>]", "git reset [--mixed] <commit> [--] <paths>...", NULL }; +enum reset_type { MIXED, SOFT, HARD, MERGE, NONE }; +static const char *reset_type_names[] = { "mixed", "soft", "hard", "merge", NULL }; + static char *args_to_str(const char **argv) { char *buf = NULL; @@ -49,7 +52,7 @@ static inline int is_merge(void) return !access(git_path("MERGE_HEAD"), F_OK); } -static int reset_index_file(const unsigned char *sha1, int is_hard_reset, int quiet) +static int reset_index_file(const unsigned char *sha1, int reset_type, int quiet) { int i = 0; const char *args[6]; @@ -57,9 +60,17 @@ static int reset_index_file(const unsigned char *sha1, int is_hard_reset, int qu args[i++] = "read-tree"; if (!quiet) args[i++] = "-v"; - args[i++] = "--reset"; - if (is_hard_reset) + switch (reset_type) { + case MERGE: args[i++] = "-u"; + args[i++] = "-m"; + break; + case HARD: + args[i++] = "-u"; + /* fallthrough */ + default: + args[i++] = "--reset"; + } args[i++] = sha1_to_hex(sha1); args[i] = NULL; @@ -169,9 +180,6 @@ static void prepend_reflog_action(const char *action, char *buf, size_t size) warning("Reflog action message too long: %.*s...", 50, buf); } -enum reset_type { MIXED, SOFT, HARD, NONE }; -static const char *reset_type_names[] = { "mixed", "soft", "hard", NULL }; - int cmd_reset(int argc, const char **argv, const char *prefix) { int i = 0, reset_type = NONE, update_ref_status = 0, quiet = 0; @@ -186,6 +194,8 @@ int cmd_reset(int argc, const char **argv, const char *prefix) OPT_SET_INT(0, "soft", &reset_type, "reset only HEAD", SOFT), OPT_SET_INT(0, "hard", &reset_type, "reset HEAD, index and working tree", HARD), + OPT_SET_INT(0, "merge", &reset_type, + "reset HEAD, index and working tree", MERGE), OPT_BOOLEAN('q', NULL, &quiet, "disable showing new HEAD in hard reset and progress message"), OPT_END() @@ -266,7 +276,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix) if (is_merge() || read_cache() < 0 || unmerged_cache()) die("Cannot do a soft reset in the middle of a merge."); } - else if (reset_index_file(sha1, (reset_type == HARD), quiet)) + else if (reset_index_file(sha1, reset_type, quiet)) die("Could not reset index file to revision '%s'.", rev); /* Any resets update HEAD to the head being switched to, diff --git a/builtin-update-index.c b/builtin-update-index.c index 65d5775107..5604977505 100644 --- a/builtin-update-index.c +++ b/builtin-update-index.c @@ -486,7 +486,7 @@ static int unresolve_one(const char *path) static void read_head_pointers(void) { if (read_ref("HEAD", head_sha1)) - die("No HEAD -- no initial commit yet?\n"); + die("No HEAD -- no initial commit yet?"); if (read_ref("MERGE_HEAD", merge_head_sha1)) { fprintf(stderr, "Not in the middle of a merge.\n"); exit(0); @@ -315,7 +315,7 @@ static int git_tcp_connect_sock(char *host, int flags) /* Not numeric */ struct servent *se = getservbyname(port,"tcp"); if ( !se ) - die("Unknown port %s\n", port); + die("Unknown port %s", port); nport = se->s_port; } diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index e00454983e..3b25d48098 100755 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -1403,7 +1403,7 @@ _git_reset () local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) - __gitcomp "--mixed --hard --soft" + __gitcomp "--merge --mixed --hard --soft" return ;; esac @@ -716,7 +716,7 @@ static int socksetup(char *listen_addr, int listen_port, int **socklist_p) gai = getaddrinfo(listen_addr, pbuf, &hints, &ai0); if (gai) - die("getaddrinfo() failed: %s\n", gai_strerror(gai)); + die("getaddrinfo() failed: %s", gai_strerror(gai)); for (ai = ai0; ai; ai = ai->ai_next) { int sockfd; @@ -2039,7 +2039,7 @@ static void diff_fill_sha1_info(struct diff_filespec *one) if (lstat(one->path, &st) < 0) die("stat %s", one->path); if (index_path(one->sha1, one->path, &st, 0)) - die("cannot hash %s\n", one->path); + die("cannot hash %s", one->path); } } else diff --git a/git-mergetool.sh b/git-mergetool.sh index d4078a6aff..b2d53752ae 100755 --- a/git-mergetool.sh +++ b/git-mergetool.sh @@ -8,7 +8,7 @@ # at the discretion of Junio C Hamano. # -USAGE='[--tool=tool] [file to merge] ...' +USAGE='[--tool=tool] [-y|--no-prompt|--prompt] [file to merge] ...' SUBDIRECTORY_OK=Yes OPTIONS_SPEC= . git-sh-setup @@ -70,16 +70,16 @@ resolve_symlink_merge () { git checkout-index -f --stage=2 -- "$MERGED" git add -- "$MERGED" cleanup_temp_files --save-backup - return + return 0 ;; [rR]*) git checkout-index -f --stage=3 -- "$MERGED" git add -- "$MERGED" cleanup_temp_files --save-backup - return + return 0 ;; [aA]*) - exit 1 + return 1 ;; esac done @@ -97,15 +97,15 @@ resolve_deleted_merge () { [mMcC]*) git add -- "$MERGED" cleanup_temp_files --save-backup - return + return 0 ;; [dD]*) git rm -- "$MERGED" > /dev/null cleanup_temp_files - return + return 0 ;; [aA]*) - exit 1 + return 1 ;; esac done @@ -137,7 +137,7 @@ merge_file () { else echo "$MERGED: file does not need merging" fi - exit 1 + return 1 fi ext="$$$(expr "$MERGED" : '.*\(\.[^/]*\)$')" @@ -176,8 +176,10 @@ merge_file () { echo "Normal merge conflict for '$MERGED':" describe_file "$local_mode" "local" "$LOCAL" describe_file "$remote_mode" "remote" "$REMOTE" - printf "Hit return to start merge resolution tool (%s): " "$merge_tool" - read ans + if "$prompt" = true; then + printf "Hit return to start merge resolution tool (%s): " "$merge_tool" + read ans + fi case "$merge_tool" in kdiff3) @@ -267,7 +269,12 @@ merge_file () { if test "$status" -ne 0; then echo "merge of $MERGED failed" 1>&2 mv -- "$BACKUP" "$MERGED" - exit 1 + + if test "$merge_keep_temporaries" = "false"; then + cleanup_temp_files + fi + + return 1 fi if test "$merge_keep_backup" = "true"; then @@ -278,8 +285,11 @@ merge_file () { git add -- "$MERGED" cleanup_temp_files + return 0 } +prompt=$(git config --bool mergetool.prompt || echo true) + while test $# != 0 do case "$1" in @@ -295,6 +305,12 @@ do shift ;; esac ;; + -y|--no-prompt) + prompt=false + ;; + --prompt) + prompt=true + ;; --) shift break @@ -341,6 +357,22 @@ init_merge_tool_path() { fi } +prompt_after_failed_merge() { + while true; do + printf "Continue merging other unresolved paths (y/n) ? " + read ans + case "$ans" in + + [yY]*) + return 0 + ;; + + [nN]*) + return 1 + ;; + esac + done +} if test -z "$merge_tool"; then merge_tool=`git config merge.tool` @@ -389,6 +421,7 @@ else init_merge_tool_path "$merge_tool" merge_keep_backup="$(git config --bool merge.keepBackup || echo true)" + merge_keep_temporaries="$(git config --bool mergetool.keepTemporaries || echo false)" if test -z "$merge_tool_cmd" && ! type "$merge_tool_path" > /dev/null 2>&1; then echo "The merge tool $merge_tool is not available as '$merge_tool_path'" @@ -400,27 +433,44 @@ else fi fi +last_status=0 +rollup_status=0 if test $# -eq 0 ; then - files=`git ls-files -u | sed -e 's/^[^ ]* //' | sort -u` - if test -z "$files" ; then - echo "No files need merging" - exit 0 + files=`git ls-files -u | sed -e 's/^[^ ]* //' | sort -u` + if test -z "$files" ; then + echo "No files need merging" + exit 0 + fi + echo Merging the files: "$files" + git ls-files -u | + sed -e 's/^[^ ]* //' | + sort -u | + while IFS= read i + do + if test $last_status -ne 0; then + prompt_after_failed_merge < /dev/tty || exit 1 fi - echo Merging the files: "$files" - git ls-files -u | - sed -e 's/^[^ ]* //' | - sort -u | - while IFS= read i - do - printf "\n" - merge_file "$i" < /dev/tty > /dev/tty - done + printf "\n" + merge_file "$i" < /dev/tty > /dev/tty + last_status=$? + if test $last_status -ne 0; then + rollup_status=1 + fi + done else - while test $# -gt 0; do - printf "\n" - merge_file "$1" - shift - done + while test $# -gt 0; do + if test $last_status -ne 0; then + prompt_after_failed_merge || exit 1 + fi + printf "\n" + merge_file "$1" + last_status=$? + if test $last_status -ne 0; then + rollup_status=1 + fi + shift + done fi -exit 0 + +exit $rollup_status @@ -158,7 +158,7 @@ static int handle_alias(int *argcp, const char ***argv) if (ret >= 0 && WIFEXITED(ret) && WEXITSTATUS(ret) != 127) exit(WEXITSTATUS(ret)); - die("Failed to run '%s' when expanding alias '%s'\n", + die("Failed to run '%s' when expanding alias '%s'", alias_string + 1, alias_command); } count = split_cmdline(alias_string, &new_argv); @@ -428,9 +428,8 @@ int main(int argc, const char **argv) * name, and the dirname as the default exec_path * if we don't have anything better. */ - do - --slash; - while (cmd <= slash && !is_dir_sep(*slash)); + while (cmd <= slash && !is_dir_sep(*slash)) + slash--; if (cmd <= slash) { *slash++ = 0; git_set_argv0_path(cmd); diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 99f71b47c2..7999bb37d3 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -6146,8 +6146,8 @@ XML } my $path = esc_html(chop_str($proj{'path'}, 25, 5)); - my $rss = "$my_url?p=$proj{'path'};a=rss"; - my $html = "$my_url?p=$proj{'path'};a=summary"; + my $rss = href('project' => $proj{'path'}, 'action' => 'rss', -full => 1); + my $html = href('project' => $proj{'path'}, 'action' => 'summary', -full => 1); print "<outline type=\"rss\" text=\"$path\" title=\"$path\" xmlUrl=\"$rss\" htmlUrl=\"$html\"/>\n"; } print <<XML; @@ -395,7 +395,7 @@ static int match_expr_eval(struct grep_opt *o, h |= match_expr_eval(o, x->u.binary.right, bol, eol, ctx, 1); break; default: - die("Unexpected node type (internal error) %d\n", x->node); + die("Unexpected node type (internal error) %d", x->node); } if (collect_hits) x->hit |= h; diff --git a/imap-send.c b/imap-send.c index 3703dbd1af..c3fa0df855 100644 --- a/imap-send.c +++ b/imap-send.c @@ -115,9 +115,9 @@ static int nfvasprintf(char **strp, const char *fmt, va_list ap) len = vsnprintf(tmp, sizeof(tmp), fmt, ap); if (len < 0) - die("Fatal: Out of memory\n"); + die("Fatal: Out of memory"); if (len >= sizeof(tmp)) - die("imap command overflow !\n"); + die("imap command overflow!"); *strp = xmemdupz(tmp, len); return len; } @@ -482,7 +482,7 @@ static int nfsnprintf(char *buf, int blen, const char *fmt, ...) va_start(va, fmt); if (blen <= 0 || (unsigned)(ret = vsnprintf(buf, blen, fmt, va)) >= (unsigned)blen) - die("Fatal: buffer too small. Please report a bug.\n"); + die("Fatal: buffer too small. Please report a bug."); va_end(va); return ret; } diff --git a/index-pack.c b/index-pack.c index 60ed41a993..2931511e8c 100644 --- a/index-pack.c +++ b/index-pack.c @@ -178,7 +178,7 @@ static char *open_pack_file(char *pack_name) } else output_fd = open(pack_name, O_CREAT|O_EXCL|O_RDWR, 0600); if (output_fd < 0) - die("unable to create %s: %s\n", pack_name, strerror(errno)); + die("unable to create %s: %s", pack_name, strerror(errno)); pack_fd = output_fd; } else { input_fd = open(pack_name, O_RDONLY); diff --git a/pack-redundant.c b/pack-redundant.c index 25b81a445c..e93eb966e2 100644 --- a/pack-redundant.c +++ b/pack-redundant.c @@ -463,7 +463,7 @@ static void minimize(struct pack_list **min) pll_free(perm_all); } if (perm_ok == NULL) - die("Internal error: No complete sets found!\n"); + die("Internal error: No complete sets found!"); /* find the permutation with the smallest size */ perm = perm_ok; @@ -573,14 +573,14 @@ static struct pack_list * add_pack_file(char *filename) struct packed_git *p = packed_git; if (strlen(filename) < 40) - die("Bad pack filename: %s\n", filename); + die("Bad pack filename: %s", filename); while (p) { if (strstr(p->pack_name, filename)) return add_pack(p); p = p->next; } - die("Filename %s not found in packed_git\n", filename); + die("Filename %s not found in packed_git", filename); } static void load_all(void) @@ -636,7 +636,7 @@ int main(int argc, char **argv) add_pack_file(*(argv + i++)); if (local_packs == NULL) - die("Zero packs found!\n"); + die("Zero packs found!"); load_all_objects(); diff --git a/t/t2011-checkout-invalid-head.sh b/t/t2011-checkout-invalid-head.sh index 764bb0a6bc..15ebdc26eb 100755 --- a/t/t2011-checkout-invalid-head.sh +++ b/t/t2011-checkout-invalid-head.sh @@ -10,6 +10,10 @@ test_expect_success 'setup' ' git commit -m initial ' +test_expect_success 'checkout should not start branch from a tree' ' + test_must_fail git checkout -b newbranch master^{tree} +' + test_expect_success 'checkout master from invalid HEAD' ' echo 0000000000000000000000000000000000000000 >.git/HEAD && git checkout master -- diff --git a/t/t4129-apply-samemode.sh b/t/t4129-apply-samemode.sh new file mode 100755 index 0000000000..adfcbb5a3b --- /dev/null +++ b/t/t4129-apply-samemode.sh @@ -0,0 +1,62 @@ +#!/bin/sh + +test_description='applying patch with mode bits' + +. ./test-lib.sh + +test_expect_success setup ' + echo original >file && + git add file && + test_tick && + git commit -m initial && + git tag initial && + echo modified >file && + git diff --stat -p >patch-0.txt && + chmod +x file && + git diff --stat -p >patch-1.txt +' + +test_expect_success 'same mode (no index)' ' + git reset --hard && + chmod +x file && + git apply patch-0.txt && + test -x file +' + +test_expect_success 'same mode (with index)' ' + git reset --hard && + chmod +x file && + git add file && + git apply --index patch-0.txt && + test -x file && + git diff --exit-code +' + +test_expect_success 'same mode (index only)' ' + git reset --hard && + chmod +x file && + git add file && + git apply --cached patch-0.txt && + git ls-files -s file | grep "^100755" +' + +test_expect_success 'mode update (no index)' ' + git reset --hard && + git apply patch-1.txt && + test -x file +' + +test_expect_success 'mode update (with index)' ' + git reset --hard && + git apply --index patch-1.txt && + test -x file && + git diff --exit-code +' + +test_expect_success 'mode update (index only)' ' + git reset --hard && + git apply --cached patch-1.txt && + git ls-files -s file | grep "^100755" +' + +test_done diff --git a/t/t5302-pack-index.sh b/t/t5302-pack-index.sh index 884e24253a..e6f70d474f 100755 --- a/t/t5302-pack-index.sh +++ b/t/t5302-pack-index.sh @@ -10,6 +10,7 @@ test_expect_success \ 'setup' \ 'rm -rf .git git init && + git config pack.threads 1 && i=1 && while test $i -le 100 do |