Merge 'http-msys-paths' into HEAD
diff --git a/Documentation/config.txt b/Documentation/config.txt index c55c22a..a82b1f1 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt
@@ -212,6 +212,12 @@ will probe and set core.fileMode false if appropriate when the repository is created. +core.hideDotFiles:: + (Windows-only) If true (which is the default), mark newly-created + directories and files whose name starts with a dot as hidden. + If 'dotGitOnly', only the .git/ directory is hidden, but no other + files starting with a dot. + core.ignorecase:: If true, this option enables various workarounds to enable Git to work better on filesystems that are not case sensitive, @@ -776,6 +782,7 @@ instead of merging the default branch from the default remote when "git pull" is run. See "pull.rebase" for doing this in a non branch-specific manner. + When the value is `interactive`, the rebase is run in interactive mode. + When preserve, also pass `--preserve-merges` along to 'git rebase' so that locally committed merge commits will not be flattened @@ -2076,6 +2083,11 @@ print a warning of such a push to stderr, but allow the push to proceed. If set to false or "ignore", allow such pushes with no message. Defaults to "refuse". ++ +There are two more options that are meant for Git experts: "updateInstead" +which will run `read-tree -u -m HEAD` and "detachInstead" which will detach +the HEAD so it does not need to change. Both options come with their own +set of possible *complications*, but can be appropriate in rare workflows. receive.denyNonFastForwards:: If set to true, git-receive-pack will deny a ref update which is
diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt index 200eb22..2f626dc 100644 --- a/Documentation/git-pull.txt +++ b/Documentation/git-pull.txt
@@ -104,7 +104,7 @@ include::merge-options.txt[] -r:: ---rebase[=false|true|preserve]:: +--rebase[=false|true|preserve|interactive]:: When true, rebase the current branch on top of the upstream branch after fetching. If there is a remote-tracking branch corresponding to the upstream branch and the upstream branch @@ -117,6 +117,8 @@ + When false, merge the current branch into the upstream branch. + +When `interactive`, enable the interactive mode of rebase. ++ See `pull.rebase`, `branch.<name>.rebase` and `branch.autosetuprebase` in linkgit:git-config[1] if you want to make `git pull` always use `--rebase` instead of merging.
diff --git a/Makefile b/Makefile index 2320de5..b4d3c06 100644 --- a/Makefile +++ b/Makefile
@@ -1148,13 +1148,11 @@ REMOTE_CURL_NAMES = $(REMOTE_CURL_PRIMARY) $(REMOTE_CURL_ALIASES) PROGRAM_OBJS += http-fetch.o PROGRAMS += $(REMOTE_CURL_NAMES) - curl_check := $(shell (echo 070908; curl-config --vernum) 2>/dev/null | sort -r | sed -ne 2p) - ifeq "$(curl_check)" "070908" - ifndef NO_EXPAT + ifndef NO_EXPAT + ifndef NO_CURL_MULTI PROGRAM_OBJS += http-push.o endif - endif - ifndef NO_EXPAT + ifdef EXPATDIR BASIC_CFLAGS += -I$(EXPATDIR)/include EXPAT_LIBEXPAT = -L$(EXPATDIR)/$(lib) $(CC_LD_DYNPATH)$(EXPATDIR)/$(lib) -lexpat @@ -1479,6 +1477,9 @@ COMPAT_CFLAGS += -Icompat/regex COMPAT_OBJS += compat/regex/regex.o endif +ifdef NATIVE_CRLF + BASIC_CFLAGS += -DNATIVE_CRLF +endif ifdef USE_NED_ALLOCATOR COMPAT_CFLAGS += -Icompat/nedmalloc
diff --git a/builtin/clone.c b/builtin/clone.c index bbd169c..1dfd21d 100644 --- a/builtin/clone.c +++ b/builtin/clone.c
@@ -947,7 +947,9 @@ } if (!is_local && !complete_refs_before_fetch) - transport_fetch_refs(transport, mapped_refs); + if (transport_fetch_refs(transport, mapped_refs)) + die(_("could not fetch refs from %s"), + transport->url); remote_head = find_ref_by_name(refs, "HEAD"); remote_head_points_at =
diff --git a/builtin/fast-export.c b/builtin/fast-export.c index 92b4624..a230c45 100644 --- a/builtin/fast-export.c +++ b/builtin/fast-export.c
@@ -571,9 +571,20 @@ } } +static void handle_reset(const char *name, struct object *object) +{ + int mark = get_object_mark(object); + + if (mark) + printf("reset %s\nfrom :%d\n\n", name, + get_object_mark(object)); + else + printf("reset %s\nfrom %s\n\n", name, + sha1_to_hex(object->sha1)); +} + static void handle_tags_and_duplicates(void) { - struct commit *commit; int i; for (i = extra_refs.nr - 1; i >= 0; i--) { @@ -585,9 +596,7 @@ break; case OBJ_COMMIT: /* create refs pointing to already seen commits */ - commit = (struct commit *)object; - printf("reset %s\nfrom :%d\n\n", name, - get_object_mark(&commit->object)); + handle_reset(name, object); show_progress(); break; }
diff --git a/builtin/init-db.c b/builtin/init-db.c index 56f85e2..ca433df 100644 --- a/builtin/init-db.c +++ b/builtin/init-db.c
@@ -385,6 +385,7 @@ check_repository_format(); reinit = create_default_files(template_dir); + mark_as_git_dir(get_git_dir()); create_object_directory();
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index f93ac45..2fb7ed1 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c
@@ -22,7 +22,9 @@ DENY_UNCONFIGURED, DENY_IGNORE, DENY_WARN, - DENY_REFUSE + DENY_REFUSE, + DENY_UPDATE_INSTEAD, + DENY_DETACH_INSTEAD, }; static int deny_deletes; @@ -100,7 +102,12 @@ } if (!strcmp(var, "receive.denycurrentbranch")) { - deny_current_branch = parse_deny_action(var, value); + if (value && !strcasecmp(value, "updateinstead")) + deny_current_branch = DENY_UPDATE_INSTEAD; + else if (value && !strcasecmp(value, "detachinstead")) + deny_current_branch = DENY_DETACH_INSTEAD; + else + deny_current_branch = parse_deny_action(var, value); return 0; } @@ -468,6 +475,44 @@ return 0; } +static void merge_worktree(unsigned char *sha1) +{ + const char *update_refresh[] = { + "update-index", "--ignore-submodules", "--refresh", NULL + }; + const char *read_tree[] = { + "read-tree", "-u", "-m", sha1_to_hex(sha1), NULL + }; + struct child_process child; + struct strbuf git_env = STRBUF_INIT; + const char *env[2]; + + if (is_bare_repository()) + die ("denyCurrentBranch = updateInstead needs a worktree"); + + strbuf_addf(&git_env, "GIT_DIR=%s", absolute_path(get_git_dir())); + env[0] = git_env.buf; + env[1] = NULL; + + memset(&child, 0, sizeof(child)); + child.argv = update_refresh; + child.env = env; + child.dir = git_work_tree_cfg ? git_work_tree_cfg : ".."; + child.stdout_to_stderr = 1; + child.git_cmd = 1; + if (run_command(&child)) + die ("Could not refresh the index"); + + child.argv = read_tree; + child.no_stdin = 1; + child.no_stdout = 1; + child.stdout_to_stderr = 0; + if (run_command(&child)) + die ("Could not merge working tree with new HEAD. Good luck."); + + strbuf_release(&git_env); +} + static const char *update(struct command *cmd, struct shallow_info *si) { const char *name = cmd->ref_name; @@ -499,6 +544,13 @@ if (deny_current_branch == DENY_UNCONFIGURED) refuse_unconfigured_deny(); return "branch is currently checked out"; + case DENY_UPDATE_INSTEAD: + merge_worktree(new_sha1); + break; + case DENY_DETACH_INSTEAD: + update_ref("push into current branch (detach)", "HEAD", + old_sha1, NULL, REF_NODEREF, UPDATE_REFS_DIE_ON_ERR); + break; } } @@ -527,6 +579,8 @@ refuse_unconfigured_deny_delete_current(); rp_error("refusing to delete the current branch: %s", name); return "deletion of the current branch prohibited"; + default: + die ("Invalid denyDeleteCurrent setting"); } } }
diff --git a/builtin/remote.c b/builtin/remote.c index 9a4640d..eee9ef4 100644 --- a/builtin/remote.c +++ b/builtin/remote.c
@@ -243,7 +243,7 @@ struct branch_info { char *remote_name; struct string_list merge; - int rebase; + enum { NO_REBASE, NORMAL_REBASE, INTERACTIVE_REBASE } rebase; }; static struct string_list branch_list; @@ -304,6 +304,8 @@ info->rebase = v; else if (!strcmp(value, "preserve")) info->rebase = 1; + else if (!strcmp(value, "interactive")) + info->rebase = INTERACTIVE_REBASE; } } return 0; @@ -999,7 +1001,9 @@ printf(" %-*s ", show_info->width, item->string); if (branch_info->rebase) { - printf_ln(_("rebases onto remote %s"), merge->items[0].string); + printf_ln(_(branch_info->rebase == INTERACTIVE_REBASE ? + "rebases interactively onto remote %s" : + "rebases onto remote %s"), merge->items[0].string); return 0; } else if (show_info->any_rebase) { printf_ln(_(" merges with remote %s"), merge->items[0].string);
diff --git a/cache.h b/cache.h index fcb511d..cf5431b 100644 --- a/cache.h +++ b/cache.h
@@ -641,6 +641,13 @@ extern char comment_line_char; extern int auto_comment_line_char; +enum hide_dotfiles_type { + HIDE_DOTFILES_FALSE = 0, + HIDE_DOTFILES_TRUE, + HIDE_DOTFILES_DOTGITONLY, +}; +extern enum hide_dotfiles_type hide_dotfiles; + enum branch_track { BRANCH_TRACK_UNSPECIFIED = -1, BRANCH_TRACK_NEVER = 0,
diff --git a/compat/mingw.c b/compat/mingw.c index c5c37e5..f7b6b26 100644 --- a/compat/mingw.c +++ b/compat/mingw.c
@@ -7,6 +7,7 @@ #include "../cache.h" static const int delay[] = { 0, 1, 10, 20, 40 }; +unsigned int _CRT_fmode = _O_BINARY; int err_win_to_posix(DWORD winerr) { @@ -284,6 +285,27 @@ return ret; } +static int make_hidden(const wchar_t *path) +{ + DWORD attribs = GetFileAttributesW(path); + if (SetFileAttributesW(path, FILE_ATTRIBUTE_HIDDEN | attribs)) + return 0; + errno = err_win_to_posix(GetLastError()); + return -1; +} + +void mingw_mark_as_git_dir(const char *dir) +{ + wchar_t wdir[MAX_PATH]; + if (hide_dotfiles != HIDE_DOTFILES_FALSE && !is_bare_repository()) + if (xutftowcs_path(wdir, dir) < 0 || make_hidden(wdir)) + warning("Failed to make '%s' hidden", dir); + git_config_set("core.hideDotFiles", + hide_dotfiles == HIDE_DOTFILES_FALSE ? "false" : + (hide_dotfiles == HIDE_DOTFILES_DOTGITONLY ? + "dotGitOnly" : "true")); +} + int mingw_mkdir(const char *path, int mode) { int ret; @@ -291,6 +313,16 @@ if (xutftowcs_path(wpath, path) < 0) return -1; ret = _wmkdir(wpath); + if (!ret && hide_dotfiles == HIDE_DOTFILES_TRUE) { + /* + * In Windows a file or dir starting with a dot is not + * automatically hidden. So lets mark it as hidden when + * such a directory is created. + */ + const char *start = basename((char*)path); + if (*start == '.') + return make_hidden(wpath); + } return ret; } @@ -317,6 +349,17 @@ if (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY)) errno = EISDIR; } + if ((oflags & O_CREAT) && fd >= 0 && + hide_dotfiles == HIDE_DOTFILES_TRUE) { + /* + * In Windows a file or dir starting with a dot is not + * automatically hidden. So lets mark it as hidden when + * such a file is created. + */ + const char *start = basename((char*)filename); + if (*start == '.' && make_hidden(wfilename)) + warning("Could not mark '%s' as hidden.", filename); + } return fd; } @@ -348,27 +391,39 @@ #undef fopen FILE *mingw_fopen (const char *filename, const char *otype) { + int hide = 0; FILE *file; wchar_t wfilename[MAX_PATH], wotype[4]; + if (hide_dotfiles == HIDE_DOTFILES_TRUE && + basename((char*)filename)[0] == '.') + hide = access(filename, F_OK); if (filename && !strcmp(filename, "/dev/null")) filename = "nul"; if (xutftowcs_path(wfilename, filename) < 0 || xutftowcs(wotype, otype, ARRAY_SIZE(wotype)) < 0) return NULL; file = _wfopen(wfilename, wotype); + if (file && hide && make_hidden(wfilename)) + warning("Could not mark '%s' as hidden.", filename); return file; } FILE *mingw_freopen (const char *filename, const char *otype, FILE *stream) { + int hide = 0; FILE *file; wchar_t wfilename[MAX_PATH], wotype[4]; + if (hide_dotfiles == HIDE_DOTFILES_TRUE && + basename((char*)filename)[0] == '.') + hide = access(filename, F_OK); if (filename && !strcmp(filename, "/dev/null")) filename = "nul"; if (xutftowcs_path(wfilename, filename) < 0 || xutftowcs(wotype, otype, ARRAY_SIZE(wotype)) < 0) return NULL; file = _wfreopen(wfilename, wotype, stream); + if (file && hide && make_hidden(wfilename)) + warning("Could not mark '%s' as hidden.", filename); return file; }
diff --git a/config.c b/config.c index 058505c..bd851a0 100644 --- a/config.c +++ b/config.c
@@ -872,6 +872,15 @@ return 0; } + if (!strcmp(var, "core.hidedotfiles")) { + if (value && !strcasecmp(value, "dotgitonly")) { + hide_dotfiles = HIDE_DOTFILES_DOTGITONLY; + return 0; + } + hide_dotfiles = git_config_bool(var, value); + return 0; + } + /* Add other config variables here and to Documentation/config.txt. */ return 0; }
diff --git a/configure.ac b/configure.ac index 4b1ae7c..890ef61 100644 --- a/configure.ac +++ b/configure.ac
@@ -521,6 +521,17 @@ [NO_CURL=], [NO_CURL=YesPlease]) +if test -z "$NO_CURL"; then + +AC_CHECK_DECLS([curl_multi_init], +[NO_CURL_MULTI=], +[NO_CURL_MULTI=UnfortunatelyYes], +[[#include <curl/curl.h>]]) + +GIT_CONF_SUBST([NO_CURL_MULTI]) + +fi + GIT_UNSTASH_FLAGS($CURLDIR) GIT_CONF_SUBST([NO_CURL])
diff --git a/contrib/credential/wincred/git-credential-wincred.c b/contrib/credential/wincred/git-credential-wincred.c index a1d38f0..219999d 100644 --- a/contrib/credential/wincred/git-credential-wincred.c +++ b/contrib/credential/wincred/git-credential-wincred.c
@@ -94,6 +94,12 @@ static void write_item(const char *what, LPCWSTR wbuf, int wlen) { char *buf; + + if (!wbuf || !wlen) { + printf("%s=\n", what); + return; + } + int len = WideCharToMultiByte(CP_UTF8, 0, wbuf, wlen, NULL, 0, NULL, FALSE); buf = xmalloc(len); @@ -141,7 +147,7 @@ static int match_cred(const CREDENTIALW *cred) { LPCWSTR target = cred->TargetName; - if (wusername && wcscmp(wusername, cred->UserName)) + if (wusername && wcscmp(wusername, cred->UserName ? cred->UserName : L"")) return 0; return match_part(&target, L"git", L":") && @@ -164,7 +170,7 @@ for (i = 0; i < num_creds; ++i) if (match_cred(creds[i])) { write_item("username", creds[i]->UserName, - wcslen(creds[i]->UserName)); + creds[i]->UserName ? wcslen(creds[i]->UserName) : 0); write_item("password", (LPCWSTR)creds[i]->CredentialBlob, creds[i]->CredentialBlobSize / sizeof(WCHAR));
diff --git a/environment.c b/environment.c index 565f652..2fd3830 100644 --- a/environment.c +++ b/environment.c
@@ -63,6 +63,7 @@ int precomposed_unicode = -1; /* see probe_utf8_pathname_composition() */ struct startup_info *startup_info; unsigned long pack_size_limit_cfg; +enum hide_dotfiles_type hide_dotfiles = HIDE_DOTFILES_DOTGITONLY; /* * The character that begins a commented line in user-editable file
diff --git a/git-am.sh b/git-am.sh index ee61a77..98f8b47 100755 --- a/git-am.sh +++ b/git-am.sh
@@ -184,7 +184,9 @@ } clean_abort () { - test $# = 0 || echo >&2 "$@" + test $# = 0 || cat >&2 <<EOF +$@ +EOF rm -fr "$dotest" exit 1 } @@ -593,7 +595,8 @@ '') files=$(git ls-files) ;; ?*) - files=$(git diff-index --cached --name-only HEAD --) ;; + files=$(git diff-index --ignore-submodules --cached \ + --name-only HEAD --) ;; esac || exit if test "$files" then @@ -767,7 +770,8 @@ case "$resolved$interactive" in tt) # This is used only for interactive view option. - git diff-index -p --cached HEAD -- >"$dotest/patch" + git diff-index --ignore-submodules -p --cached \ + HEAD -- >"$dotest/patch" ;; esac esac @@ -843,7 +847,7 @@ # trust what the user has in the index file and the # working tree. resolved= - git diff-index --quiet --cached HEAD -- && { + git diff-index --ignore-submodules --quiet --cached HEAD -- && { gettextln "No changes - did you forget to use 'git add'? If there is nothing left to stage, chances are that something else already introduced the same changes; you might want to skip this patch." @@ -867,7 +871,8 @@ then # Applying the patch to an earlier tree and merging the # result may have produced the same tree as ours. - git diff-index --quiet --cached HEAD -- && { + git diff-index --ignore-submodules --quiet --cached \ + HEAD -- && { say "$(gettext "No changes -- Patch already applied.")" go_next continue
diff --git a/git-compat-util.h b/git-compat-util.h index f587749..fc9beb0 100644 --- a/git-compat-util.h +++ b/git-compat-util.h
@@ -790,4 +790,8 @@ #define gmtime_r git_gmtime_r #endif +#ifndef mark_as_git_dir +#define mark_as_git_dir(x) /* noop */ +#endif + #endif
diff --git a/git-gui/Makefile b/git-gui/Makefile index cde8b2e..e10b1d1 100644 --- a/git-gui/Makefile +++ b/git-gui/Makefile
@@ -290,6 +290,7 @@ $(QUIET)$(INSTALL_D0)'$(DESTDIR_SQ)$(gitexecdir_SQ)' $(INSTALL_D1) $(QUIET)$(INSTALL_X0)git-gui $(INSTALL_X1) '$(DESTDIR_SQ)$(gitexecdir_SQ)' $(QUIET)$(INSTALL_X0)git-gui--askpass $(INSTALL_X1) '$(DESTDIR_SQ)$(gitexecdir_SQ)' + $(QUIET)$(INSTALL_X0)git-gui--askyesno $(INSTALL_X1) '$(DESTDIR_SQ)$(gitexecdir_SQ)' $(QUIET)$(foreach p,$(GITGUI_BUILT_INS), $(INSTALL_L0)'$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' $(INSTALL_L1)'$(DESTDIR_SQ)$(gitexecdir_SQ)/git-gui' $(INSTALL_L2)'$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' $(INSTALL_L3) &&) true ifdef GITGUI_WINDOWS_WRAPPER $(QUIET)$(INSTALL_R0)git-gui.tcl $(INSTALL_R1) '$(DESTDIR_SQ)$(gitexecdir_SQ)' @@ -308,6 +309,7 @@ $(QUIET)$(CLEAN_DST) '$(DESTDIR_SQ)$(gitexecdir_SQ)' $(QUIET)$(REMOVE_F0)'$(DESTDIR_SQ)$(gitexecdir_SQ)'/git-gui $(REMOVE_F1) $(QUIET)$(REMOVE_F0)'$(DESTDIR_SQ)$(gitexecdir_SQ)'/git-gui--askpass $(REMOVE_F1) + $(QUIET)$(REMOVE_F0)'$(DESTDIR_SQ)$(gitexecdir_SQ)'/git-gui--askyesno $(REMOVE_F1) $(QUIET)$(foreach p,$(GITGUI_BUILT_INS), $(REMOVE_F0)'$(DESTDIR_SQ)$(gitexecdir_SQ)'/$p $(REMOVE_F1) &&) true ifdef GITGUI_WINDOWS_WRAPPER $(QUIET)$(REMOVE_F0)'$(DESTDIR_SQ)$(gitexecdir_SQ)'/git-gui.tcl $(REMOVE_F1)
diff --git a/git-gui/git-gui--askyesno b/git-gui/git-gui--askyesno new file mode 100755 index 0000000..2a6e6fd --- /dev/null +++ b/git-gui/git-gui--askyesno
@@ -0,0 +1,51 @@ +#!/bin/sh +# Tcl ignores the next line -*- tcl -*- \ +exec wish "$0" -- "$@" + +# This is an implementation of a simple yes no dialog +# which is injected into the git commandline by git gui +# in case a yesno question needs to be answered. + +set NS {} +set use_ttk [package vsatisfies [package provide Tk] 8.5] +if {$use_ttk} { + set NS ttk +} + +if {$argc < 1} { + puts stderr "Usage: $argv0 <question>" + exit 1 +} else { + set prompt [join $argv " "] +} + +${NS}::frame .t +${NS}::label .t.m -text $prompt -justify center -width 40 +.t.m configure -wraplength 400 +pack .t.m -side top -fill x -padx 20 -pady 20 -expand 1 +pack .t -side top -fill x -ipadx 20 -ipady 20 -expand 1 + +${NS}::frame .b +${NS}::frame .b.left -width 200 +${NS}::button .b.yes -text Yes -command yes +${NS}::button .b.no -text No -command no + + +pack .b.left -side left -expand 1 -fill x +pack .b.yes -side left -expand 1 +pack .b.no -side right -expand 1 -ipadx 5 +pack .b -side bottom -fill x -ipadx 20 -ipady 15 + +bind . <Key-Return> {exit 0} +bind . <Key-Escape> {exit 1} + +proc no {} { + exit 1 +} + +proc yes {} { + exit 0 +} + +wm title . "Question?" +tk::PlaceWindow .
diff --git a/git-gui/git-gui.sh b/git-gui/git-gui.sh index b186329..3f1fe0a 100755 --- a/git-gui/git-gui.sh +++ b/git-gui/git-gui.sh
@@ -548,6 +548,9 @@ _trace_exec [concat $opt $cmdp $args] set result [eval exec $opt $cmdp $args] + if {[encoding system] != "utf-8"} { + set result [encoding convertfrom utf-8 [encoding convertto $result]] + } if {$::_trace} { puts stderr "< $result" } @@ -1104,7 +1107,7 @@ [list git_read config] \ $args \ [list --null --list]] - fconfigure $fd_rc -translation binary + fconfigure $fd_rc -translation binary -encoding utf-8 set buf [read $fd_rc] close $fd_rc } @@ -1241,6 +1244,12 @@ if {![info exists env(SSH_ASKPASS)]} { set env(SSH_ASKPASS) [gitexec git-gui--askpass] } +if {![info exists env(GIT_ASKPASS)]} { + set env(GIT_ASKPASS) [gitexec git-gui--askpass] +} +if {![info exists env(GIT_ASK_YESNO)]} { + set env(GIT_ASK_YESNO) [gitexec git-gui--askyesno] +} ###################################################################### ## @@ -1337,9 +1346,6 @@ set _reponame [lindex $_reponame end] } -set env(GIT_DIR) $_gitdir -set env(GIT_WORK_TREE) $_gitworktree - ###################################################################### ## ## global init @@ -1682,7 +1688,7 @@ set i [split [string range $buf_rdi $c [expr {$z1 - 2}]] { }] set p [string range $buf_rdi $z1 [expr {$z2 - 1}]] merge_state \ - [encoding convertfrom $p] \ + [encoding convertfrom utf-8 $p] \ [lindex $i 4]? \ [list [lindex $i 0] [lindex $i 2]] \ [list] @@ -1715,7 +1721,7 @@ set i [split [string range $buf_rdf $c [expr {$z1 - 2}]] { }] set p [string range $buf_rdf $z1 [expr {$z2 - 1}]] merge_state \ - [encoding convertfrom $p] \ + [encoding convertfrom utf-8 $p] \ ?[lindex $i 4] \ [list] \ [list [lindex $i 0] [lindex $i 2]] @@ -1738,7 +1744,7 @@ set pck [split $buf_rlo "\0"] set buf_rlo [lindex $pck end] foreach p [lrange $pck 0 end-1] { - set p [encoding convertfrom $p] + set p [encoding convertfrom utf-8 $p] if {[string index $p end] eq {/}} { set p [string range $p 0 end-1] } @@ -2159,7 +2165,7 @@ proc do_gitk {revs {is_submodule false}} { global current_diff_path file_states current_diff_side ui_index - global _gitdir _gitworktree + global _gitworktree # -- Always start gitk through whatever we were loaded with. This # lets us bypass using shell process on Windows systems. @@ -2171,12 +2177,19 @@ } else { global env + if {[info exists env(GIT_DIR)]} { + set old_GIT_DIR $env(GIT_DIR) + } else { + set old_GIT_DIR {} + } + set pwd [pwd] if {!$is_submodule} { if {![is_bare]} { cd $_gitworktree } + set env(GIT_DIR) [file normalize [gitdir]] } else { cd $current_diff_path if {$revs eq {--}} { @@ -2197,18 +2210,15 @@ } set revs $old_sha1...$new_sha1 } - # GIT_DIR and GIT_WORK_TREE for the submodule are not the ones - # we've been using for the main repository, so unset them. - # TODO we could make life easier (start up faster?) for gitk - # by setting these to the appropriate values to allow gitk - # to skip the heuristics to find their proper value - unset env(GIT_DIR) - unset env(GIT_WORK_TREE) + if {[info exists env(GIT_DIR)]} { + unset env(GIT_DIR) + } } eval exec $cmd $revs "--" "--" & - set env(GIT_DIR) $_gitdir - set env(GIT_WORK_TREE) $_gitworktree + if {$old_GIT_DIR ne {}} { + set env(GIT_DIR) $old_GIT_DIR + } cd $pwd ui_status $::starting_gitk_msg @@ -2229,20 +2239,22 @@ error_popup [mc "Couldn't find git gui in PATH"] } else { global env - global _gitdir _gitworktree - # see note in do_gitk about unsetting these vars when - # running tools in a submodule - unset env(GIT_DIR) - unset env(GIT_WORK_TREE) + if {[info exists env(GIT_DIR)]} { + set old_GIT_DIR $env(GIT_DIR) + unset env(GIT_DIR) + } else { + set old_GIT_DIR {} + } set pwd [pwd] cd $current_diff_path eval exec $exe gui & - set env(GIT_DIR) $_gitdir - set env(GIT_WORK_TREE) $_gitworktree + if {$old_GIT_DIR ne {}} { + set env(GIT_DIR) $old_GIT_DIR + } cd $pwd ui_status $::starting_gitk_msg
diff --git a/git-gui/lib/browser.tcl b/git-gui/lib/browser.tcl index 0328338..555db89 100644 --- a/git-gui/lib/browser.tcl +++ b/git-gui/lib/browser.tcl
@@ -197,7 +197,7 @@ $w conf -state disabled set fd [git_read ls-tree -z $tree_id] - fconfigure $fd -blocking 0 -translation binary -encoding binary + fconfigure $fd -blocking 0 -translation binary -encoding utf-8 fileevent $fd readable [cb _read $fd] }
diff --git a/git-gui/lib/index.tcl b/git-gui/lib/index.tcl index 74a81a7..d10ffe9 100644 --- a/git-gui/lib/index.tcl +++ b/git-gui/lib/index.tcl
@@ -115,7 +115,7 @@ set info [lindex $s 2] if {$info eq {}} continue - puts -nonewline $fd "$info\t[encoding convertto $path]\0" + puts -nonewline $fd "$info\t[encoding convertto utf-8 $path]\0" display_file $path $new } @@ -186,7 +186,7 @@ ?M {set new M_} ?? {continue} } - puts -nonewline $fd "[encoding convertto $path]\0" + puts -nonewline $fd "[encoding convertto utf-8 $path]\0" display_file $path $new } @@ -247,7 +247,7 @@ ?M - ?T - ?D { - puts -nonewline $fd "[encoding convertto $path]\0" + puts -nonewline $fd "[encoding convertto utf-8 $path]\0" display_file $path ?_ } }
diff --git a/git-merge-octopus.sh b/git-merge-octopus.sh index 8643f74..2226eeb 100755 --- a/git-merge-octopus.sh +++ b/git-merge-octopus.sh
@@ -71,7 +71,9 @@ case "$LF$common$LF" in *"$LF$SHA1$LF"*) - echo "Already up-to-date with $pretty_name" + cat << EOF +Already up-to-date with $pretty_name +EOF continue ;; esac @@ -83,7 +85,9 @@ # tree as the intermediate result of the merge. # We still need to count this as part of the parent set. - echo "Fast-forwarding to: $pretty_name" + cat << EOF +Fast-forwarding to: $pretty_name +EOF git read-tree -u -m $head $SHA1 || exit MRC=$SHA1 MRT=$(git write-tree) continue @@ -91,7 +95,9 @@ NON_FF_MERGE=1 - echo "Trying simple merge with $pretty_name" + cat << EOF +Trying simple merge with $pretty_name +EOF git read-tree -u -m --aggressive $common $MRT $SHA1 || exit 2 next=$(git write-tree 2>/dev/null) if test $? -ne 0
diff --git a/git-pull.sh b/git-pull.sh index 18a394f..2a17930 100755 --- a/git-pull.sh +++ b/git-pull.sh
@@ -135,6 +135,7 @@ ;; --no-r|--no-re|--no-reb|--no-reba|--no-rebas|--no-rebase) rebase=false + ;; --recurse-submodules) recurse_submodules=--recurse-submodules @@ -175,6 +176,10 @@ done case "$rebase" in +i|interactive) + rebase=true + rebase_args=-i + ;; preserve) rebase=true rebase_args=--preserve-merges @@ -182,7 +187,7 @@ true|false|'') ;; *) - echo "Invalid value for --rebase, should be true, false, or preserve" + echo "Invalid value for --rebase, should be true, false, interactive or preserve" usage exit 1 ;;
diff --git a/git-sh-setup.sh b/git-sh-setup.sh index 9447980..5adc011 100644 --- a/git-sh-setup.sh +++ b/git-sh-setup.sh
@@ -59,7 +59,9 @@ say () { if test -z "$GIT_QUIET" then - printf '%s\n' "$*" + cat <<EOF +$* +EOF fi }
diff --git a/git-submodule.sh b/git-submodule.sh index 9245abf..a0d8705 100755 --- a/git-submodule.sh +++ b/git-submodule.sh
@@ -434,9 +434,11 @@ if test -z "$force" && ! git add --dry-run --ignore-missing "$sm_path" > /dev/null 2>&1 then - eval_gettextln "The following path is ignored by one of your .gitignore files: -\$sm_path -Use -f if you really want to add it." >&2 + cat >&2 <<EOF +The following path is ignored by one of your .gitignore files: +$(eval_gettextln $sm_path) +Use -f if you really want to add it. +EOF exit 1 fi
diff --git a/gitk-git/gitk b/gitk-git/gitk index 3520bda..90e83a6 100755 --- a/gitk-git/gitk +++ b/gitk-git/gitk
@@ -404,7 +404,7 @@ if {$revs eq {}} { return 0 } - set args [concat $vflags($view) $revs] + set args [limit_arg_length [concat $vflags($view) $revs]] } else { set args $vorigargs($view) } @@ -7557,7 +7557,7 @@ if {[string index $fname 0] eq "\""} { set fname [lindex $fname 0] } - set fname [encoding convertfrom $fname] + set fname [encoding convertfrom utf-8 $fname] lappend treefilelist($id) $fname } if {![eof $gtf]} { @@ -7819,7 +7819,7 @@ if {[string index $file 0] eq "\""} { set file [lindex $file 0] } - set file [encoding convertfrom $file] + set file [encoding convertfrom utf-8 $file] if {$file ne [lindex $treediff end]} { lappend treediff $file lappend sublist $file @@ -7964,7 +7964,7 @@ global ctext curdiffstart treediffs diffencoding global ctext_file_names jump_to_here targetline diffline - set fname [encoding convertfrom $fname] + set fname [encoding convertfrom utf-8 $fname] set diffencoding [get_path_encoding $fname] set i [lsearch -exact $treediffs($ids) $fname] if {$i >= 0} { @@ -8021,7 +8021,7 @@ if {![string compare -length 5 "diff " $line]} { if {![regexp {^diff (--cc|--git) } $line m type]} { - set line [encoding convertfrom $line] + set line [encoding convertfrom utf-8 $line] $ctext insert end "$line\n" hunksep continue } @@ -8068,7 +8068,7 @@ makediffhdr $fname $ids } elseif {![string compare -length 16 "* Unmerged path " $line]} { - set fname [encoding convertfrom [string range $line 16 end]] + set fname [encoding convertfrom utf-8 [string range $line 16 end]] $ctext insert end "\n" set curdiffstart [$ctext index "end - 1c"] lappend ctext_file_names $fname @@ -8123,7 +8123,7 @@ if {[string index $fname 0] eq "\""} { set fname [lindex $fname 0] } - set fname [encoding convertfrom $fname] + set fname [encoding convertfrom utf-8 $fname] set i [lsearch -exact $treediffs($ids) $fname] if {$i >= 0} { setinlist difffilestart $i $curdiffstart @@ -8142,6 +8142,7 @@ set diffinhdr 0 return } + set line [encoding convertfrom utf-8 $line] $ctext insert end "$line\n" filesep } else { @@ -9969,7 +9970,8 @@ } } if {$ids ne {}} { - set fd [open [concat $cmd $ids] r] + set cmd [limit_arg_length [concat $cmd $ids]] + set fd [open $cmd r] fconfigure $fd -blocking 0 incr allcommits nowbusy allcommits @@ -9979,6 +9981,21 @@ } } +# The maximum command line length for the CreateProcess function is 32767 characters, see +# http://blogs.msdn.com/oldnewthing/archive/2003/12/10/56028.aspx +# Be a little conservative in case Tcl adds some more stuff to the command line we do not +# know about and truncate the command line at a SHA1-boundary below 32000 characters. +proc limit_arg_length {cmd} { + if {[tk windowingsystem] == "win32" && + [string length $cmd] > 32000} { + set ndx [string last " " $cmd 32000] + if {$ndx != -1} { + return [string range $cmd 0 $ndx] + } + } + return $cmd +} + # Since most commits have 1 parent and 1 child, we group strings of # such commits into "arcs" joining branch/merge points (BMPs), which # are commits that either don't have 1 parent or don't have 1 child. @@ -11952,7 +11969,7 @@ foreach row [split $rlist "\n"] { if {[regexp "(.*): $attr: (.*)" $row m path value]} { if {[string index $path 0] eq "\""} { - set path [encoding convertfrom [lindex $path 0]] + set path [encoding convertfrom utf-8 [lindex $path 0]] } set path_attr_cache($attr,$path) $value } @@ -12135,7 +12152,6 @@ set gitk_prefix [file dirname [file dirname [file normalize $argv0]]] set gitk_libdir [file join $gitk_prefix share gitk lib] set gitk_msgsdir [file join $gitk_libdir msgs] - unset gitk_prefix } ## Internationalization (i18n) through msgcat and gettext. See @@ -12314,28 +12330,32 @@ set worktree [exec git rev-parse --show-toplevel] setcoords makewindow -catch { - image create photo gitlogo -width 16 -height 16 +if {$::tcl_platform(platform) eq {windows} && [file exists $gitk_prefix/etc/git.ico]} { + wm iconbitmap . -default $gitk_prefix/etc/git.ico +} else { + catch { + image create photo gitlogo -width 16 -height 16 - image create photo gitlogominus -width 4 -height 2 - gitlogominus put #C00000 -to 0 0 4 2 - gitlogo copy gitlogominus -to 1 5 - gitlogo copy gitlogominus -to 6 5 - gitlogo copy gitlogominus -to 11 5 - image delete gitlogominus + image create photo gitlogominus -width 4 -height 2 + gitlogominus put #C00000 -to 0 0 4 2 + gitlogo copy gitlogominus -to 1 5 + gitlogo copy gitlogominus -to 6 5 + gitlogo copy gitlogominus -to 11 5 + image delete gitlogominus - image create photo gitlogoplus -width 4 -height 4 - gitlogoplus put #008000 -to 1 0 3 4 - gitlogoplus put #008000 -to 0 1 4 3 - gitlogo copy gitlogoplus -to 1 9 - gitlogo copy gitlogoplus -to 6 9 - gitlogo copy gitlogoplus -to 11 9 - image delete gitlogoplus + image create photo gitlogoplus -width 4 -height 4 + gitlogoplus put #008000 -to 1 0 3 4 + gitlogoplus put #008000 -to 0 1 4 3 + gitlogo copy gitlogoplus -to 1 9 + gitlogo copy gitlogoplus -to 6 9 + gitlogo copy gitlogoplus -to 11 9 + image delete gitlogoplus - image create photo gitlogo32 -width 32 -height 32 - gitlogo32 copy gitlogo -zoom 2 2 + image create photo gitlogo32 -width 32 -height 32 + gitlogo32 copy gitlogo -zoom 2 2 - wm iconphoto . -default gitlogo gitlogo32 + wm iconphoto . -default gitlogo gitlogo32 + } } # wait for the window to become visible tkwait visibility .
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index a9f57d6..7cd317a 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl
@@ -4543,6 +4543,29 @@ print $cgi->a({-href => href(action=>"blob_plain", file_name=>$file_name, hash_base=>$hb), -title => $name}, esc_path($basename)); + if (gitweb_check_feature('highlight')) { + print ' +<a id="lineNoToggle" href="#" onclick="toggleLineNumbers();"></a> +<script> +function toggleLineNumbers() { + e = document.getElementById("lineNoStyle"); + e2 = document.getElementById("lineNoToggle"); + if (e2.innerHTML == "[Hide line numbers]") { + e.innerHTML = ".linenr { display:none; }"; + e2.innerHTML = "[Show line numbers]"; + } + else { + e.innerHTML = ""; + e2.innerHTML = "[Hide line numbers]"; + } +} +var style = document.createElement("style"); +style.setAttribute("id", "lineNoStyle"); +document.getElementsByTagName("head")[0].appendChild(style); +toggleLineNumbers(); +</script> +'; + } } elsif (defined $type && $type eq 'tree') { print $cgi->a({-href => href(action=>"tree", file_name=>$file_name, hash_base=>$hb), @@ -7054,7 +7077,19 @@ # we can have blame only for text/* mimetype $have_blame &&= ($mimetype =~ m!^text/!); + my $highlight_js = gitweb_check_feature('syntaxhighlighter_js'); + if ($highlight_js) { + push @stylesheets, $highlight_js->{url} . '/styles/shCore' + . $highlight_js->{style} . '.css'; + push @stylesheets, $highlight_js->{url} . '/styles/shTheme' + . $highlight_js->{theme} . '.css'; + } + my $highlight = gitweb_check_feature('highlight'); + if ($highlight_js && $highlight) { + die_error(500, 'The highlight and syntaxhighlighter_js are' + . 'mutually exclusive'); + } my $syntax = guess_file_syntax($highlight, $mimetype, $file_name); $fd = run_highlighter($fd, $highlight, $syntax) if $syntax; @@ -7102,6 +7137,72 @@ href(action=>"blob_plain", hash=>$hash, hash_base=>$hash_base, file_name=>$file_name) . qq!" />\n!; + } elsif ($highlight_js) { + my $ext = $file_name; + $ext =~ s/.*\.//; + print qq!<pre class="brush:!.$ext.qq!">!; + while (my $line = <$fd>) { + $line =~ s!&!\&!g; + $line =~ s!<!\<!g; + print $line; + } + print qq!</pre>!; + foreach my $name ('Core', 'Autoloader') { + print qq!<script src="!.$highlight_js->{url} + .qq!/scripts/sh!.$name + .qq!.js" type="text/javascript"></script>!; + } + print qq!<script type="text/javascript">!; + print qq!SyntaxHighlighter.defaults["pad-line-numbers"] = 3;!; + print qq!SyntaxHighlighter.defaults["toolbar"] = false;!; + # for XHTML compliance + print qq!SyntaxHighlighter.config["space"] = ' ';!; + print qq!SyntaxHighlighter.autoloader(!; + my $brush_prefix = $highlight_js->{url} . '/scripts/shBrush'; + foreach my $language ('applescript AppleScript', + 'actionscript3 as3 AS3', + 'bash shell Bash', + 'clj Clojure', + 'coldfusion cf ColdFusion', + 'cpp c Cpp', + 'c# c-sharp csharp CSharp', + 'css Css', + 'delphi pascal Delphi', + 'diff patch pas Diff', + 'erl erlang Erlang', + 'groovy Groovy', + 'java Java', + 'jfx javafx JavaFX', + 'js jscript javascript JScript', + 'perl pl Perl', + 'php Php', + 'text plain Plain', + 'py python Python', + 'ruby rails ror rb Ruby', + 'scala Scala', + 'scm Scheme', + 'sql Sql', + 'vb vbnet Vb', + 'xml xhtml xslt html Xml') { + my $lang = $language; + $lang =~ s! (\S+)$! $brush_prefix$1!; + print "'".$lang.qq!.js',!; + } + print qq!''); SyntaxHighlighter.all();! + .qq!function scrollTo(number) {! + .qq! var elements = document.getElementsByClassName(number);! + .qq! if (elements.length == 0) setTimeout('scrollTo("' + number + '");', 50);! + .qq! else {! + .qq! window.scroll(0, elements[0].offsetTop);! + .qq! window.scrollTo(0, elements[0].offsetTop);! + .qq! elements[0].style.color = '#ff0000';! + .qq! }! + .qq!}! + .qq!var lineRegex = /#l(\\d+)\$/;! + .qq!var lineNumber = lineRegex.exec(document.URL);! + .qq!if (lineNumber)! + .qq! scrollTo('number' + lineNumber[1]);! + .qq!</script>!; } else { my $nr; while (my $line = <$fd>) {
diff --git a/t/annotate-tests.sh b/t/annotate-tests.sh index 071e4d7..80262ed 100644 --- a/t/annotate-tests.sh +++ b/t/annotate-tests.sh
@@ -263,27 +263,27 @@ ' test_expect_success 'blame -L /RE/ (RE to end)' ' - check_count -L/evil/ C 1 "A U Thor" 1 + check_count -L/\;*evil/ C 1 "A U Thor" 1 ' test_expect_success 'blame -L /RE/,/RE2/' ' - check_count -L/robot/,/green/ A 1 B 1 B2 1 D 1 E 1 + check_count -L/\;*robot/,/\;*green/ A 1 B 1 B2 1 D 1 E 1 ' test_expect_success 'blame -L X,/RE/' ' - check_count -L5,/evil/ B1 1 D 1 "A U Thor" 1 + check_count -L5,/\;*evil/ B1 1 D 1 "A U Thor" 1 ' test_expect_success 'blame -L /RE/,Y' ' - check_count -L/99/,7 B1 1 D 1 "A U Thor" 1 + check_count -L/\;*99/,7 B1 1 D 1 "A U Thor" 1 ' test_expect_success 'blame -L /RE/,+N' ' - check_count -L/99/,+3 B1 1 D 1 "A U Thor" 1 + check_count -L/\;*99/,+3 B1 1 D 1 "A U Thor" 1 ' test_expect_success 'blame -L /RE/,-N' ' - check_count -L/99/,-3 B 1 B2 1 D 1 + check_count -L/\;*99/,-3 B 1 B2 1 D 1 ' # 'file' ends with an incomplete line, so 'wc' reports one fewer lines than @@ -349,19 +349,19 @@ ' test_expect_success 'blame -L /RE/ (relative)' ' - check_count -L3,3 -L/fox/ B1 1 B2 1 C 1 D 1 "A U Thor" 1 + check_count -L3,3 -L/\;*fox/ B1 1 B2 1 C 1 D 1 "A U Thor" 1 ' test_expect_success 'blame -L /RE/ (relative: no preceding range)' ' - check_count -L/dog/ A 1 B 1 B1 1 B2 1 C 1 D 1 "A U Thor" 1 + check_count -L/\;*dog/ A 1 B 1 B1 1 B2 1 C 1 D 1 "A U Thor" 1 ' test_expect_success 'blame -L /RE/ (relative: adjacent)' ' - check_count -L1,1 -L/dog/,+1 A 1 E 1 + check_count -L1,1 -L/\;*dog/,+1 A 1 E 1 ' test_expect_success 'blame -L /RE/ (relative: not found)' ' - test_must_fail $PROG -L4,4 -L/dog/ file + test_must_fail $PROG -L4,4 -L/\;*dog/ file ' test_expect_success 'blame -L /RE/ (relative: end-of-file)' ' @@ -369,11 +369,11 @@ ' test_expect_success 'blame -L ^/RE/ (absolute)' ' - check_count -L3,3 -L^/dog/,+2 A 1 B2 1 + check_count -L3,3 -L^/\;*dog/,+2 A 1 B2 1 ' test_expect_success 'blame -L ^/RE/ (absolute: no preceding range)' ' - check_count -L^/dog/,+2 A 1 B2 1 + check_count -L^/\;*dog/,+2 A 1 B2 1 ' test_expect_success 'blame -L ^/RE/ (absolute: not found)' '
diff --git a/t/lib-credential.sh b/t/lib-credential.sh index 9e7d796..c58f50b 100755 --- a/t/lib-credential.sh +++ b/t/lib-credential.sh
@@ -44,6 +44,7 @@ reject $1 https example.com user2 reject $1 http path.tld user reject $1 https timeout.tld user + reject $1 https sso.tld } reject() { @@ -250,6 +251,24 @@ password=pass2 EOF ' + + test_expect_success "helper ($HELPER) can store empty username" ' + check approve $HELPER <<-\EOF && + protocol=https + host=sso.tld + username= + password= + EOF + check fill $HELPER <<-\EOF + protocol=https + host=sso.tld + -- + protocol=https + host=sso.tld + username= + password= + EOF + ' } helper_test_timeout() {
diff --git a/t/lib-git-daemon.sh b/t/lib-git-daemon.sh index bc4b341..9b1271c 100644 --- a/t/lib-git-daemon.sh +++ b/t/lib-git-daemon.sh
@@ -23,6 +23,11 @@ test_done fi +if ! test_have_prereq PIPE +then + test_skip_or_die $GIT_TEST_GIT_DAEMON "file system does not support FIFOs" +fi + LIB_GIT_DAEMON_PORT=${LIB_GIT_DAEMON_PORT-${this_test#t}} GIT_DAEMON_PID=
diff --git a/t/t0001-init.sh b/t/t0001-init.sh index e62c0ff..71b8d8f 100755 --- a/t/t0001-init.sh +++ b/t/t0001-init.sh
@@ -332,4 +332,32 @@ test_path_is_dir realgitdir/refs ' +# Tests for the hidden file attribute on windows +is_hidden () { + test "1" -eq "$(echo puts [file attributes $1 -hidden]|tclsh)" +} + +test_expect_success MINGW 'plain hidden' ' + rm -rf newdir && + ( + unset GIT_DIR GIT_WORK_TREE + mkdir newdir && + cd newdir && + git init && + is_hidden .git + ) && + check_config newdir/.git false unset +' + +test_expect_success MINGW 'plain bare not hidden' ' + rm -rf newdir + ( + unset GIT_DIR GIT_WORK_TREE GIT_CONFIG + mkdir newdir && + cd newdir && + git --bare init + ) && + ! is_hidden newdir +' + test_done
diff --git a/t/t0008-ignores.sh b/t/t0008-ignores.sh index 39e55a1..f197c3a 100755 --- a/t/t0008-ignores.sh +++ b/t/t0008-ignores.sh
@@ -5,7 +5,13 @@ . ./test-lib.sh init_vars () { - global_excludes="$(pwd)/global-excludes" + # On Windows, avoid using "C:" in the global-excludes paths. + if test_have_prereq MINGW + then + global_excludes="global-excludes" + else + global_excludes="$(pwd)/global-excludes" + fi } enable_global_excludes () {
diff --git a/t/t0026-eol-config.sh b/t/t0026-eol-config.sh index 4807b0f..43a580a 100755 --- a/t/t0026-eol-config.sh +++ b/t/t0026-eol-config.sh
@@ -80,4 +80,22 @@ test -z "$onediff" && test -z "$twodiff" ' +test_expect_success NATIVE_CRLF 'eol native is crlf' ' + + rm -rf native_eol && mkdir native_eol && + ( cd native_eol && + printf "*.txt text\n" > .gitattributes + printf "one\r\ntwo\r\nthree\r\n" > filedos.txt + printf "one\ntwo\nthree\n" > fileunix.txt + git init && + git config core.autocrlf false && + git config core.eol native && + git add filedos.txt fileunix.txt && + git commit -m "first" && + rm file*.txt && + git reset --hard HEAD && + has_cr filedos.txt && has_cr fileunix.txt + ) +' + test_done
diff --git a/t/t1050-large.sh b/t/t1050-large.sh index aea4936..4be4a56 100755 --- a/t/t1050-large.sh +++ b/t/t1050-large.sh
@@ -9,10 +9,10 @@ # clone does not allow us to pass core.bigfilethreshold to # new repos, so set core.bigfilethreshold globally git config --global core.bigfilethreshold 200k && - echo X | dd of=large1 bs=1k seek=2000 && - echo X | dd of=large2 bs=1k seek=2000 && - echo X | dd of=large3 bs=1k seek=2000 && - echo Y | dd of=huge bs=1k seek=2500 && + perl -e "print \"\\0\" x 2048000; print \"X\\n\";" > large1 && + perl -e "print \"\\0\" x 2048000; print \"X\\n\";" > large2 && + perl -e "print \"\\0\" x 2048000; print \"X\\n\";" > large3 && + perl -e "print \"\\0\" x 2560000; print \"Y\\n\";" > huge && GIT_ALLOC_LIMIT=1500 && export GIT_ALLOC_LIMIT '
diff --git a/t/t1501-worktree.sh b/t/t1501-worktree.sh index 8f36aa9..06982bd 100755 --- a/t/t1501-worktree.sh +++ b/t/t1501-worktree.sh
@@ -339,6 +339,10 @@ git --git-dir="$(pwd)//repo.git" --work-tree="$(pwd)" add dummy_file ' +test_have_prereq MINGW && +# make sure to test DOS path on Windows +TRASH_DIRECTORY="$(cd "$TRASH_DIRECTORY" && pwd)" + test_expect_success 'relative $GIT_WORK_TREE and git subprocesses' ' GIT_DIR=repo.git GIT_WORK_TREE=repo.git/work \ test-subprocess --setup-work-tree rev-parse --show-toplevel >actual &&
diff --git a/t/t3102-ls-tree-wildcards.sh b/t/t3102-ls-tree-wildcards.sh index c286854..766af3d 100755 --- a/t/t3102-ls-tree-wildcards.sh +++ b/t/t3102-ls-tree-wildcards.sh
@@ -4,14 +4,14 @@ . ./test-lib.sh -test_expect_success 'setup' ' +test_expect_success NOT_MINGW 'setup' ' mkdir a aa "a[a]" && touch a/one aa/two "a[a]/three" && git add a/one aa/two "a[a]/three" && git commit -m test ' -test_expect_success 'ls-tree a[a] matches literally' ' +test_expect_success NOT_MINGW 'ls-tree a* matches literally' ' cat >expected <<EOF && 100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 a[a]/three EOF
diff --git a/t/t4130-apply-criss-cross-rename.sh b/t/t4130-apply-criss-cross-rename.sh index d173acd..bf7049e 100755 --- a/t/t4130-apply-criss-cross-rename.sh +++ b/t/t4130-apply-criss-cross-rename.sh
@@ -14,8 +14,8 @@ test_expect_success 'setup' ' create_file file1 "File1 contents" && - create_file file2 "File2 contents" && - create_file file3 "File3 contents" && + create_file file2 "File2 more contents" && + create_file file3 "File3 even more contents" && git add file1 file2 file3 && git commit -m 1 '
diff --git a/t/t5504-fetch-receive-strict.sh b/t/t5504-fetch-receive-strict.sh index 69ee13c..bb8bc94 100755 --- a/t/t5504-fetch-receive-strict.sh +++ b/t/t5504-fetch-receive-strict.sh
@@ -101,7 +101,7 @@ git config transfer.fsckobjects false ) && test_must_fail git push --porcelain dst master:refs/heads/test >act && - test_cmp exp act + test_cmp exp act || test ! -s act ' test_expect_success 'push with transfer.fsckobjects' ' @@ -112,7 +112,7 @@ git config transfer.fsckobjects true ) && test_must_fail git push --porcelain dst master:refs/heads/test >act && - test_cmp exp act + test_cmp exp act || test ! -s act ' test_done
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh index 67e0ab3..0df3210 100755 --- a/t/t5516-fetch-push.sh +++ b/t/t5516-fetch-push.sh
@@ -1277,4 +1277,40 @@ git push --no-thin --receive-pack="$rcvpck" no-thin/.git refs/heads/master:refs/heads/foo ' +test_expect_success 'receive.denyCurrentBranch = updateInstead' ' + git push testrepo master && + (cd testrepo && + git reset --hard && + git config receive.denyCurrentBranch updateInstead + ) && + test_commit third path2 && + git push testrepo master && + test $(git rev-parse HEAD) = $(cd testrepo && git rev-parse HEAD) && + test third = "$(cat testrepo/path2)" && + (cd testrepo && + git update-index --refresh && + git diff-files --quiet && + git diff-index --cached HEAD -- + ) +' + +test_expect_success 'receive.denyCurrentBranch = detachInstead' ' + (cd testrepo && + git reset --hard && + git config receive.denyCurrentBranch detachInstead + ) && + OLDHEAD=$(cd testrepo && git rev-parse HEAD) && + test_commit fourth path2 && + test fourth = "$(cat path2)" && + git push testrepo master && + test $OLDHEAD = $(cd testrepo && git rev-parse HEAD) && + test fourth != "$(cat testrepo/path2)" && + (cd testrepo && + test_must_fail git symbolic-ref HEAD && + git update-index --refresh && + git diff-files --quiet && + git diff-index --cached HEAD -- + ) +' + test_done
diff --git a/t/t6038-merge-text-auto.sh b/t/t6038-merge-text-auto.sh index d9c2d38..85c10b0 100755 --- a/t/t6038-merge-text-auto.sh +++ b/t/t6038-merge-text-auto.sh
@@ -72,6 +72,10 @@ same line EOF + if test_have_prereq NATIVE_CRLF; then + append_cr <expected >expected.temp && + mv expected.temp expected + fi && git config merge.renormalize true && git rm -fr . && rm -f .gitattributes && @@ -86,6 +90,10 @@ same line EOF + if test_have_prereq NATIVE_CRLF; then + append_cr <expected >expected.temp && + mv expected.temp expected + fi && git config merge.renormalize true && git rm -fr . && rm -f .gitattributes && @@ -95,16 +103,19 @@ ' test_expect_success 'Detect CRLF/LF conflict after setting text=auto' ' - q_to_cr <<-\EOF >expected && - <<<<<<< - first line - same line - ======= - first lineQ - same lineQ - >>>>>>> - EOF - + echo "<<<<<<<" >expected && + if test_have_prereq NATIVE_CRLF; then + echo first line | append_cr >>expected && + echo same line | append_cr >>expected && + echo ======= | append_cr >>expected + else + echo first line >>expected && + echo same line >>expected && + echo ======= >>expected + fi && + echo first line | append_cr >>expected && + echo same line | append_cr >>expected && + echo ">>>>>>>" >>expected && git config merge.renormalize false && rm -f .gitattributes && git reset --hard a && @@ -114,16 +125,19 @@ ' test_expect_success 'Detect LF/CRLF conflict from addition of text=auto' ' - q_to_cr <<-\EOF >expected && - <<<<<<< - first lineQ - same lineQ - ======= - first line - same line - >>>>>>> - EOF - + echo "<<<<<<<" >expected && + echo first line | append_cr >>expected && + echo same line | append_cr >>expected && + if test_have_prereq NATIVE_CRLF; then + echo ======= | append_cr >>expected && + echo first line | append_cr >>expected && + echo same line | append_cr >>expected + else + echo ======= >>expected && + echo first line >>expected && + echo same line >>expected + fi && + echo ">>>>>>>" >>expected && git config merge.renormalize false && rm -f .gitattributes && git reset --hard b &&
diff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh index 66c8b0a..b7dedb1 100755 --- a/t/t9350-fast-export.sh +++ b/t/t9350-fast-export.sh
@@ -522,4 +522,15 @@ test_cmp expected actual ' +cat > expected << EOF +reset refs/heads/master +from $(git rev-parse master) + +EOF + +test_expect_failure 'refs are updated even if no commits need to be exported' ' + git fast-export master..master > actual && + test_cmp expected actual +' + test_done
diff --git a/t/test-lib.sh b/t/test-lib.sh index b1bc65b..eb9c219 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh
@@ -15,6 +15,10 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see http://www.gnu.org/licenses/ . +# for git on windows so stdin will not be misdetected as attached to a +# terminal +exec < /dev/null + # Keep the original TERM for say_color ORIGINAL_TERM=$TERM @@ -871,6 +875,7 @@ # exec does not inherit the PID test_set_prereq MINGW test_set_prereq NOT_CYGWIN + test_set_prereq NATIVE_CRLF test_set_prereq SED_STRIPS_CR test_set_prereq GREP_STRIPS_CR GIT_TEST_CMP=mingw_test_cmp
diff --git a/transport-helper.c b/transport-helper.c index 3d8fe7d..9bf11e4 100644 --- a/transport-helper.c +++ b/transport-helper.c
@@ -14,6 +14,8 @@ #include "refs.h" static int debug; +/* TODO: put somewhere sensible, e.g. git_transport_options? */ +static int auto_gc = 1; struct helper_data { const char *name; @@ -435,10 +437,25 @@ for (i = 0; i < revlist_args->nr; i++) argv_array_push(&fastexport->args, revlist_args->items[i].string); + argv_array_push(&fastexport->args, "--"); + fastexport->git_cmd = 1; return start_command(fastexport); } +static void check_helper_status(struct helper_data *data) +{ + int pid, status; + + pid = waitpid(data->helper->pid, &status, WNOHANG); + if (pid < 0) + die("Could not retrieve status of remote helper '%s'", + data->name); + if (pid > 0 && WIFEXITED(status)) + die("Remote helper '%s' died with %d", + data->name, WEXITSTATUS(status)); +} + static int fetch_with_import(struct transport *transport, int nr_heads, struct ref **to_fetch) { @@ -474,6 +491,7 @@ if (finish_command(&fastimport)) die("Error while running fast-import"); + check_helper_status(data); /* * The fast-import stream of a remote helper that advertises @@ -505,6 +523,12 @@ } } strbuf_release(&buf); + if (auto_gc) { + const char *argv_gc_auto[] = { + "gc", "--auto", "--quiet", NULL, + }; + run_command_v_opt(argv_gc_auto, RUN_GIT_CMD); + } return 0; } @@ -913,6 +937,7 @@ if (finish_command(&exporter)) die("Error while running fast-export"); + check_helper_status(data); if (push_update_refs_status(data, remote_refs, flags)) return 1;