diff options
62 files changed, 610 insertions, 319 deletions
diff --git a/Documentation/CodingGuidelines b/Documentation/CodingGuidelines index dab5c61bfe..f424dbd75c 100644 --- a/Documentation/CodingGuidelines +++ b/Documentation/CodingGuidelines @@ -164,6 +164,16 @@ For C programs: * multi-line comment. */ + Note however that a comment that explains a translatable string to + translators uses a convention of starting with a magic token + "TRANSLATORS: " immediately after the opening delimiter, even when + it spans multiple lines. We do not add an asterisk at the beginning + of each line, either. E.g. + + /* TRANSLATORS: here is a comment that explains the string + to be translated, that follows immediately after it */ + _("Here is a translatable string explained by the above."); + - Double negation is often harder to understand than no negation at all. diff --git a/Documentation/RelNotes/2.0.0.txt b/Documentation/RelNotes/2.0.0.txt index 9e06b7dd52..3bd2b65964 100644 --- a/Documentation/RelNotes/2.0.0.txt +++ b/Documentation/RelNotes/2.0.0.txt @@ -41,12 +41,20 @@ with "git diff-files --diff-filter=d"). "git request-pull" lost a few "heuristics" that often led to mistakes. +The default prefix for "git svn" has changed in Git 2.0. For a long +time, "git svn" created its remote-tracking branches directly under +refs/remotes, but it now places them under refs/remotes/origin/ unless +it is told otherwise with its --prefix option. + Updates since v1.9 series ------------------------- UI, Workflows & Features + * The "multi-mail" post-receive hook (in contrib/) has been updated + to a more recent version from the upstream. + * "git gc --aggressive" learned "--depth" option and "gc.aggressiveDepth" configuration variable to allow use of a less insane depth than the built-in default value of 250. @@ -80,9 +88,9 @@ UI, Workflows & Features * "git grep" learned to behave in a way similar to native grep when "-h" (no header) and "-c" (count) options are given. - * transport-helper, fast-import and fast-export have been updated to - allow the ref mapping and ref deletion in a way similar to the - natively supported transports. + * "git push" via transport-helper interface (e.g. remote-hg) has + been updated to allow ref deletion in a way similar to the natively + supported transports. * The "simple" mode is the default for "git push". @@ -171,6 +179,23 @@ Unless otherwise noted, all the fixes since v1.9 in the maintenance track are contained in this release (see the maintenance releases' notes for details). + * "git rebase" used a POSIX shell construct FreeBSD /bin/sh does not + work well with. + (merge 8cd6596 km/avoid-non-function-return-in-rebase later to maint). + + * zsh prompt (in contrib/) leaked unnecessary error messages. + + * bash completion (in contrib/) did not complete the refs and remotes + correctly given "git pu<TAB>" when "pu" is aliased to "push". + + * Some more Unicode codepoints defined in Unicode 6.3 as having zero + width have been taught to our display column counting logic. + (merge d813ab9 tb/unicode-6.3-zero-width later to maint). + + * Some tests used shell constructs that did not work well on FreeBSD + (merge ff7a1c6 km/avoid-bs-in-shell-glob later to maint). + (merge 00764ca km/avoid-cp-a later to maint). + * "git update-ref --stdin" did not fail a request to create a ref when the ref already existed. (merge b9d56b5 mh/update-ref-batch-create-fix later to maint). diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt index 30c5ee2564..5b3c38de7f 100644 --- a/Documentation/git-svn.txt +++ b/Documentation/git-svn.txt @@ -86,13 +86,11 @@ COMMANDS (refs/remotes/$remote/*). Setting a prefix is also useful if you wish to track multiple projects that share a common repository. + By default, the prefix is set to 'origin/'. + -NOTE: In Git v2.0, the default prefix will CHANGE from "" (no prefix) -to "origin/". This is done to put SVN-tracking refs at -"refs/remotes/origin/*" instead of "refs/remotes/*", and make them -more compatible with how Git's own remote-tracking refs are organized -(i.e. refs/remotes/$remote/*). You can enjoy the same benefits today, -by using the --prefix option. +NOTE: Before Git v2.0, the default prefix was "" (no prefix). This +meant that SVN-tracking refs were put at "refs/remotes/*", which is +incompatible with how Git's own remote-tracking refs are organized. --ignore-paths=<regex>;; When passed to 'init' or 'clone' this regular expression will @@ -994,16 +992,6 @@ without giving any repository layout options. If the full history with branches and tags is required, the options '--trunk' / '--branches' / '--tags' must be used. -When using the options for describing the repository layout (--trunk, ---tags, --branches, --stdlayout), please also specify the --prefix -option (e.g. '--prefix=origin/') to cause your SVN-tracking refs to be -placed at refs/remotes/origin/* rather than the default refs/remotes/*. -The former is more compatible with the layout of Git's "regular" -remote-tracking refs (refs/remotes/$remote/*), and may potentially -prevent similarly named SVN branches and Git remotes from clobbering -each other. In Git v2.0 the default prefix used (i.e. when no --prefix -is given) will change from "" (no prefix) to "origin/". - When using multiple --branches or --tags, 'git svn' does not automatically handle name collisions (for example, if two branches from different paths have the same name, or if a branch and a tag have the same name). In these cases, diff --git a/Documentation/howto-index.sh b/Documentation/howto-index.sh index a2340864b5..167b363668 100755 --- a/Documentation/howto-index.sh +++ b/Documentation/howto-index.sh @@ -11,8 +11,8 @@ EOF for txt do - title=`expr "$txt" : '.*/\(.*\)\.txt$'` - from=`sed -ne ' + title=$(expr "$txt" : '.*/\(.*\)\.txt$') + from=$(sed -ne ' /^$/q /^From:[ ]/{ s/// @@ -21,9 +21,9 @@ do s/^/by / p } - ' "$txt"` + ' "$txt") - abstract=`sed -ne ' + abstract=$(sed -ne ' /^Abstract:[ ]/{ s/^[^ ]*// x @@ -39,11 +39,11 @@ do x p q - }' "$txt"` + }' "$txt") if grep 'Content-type: text/asciidoc' >/dev/null $txt then - file=`expr "$txt" : '\(.*\)\.txt$'`.html + file=$(expr "$txt" : '\(.*\)\.txt$').html else file="$txt" fi diff --git a/Documentation/install-webdoc.sh b/Documentation/install-webdoc.sh index 76d69a907b..ed8b4ff3e5 100755 --- a/Documentation/install-webdoc.sh +++ b/Documentation/install-webdoc.sh @@ -18,17 +18,17 @@ do else echo >&2 "# install $h $T/$h" rm -f "$T/$h" - mkdir -p `dirname "$T/$h"` + mkdir -p $(dirname "$T/$h") cp "$h" "$T/$h" fi done -strip_leading=`echo "$T/" | sed -e 's|.|.|g'` +strip_leading=$(echo "$T/" | sed -e 's|.|.|g') for th in \ "$T"/*.html "$T"/*.txt \ "$T"/howto/*.txt "$T"/howto/*.html \ "$T"/technical/*.txt "$T"/technical/*.html do - h=`expr "$th" : "$strip_leading"'\(.*\)'` + h=$(expr "$th" : "$strip_leading"'\(.*\)') case "$h" in RelNotes-*.txt | index.html) continue ;; esac diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index a651d68656..5b367ab7fe 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v1.9.0.GIT +DEF_VER=v2.0.0-rc0 LF=' ' @@ -34,8 +34,15 @@ all:: # git-http-push are not built, and you cannot use http:// and https:// # transports (neither smart nor dumb). # +# Define CURL_CONFIG to the path to a curl-config binary other than the +# default 'curl-config'. +# +# Define CURL_STATIC to statically link libcurl. Only applies if +# CURL_CONFIG is used. +# # Define CURLDIR=/foo/bar if your curl header and library files are in -# /foo/bar/include and /foo/bar/lib directories. +# /foo/bar/include and /foo/bar/lib directories. This overrides CURL_CONFIG, +# but is less robust. # # Define NO_EXPAT if you do not have expat installed. git-http-push is # not built, and you cannot push using http:// and https:// transports (dumb). @@ -143,9 +150,11 @@ all:: # # Define NEEDS_SSL_WITH_CRYPTO if you need -lssl when using -lcrypto (Darwin). # -# Define NEEDS_SSL_WITH_CURL if you need -lssl with -lcurl (Minix). +# Define NEEDS_SSL_WITH_CURL if you need -lssl with -lcurl (Minix). Only used +# if CURLDIR is set. # -# Define NEEDS_IDN_WITH_CURL if you need -lidn when using -lcurl (Minix). +# Define NEEDS_IDN_WITH_CURL if you need -lidn when using -lcurl (Minix). Only +# used if CURLDIR is set. # # Define NEEDS_LIBICONV if linking with libc is not enough (Darwin). # @@ -1121,18 +1130,30 @@ else # Try "-Wl,-rpath=$(CURLDIR)/$(lib)" in such a case. BASIC_CFLAGS += -I$(CURLDIR)/include CURL_LIBCURL = -L$(CURLDIR)/$(lib) $(CC_LD_DYNPATH)$(CURLDIR)/$(lib) -lcurl + ifdef NEEDS_SSL_WITH_CURL + CURL_LIBCURL += -lssl + ifdef NEEDS_CRYPTO_WITH_SSL + CURL_LIBCURL += -lcrypto + endif + endif + ifdef NEEDS_IDN_WITH_CURL + CURL_LIBCURL += -lidn + endif else - CURL_LIBCURL = -lcurl - endif - ifdef NEEDS_SSL_WITH_CURL - CURL_LIBCURL += -lssl - ifdef NEEDS_CRYPTO_WITH_SSL - CURL_LIBCURL += -lcrypto + CURL_CONFIG ?= curl-config + BASIC_CFLAGS += $(shell $(CURL_CONFIG) --cflags) + ifdef CURL_STATIC + CURL_LIBCURL = $(shell $(CURL_CONFIG) --static-libs) + ifeq "$(CURL_LIBCURL)" "" + $(error libcurl not detected or not compiled with static support) + endif + else + CURL_LIBCURL = $(shell $(CURL_CONFIG) --libs) + ifeq "$(CURL_LIBCURL)" "" + $(error libcurl not detected; try setting CURLDIR) + endif endif endif - ifdef NEEDS_IDN_WITH_CURL - CURL_LIBCURL += -lidn - endif REMOTE_CURL_PRIMARY = git-remote-http$X REMOTE_CURL_ALIASES = git-remote-https$X git-remote-ftp$X git-remote-ftps$X @@ -2102,7 +2123,7 @@ pdf: XGETTEXT_FLAGS = \ --force-po \ - --add-comments \ + --add-comments=TRANSLATORS: \ --msgid-bugs-address="Git Mailing List <git@vger.kernel.org>" \ --from-code=UTF-8 XGETTEXT_FLAGS_C = $(XGETTEXT_FLAGS) --language=C \ diff --git a/builtin/init-db.c b/builtin/init-db.c index c7c76bbf21..56f85e239a 100644 --- a/builtin/init-db.c +++ b/builtin/init-db.c @@ -412,11 +412,9 @@ int init_db(const char *template_dir, unsigned int flags) if (!(flags & INIT_DB_QUIET)) { int len = strlen(git_dir); - /* - * TRANSLATORS: The first '%s' is either "Reinitialized - * existing" or "Initialized empty", the second " shared" or - * "", and the last '%s%s' is the verbatim directory name. - */ + /* TRANSLATORS: The first '%s' is either "Reinitialized + existing" or "Initialized empty", the second " shared" or + "", and the last '%s%s' is the verbatim directory name. */ printf(_("%s%s Git repository in %s%s\n"), reinit ? _("Reinitialized existing") : _("Initialized empty"), shared_repository ? _(" shared") : "", @@ -557,6 +557,7 @@ int git_parse_ulong(const char *value, unsigned long *ret) return 1; } +NORETURN static void die_bad_number(const char *name, const char *value) { const char *reason = errno == ERANGE ? diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 87de809d23..2c59a76bc2 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -2564,6 +2564,7 @@ __git_main () local expansion=$(__git_aliased_command "$command") if [ -n "$expansion" ]; then + words[1]=$expansion completion_func="_git_${expansion//-/_}" declare -f $completion_func >/dev/null && $completion_func fi diff --git a/contrib/completion/git-completion.zsh b/contrib/completion/git-completion.zsh index 6b77968572..9f6f0fa558 100644 --- a/contrib/completion/git-completion.zsh +++ b/contrib/completion/git-completion.zsh @@ -104,6 +104,7 @@ __git_zsh_bash_func () local expansion=$(__git_aliased_command "$command") if [ -n "$expansion" ]; then + words[1]=$expansion completion_func="_git_${expansion//-/_}" declare -f $completion_func >/dev/null && $completion_func fi diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh index 7b732d2aeb..54489080f8 100644 --- a/contrib/completion/git-prompt.sh +++ b/contrib/completion/git-prompt.sh @@ -259,6 +259,13 @@ __git_ps1_colorize_gitstring () r="$c_clear$r" } +eread () +{ + f="$1" + shift + test -r "$f" && read "$@" <"$f" +} + # __git_ps1 accepts 0 or 1 arguments (i.e., format string) # when called from PS1 using command substitution # in this mode it prints text to add to bash PS1 prompt (includes branch name) @@ -321,9 +328,9 @@ __git_ps1 () local step="" local total="" if [ -d "$g/rebase-merge" ]; then - read b 2>/dev/null <"$g/rebase-merge/head-name" - read step 2>/dev/null <"$g/rebase-merge/msgnum" - read total 2>/dev/null <"$g/rebase-merge/end" + eread "$g/rebase-merge/head-name" b + eread "$g/rebase-merge/msgnum" step + eread "$g/rebase-merge/end" total if [ -f "$g/rebase-merge/interactive" ]; then r="|REBASE-i" else @@ -331,10 +338,10 @@ __git_ps1 () fi else if [ -d "$g/rebase-apply" ]; then - read step 2>/dev/null <"$g/rebase-apply/next" - read total 2>/dev/null <"$g/rebase-apply/last" + eread "$g/rebase-apply/next" step + eread "$g/rebase-apply/last" total if [ -f "$g/rebase-apply/rebasing" ]; then - read b 2>/dev/null <"$g/rebase-apply/head-name" + eread "$g/rebase-apply/head-name" b r="|REBASE" elif [ -f "$g/rebase-apply/applying" ]; then r="|AM" @@ -358,7 +365,7 @@ __git_ps1 () b="$(git symbolic-ref HEAD 2>/dev/null)" else local head="" - if ! read head 2>/dev/null <"$g/HEAD"; then + if ! eread "$g/HEAD" head; then if [ $pcmode = yes ]; then PS1="$ps1pc_start$ps1pc_end" fi diff --git a/contrib/examples/git-checkout.sh b/contrib/examples/git-checkout.sh index d2c1f98b86..683cae7c3f 100755 --- a/contrib/examples/git-checkout.sh +++ b/contrib/examples/git-checkout.sh @@ -222,7 +222,7 @@ else # Match the index to the working tree, and do a three-way. git diff-files --name-only | git update-index --remove --stdin && - work=`git write-tree` && + work=$(git write-tree) && git read-tree $v --reset -u $new || exit eval GITHEAD_$new='${new_name:-${branch:-$new}}' && @@ -233,7 +233,7 @@ else # Do not register the cleanly merged paths in the index yet. # this is not a real merge before committing, but just carrying # the working tree changes along. - unmerged=`git ls-files -u` + unmerged=$(git ls-files -u) git read-tree $v --reset $new case "$unmerged" in '') ;; @@ -269,7 +269,7 @@ if [ "$?" -eq 0 ]; then fi if test -n "$branch" then - old_branch_name=`expr "z$oldbranch" : 'zrefs/heads/\(.*\)'` + old_branch_name=$(expr "z$oldbranch" : 'zrefs/heads/\(.*\)') GIT_DIR="$GIT_DIR" git symbolic-ref -m "checkout: moving from ${old_branch_name:-$old} to $branch" HEAD "refs/heads/$branch" if test -n "$quiet" then @@ -282,7 +282,7 @@ if [ "$?" -eq 0 ]; then fi elif test -n "$detached" then - old_branch_name=`expr "z$oldbranch" : 'zrefs/heads/\(.*\)'` + old_branch_name=$(expr "z$oldbranch" : 'zrefs/heads/\(.*\)') git update-ref --no-deref -m "checkout: moving from ${old_branch_name:-$old} to $arg" HEAD "$detached" || die "Cannot detach HEAD" if test -n "$detach_warn" diff --git a/contrib/examples/git-clone.sh b/contrib/examples/git-clone.sh index 547228e13c..b4c9376a2c 100755 --- a/contrib/examples/git-clone.sh +++ b/contrib/examples/git-clone.sh @@ -40,7 +40,7 @@ eval "$(echo "$OPTIONS_SPEC" | git rev-parse --parseopt -- "$@" || echo exit $?) get_repo_base() { ( - cd "`/bin/pwd`" && + cd "$(/bin/pwd)" && cd "$1" || cd "$1.git" && { cd .git @@ -50,7 +50,7 @@ get_repo_base() { } if [ -n "$GIT_SSL_NO_VERIFY" -o \ - "`git config --bool http.sslVerify`" = false ]; then + "$(git config --bool http.sslVerify)" = false ]; then curl_extra_args="-k" fi @@ -70,7 +70,7 @@ clone_dumb_http () { clone_tmp="$GIT_DIR/clone-tmp" && mkdir -p "$clone_tmp" || exit 1 if [ -n "$GIT_CURL_FTP_NO_EPSV" -o \ - "`git config --bool http.noEPSV`" = true ]; then + "$(git config --bool http.noEPSV)" = true ]; then curl_extra_args="${curl_extra_args} --disable-epsv" fi http_fetch "$1/info/refs" "$clone_tmp/refs" || @@ -79,7 +79,7 @@ Perhaps git-update-server-info needs to be run there?" test "z$quiet" = z && v=-v || v= while read sha1 refname do - name=`expr "z$refname" : 'zrefs/\(.*\)'` && + name=$(expr "z$refname" : 'zrefs/\(.*\)') && case "$name" in *^*) continue;; esac @@ -88,7 +88,7 @@ Perhaps git-update-server-info needs to be run there?" *) continue ;; esac if test -n "$use_separate_remote" && - branch_name=`expr "z$name" : 'zheads/\(.*\)'` + branch_name=$(expr "z$name" : 'zheads/\(.*\)') then tname="remotes/$origin/$branch_name" else @@ -100,7 +100,7 @@ Perhaps git-update-server-info needs to be run there?" http_fetch "$1/HEAD" "$GIT_DIR/REMOTE_HEAD" || rm -f "$GIT_DIR/REMOTE_HEAD" if test -f "$GIT_DIR/REMOTE_HEAD"; then - head_sha1=`cat "$GIT_DIR/REMOTE_HEAD"` + head_sha1=$(cat "$GIT_DIR/REMOTE_HEAD") case "$head_sha1" in 'ref: refs/'*) ;; @@ -444,15 +444,15 @@ then # a non-bare repository is always in separate-remote layout remote_top="refs/remotes/$origin" head_sha1= - test ! -r "$GIT_DIR/REMOTE_HEAD" || head_sha1=`cat "$GIT_DIR/REMOTE_HEAD"` + test ! -r "$GIT_DIR/REMOTE_HEAD" || head_sha1=$(cat "$GIT_DIR/REMOTE_HEAD") case "$head_sha1" in 'ref: refs/'*) # Uh-oh, the remote told us (http transport done against # new style repository with a symref HEAD). # Ideally we should skip the guesswork but for now # opt for minimum change. - head_sha1=`expr "z$head_sha1" : 'zref: refs/heads/\(.*\)'` - head_sha1=`cat "$GIT_DIR/$remote_top/$head_sha1"` + head_sha1=$(expr "z$head_sha1" : 'zref: refs/heads/\(.*\)') + head_sha1=$(cat "$GIT_DIR/$remote_top/$head_sha1") ;; esac @@ -467,7 +467,7 @@ then while read name do test t = $done && continue - branch_tip=`cat "$GIT_DIR/$remote_top/$name"` + branch_tip=$(cat "$GIT_DIR/$remote_top/$name") if test "$head_sha1" = "$branch_tip" then echo "$name" diff --git a/contrib/examples/git-commit.sh b/contrib/examples/git-commit.sh index 4aab1a6d21..5cafe2eb77 100755 --- a/contrib/examples/git-commit.sh +++ b/contrib/examples/git-commit.sh @@ -91,7 +91,7 @@ signoff= force_author= only_include_assumed= untracked_files= -templatefile="`git config commit.template`" +templatefile="$(git config commit.template)" while test $# != 0 do case "$1" in @@ -350,7 +350,7 @@ t,) TMP_INDEX="$GIT_DIR/tmp-index$$" W= test -z "$initial_commit" && W=--with-tree=HEAD - commit_only=`git ls-files --error-unmatch $W -- "$@"` || exit + commit_only=$(git ls-files --error-unmatch $W -- "$@") || exit # Build a temporary index and update the real index # the same way. @@ -475,8 +475,8 @@ then fi if test '' != "$force_author" then - GIT_AUTHOR_NAME=`expr "z$force_author" : 'z\(.*[^ ]\) *<.*'` && - GIT_AUTHOR_EMAIL=`expr "z$force_author" : '.*\(<.*\)'` && + GIT_AUTHOR_NAME=$(expr "z$force_author" : 'z\(.*[^ ]\) *<.*') && + GIT_AUTHOR_EMAIL=$(expr "z$force_author" : '.*\(<.*\)') && test '' != "$GIT_AUTHOR_NAME" && test '' != "$GIT_AUTHOR_EMAIL" || die "malformed --author parameter" @@ -489,7 +489,7 @@ then rloga='commit' if [ -f "$GIT_DIR/MERGE_HEAD" ]; then rloga='commit (merge)' - PARENTS="-p HEAD "`sed -e 's/^/-p /' "$GIT_DIR/MERGE_HEAD"` + PARENTS="-p HEAD "$(sed -e 's/^/-p /' "$GIT_DIR/MERGE_HEAD") elif test -n "$amend"; then rloga='commit (amend)' PARENTS=$(git cat-file commit HEAD | diff --git a/contrib/examples/git-fetch.sh b/contrib/examples/git-fetch.sh index a314273bd5..554070909c 100755 --- a/contrib/examples/git-fetch.sh +++ b/contrib/examples/git-fetch.sh @@ -67,7 +67,7 @@ do keep='-k -k' ;; --depth=*) - shallow_depth="--depth=`expr "z$1" : 'z-[^=]*=\(.*\)'`" + shallow_depth="--depth=$(expr "z$1" : 'z-[^=]*=\(.*\)')" ;; --depth) shift @@ -262,12 +262,12 @@ fetch_per_ref () { http://* | https://* | ftp://*) test -n "$shallow_depth" && die "shallow clone with http not supported" - proto=`expr "$remote" : '\([^:]*\):'` + proto=$(expr "$remote" : '\([^:]*\):') if [ -n "$GIT_SSL_NO_VERIFY" ]; then curl_extra_args="-k" fi if [ -n "$GIT_CURL_FTP_NO_EPSV" -o \ - "`git config --bool http.noEPSV`" = true ]; then + "$(git config --bool http.noEPSV)" = true ]; then noepsv_opt="--disable-epsv" fi diff --git a/contrib/examples/git-ls-remote.sh b/contrib/examples/git-ls-remote.sh index fec70bbf88..2aa89a7df8 100755 --- a/contrib/examples/git-ls-remote.sh +++ b/contrib/examples/git-ls-remote.sh @@ -55,11 +55,11 @@ tmpdir=$tmp-d case "$peek_repo" in http://* | https://* | ftp://* ) if [ -n "$GIT_SSL_NO_VERIFY" -o \ - "`git config --bool http.sslVerify`" = false ]; then + "$(git config --bool http.sslVerify)" = false ]; then curl_extra_args="-k" fi if [ -n "$GIT_CURL_FTP_NO_EPSV" -o \ - "`git config --bool http.noEPSV`" = true ]; then + "$(git config --bool http.noEPSV)" = true ]; then curl_extra_args="${curl_extra_args} --disable-epsv" fi curl -nsf $curl_extra_args --header "Pragma: no-cache" "$peek_repo/info/refs" || diff --git a/contrib/examples/git-merge.sh b/contrib/examples/git-merge.sh index a5e42a9f01..7e40f40c78 100755 --- a/contrib/examples/git-merge.sh +++ b/contrib/examples/git-merge.sh @@ -341,7 +341,7 @@ case "$use_strategies" in '') case "$#" in 1) - var="`git config --get pull.twohead`" + var="$(git config --get pull.twohead)" if test -n "$var" then use_strategies="$var" @@ -349,7 +349,7 @@ case "$use_strategies" in use_strategies="$default_twohead_strategies" fi ;; *) - var="`git config --get pull.octopus`" + var="$(git config --get pull.octopus)" if test -n "$var" then use_strategies="$var" diff --git a/contrib/examples/git-repack.sh b/contrib/examples/git-repack.sh index 757933174e..f312405a25 100755 --- a/contrib/examples/git-repack.sh +++ b/contrib/examples/git-repack.sh @@ -49,7 +49,7 @@ do shift done -case "`git config --bool repack.usedeltabaseoffset || echo true`" in +case "$(git config --bool repack.usedeltabaseoffset || echo true)" in true) extra="$extra --delta-base-offset" ;; esac diff --git a/contrib/examples/git-resolve.sh b/contrib/examples/git-resolve.sh index 8f98142f77..48d0fc971f 100755 --- a/contrib/examples/git-resolve.sh +++ b/contrib/examples/git-resolve.sh @@ -75,7 +75,7 @@ case "$common" in GIT_INDEX_FILE=$G git read-tree -m $c $head $merge \ 2>/dev/null || continue # Count the paths that are unmerged. - cnt=`GIT_INDEX_FILE=$G git ls-files --unmerged | wc -l` + cnt=$(GIT_INDEX_FILE=$G git ls-files --unmerged | wc -l) if test $best_cnt -le 0 -o $cnt -le $best_cnt then best=$c diff --git a/contrib/examples/git-revert.sh b/contrib/examples/git-revert.sh index 6bf155cbdb..7e2aad5491 100755 --- a/contrib/examples/git-revert.sh +++ b/contrib/examples/git-revert.sh @@ -137,7 +137,7 @@ cherry-pick) q }' - logmsg=`git show -s --pretty=raw --encoding="$encoding" "$commit"` + logmsg=$(git show -s --pretty=raw --encoding="$encoding" "$commit") set_author_env=`echo "$logmsg" | LANG=C LC_ALL=C sed -ne "$pick_author_script"` eval "$set_author_env" diff --git a/contrib/examples/git-tag.sh b/contrib/examples/git-tag.sh index 2c15bc955b..1bd8f3c58d 100755 --- a/contrib/examples/git-tag.sh +++ b/contrib/examples/git-tag.sh @@ -156,7 +156,7 @@ prev=0000000000000000000000000000000000000000 if git show-ref --verify --quiet -- "refs/tags/$name" then test -n "$force" || die "tag '$name' already exists" - prev=`git rev-parse "refs/tags/$name"` + prev=$(git rev-parse "refs/tags/$name") fi shift git check-ref-format "tags/$name" || diff --git a/contrib/hooks/multimail/CHANGES b/contrib/hooks/multimail/CHANGES new file mode 100644 index 0000000000..3603d56c26 --- /dev/null +++ b/contrib/hooks/multimail/CHANGES @@ -0,0 +1,33 @@ +Release 1.0.0 +============= + +* Fix encoding of non-ASCII email addresses in email headers. + +* Fix backwards-compatibility bugs for older Python 2.x versions. + +* Fix a backwards-compatibility bug for Git 1.7.1. + +* Add an option commitDiffOpts to customize logs for revisions. + +* Pass "-oi" to sendmail by default to prevent premature termination + on a line containing only ".". + +* Stagger email "Date:" values in an attempt to help mail clients + thread the emails in the right order. + +* If a mailing list setting is missing, just skip sending the + corresponding email (with a warning) instead of failing. + +* Add a X-Git-Host header that can be used for email filtering. + +* Allow the sender's fully-qualified domain name to be configured. + +* Minor documentation improvements. + +* Add this CHANGES file. + + +Release 0.9.0 +============= + +* Initial release. diff --git a/contrib/hooks/multimail/README b/contrib/hooks/multimail/README index 9904396710..477d65fed3 100644 --- a/contrib/hooks/multimail/README +++ b/contrib/hooks/multimail/README @@ -91,9 +91,10 @@ Requirements been tested; if you do so, please report your results.) * To send emails using the default configuration, a standard sendmail - program must be located at '/usr/sbin/sendmail' and configured - correctly to send emails. If this is not the case, see the - multimailhook.mailer configuration variable below for how to + program must be located at '/usr/sbin/sendmail' or + '/usr/lib/sendmail' and must be configured correctly to send emails. + If this is not the case, set multimailhook.sendmailCommand, or see + the multimailhook.mailer configuration variable below for how to configure git-multimail to send emails via an SMTP server. @@ -169,7 +170,7 @@ multimailhook.repoName for gitolite repositories, or otherwise to derive this value from the repository path name. -multimailhook.mailinglist +multimailhook.mailingList The list of email addresses to which notification emails should be sent, as RFC 2822 email addresses separated by commas. This @@ -184,26 +185,29 @@ multimailhook.refchangeList reference changes should be sent, as RFC 2822 email addresses separated by commas. This configuration option can be multivalued. The default is the value in - multimailhook.mailinglist. Set this value to the empty string to - prevent reference change emails from being sent. + multimailhook.mailingList. Set this value to the empty string to + prevent reference change emails from being sent even if + multimailhook.mailingList is set. multimailhook.announceList The list of email addresses to which emails about new annotated tags should be sent, as RFC 2822 email addresses separated by commas. This configuration option can be multivalued. The - default is the value in multimailhook.refchangelist or - multimailhook.mailinglist. Set this value to the empty string to - prevent annotated tag announcement emails from being sent. + default is the value in multimailhook.refchangeList or + multimailhook.mailingList. Set this value to the empty string to + prevent annotated tag announcement emails from being sent even if + one of the other values is set. multimailhook.commitList The list of email addresses to which emails about individual new commits should be sent, as RFC 2822 email addresses separated by commas. This configuration option can be multivalued. The - default is the value in multimailhook.mailinglist. Set this value + default is the value in multimailhook.mailingList. Set this value to the empty string to prevent notification emails about - individual commits from being sent. + individual commits from being sent even if + multimailhook.mailingList is set. multimailhook.announceShortlog @@ -237,10 +241,11 @@ multimailhook.mailer quoting is allowed in the value of this setting, but remember that Git requires double-quotes to be escaped; e.g., - git config multimailhook.sendmailcommand '/usr/sbin/sendmail -t -F \"Git Repo\"' + git config multimailhook.sendmailcommand '/usr/sbin/sendmail -oi -t -F \"Git Repo\"' - Default is '/usr/sbin/sendmail -t' or '/usr/lib/sendmail - -t' (depending on which file is present and executable). + Default is '/usr/sbin/sendmail -oi -t' or + '/usr/lib/sendmail -oi -t' (depending on which file is + present and executable). multimailhook.envelopeSender @@ -344,6 +349,14 @@ multimailhook.logOpts [multimailhook] logopts = --pretty=format:\"%h %aN <%aE>%n%s%n%n%b%n\" +multimailhook.commitLogOpts + + Options passed to "git log" to generate additional info for + revision change emails. For example, adding --ignore-all-spaces + will suppress whitespace changes. The default options are "-C + --stat -p --cc". Shell quoting is allowed; see + multimailhook.logOpts for details. + multimailhook.emailDomain Domain name appended to the username of the person doing the push @@ -381,8 +394,8 @@ Email filtering aids All emails include extra headers to enable fine tuned filtering and give information for debugging. All emails include the headers -"X-Git-Repo", "X-Git-Refname", and "X-Git-Reftype". ReferenceChange -emails also include headers "X-Git-Oldrev" and "X-Git-Newrev"; +"X-Git-Host", "X-Git-Repo", "X-Git-Refname", and "X-Git-Reftype". +ReferenceChange emails also include headers "X-Git-Oldrev" and "X-Git-Newrev"; Revision emails also include header "X-Git-Rev". @@ -463,6 +476,7 @@ The git-multimail project itself is currently hosted on GitHub: We use the GitHub issue tracker to keep track of bugs and feature requests, and GitHub pull requests to exchange patches (though, if you prefer, you can send patches via the Git mailing list with cc to me). +Please sign off your patches as per the Git project practice. Please note that although a copy of git-multimail will probably be distributed in the "contrib" section of the main Git project, diff --git a/contrib/hooks/multimail/README.Git b/contrib/hooks/multimail/README.Git index 9c2e66a69a..129b771410 100644 --- a/contrib/hooks/multimail/README.Git +++ b/contrib/hooks/multimail/README.Git @@ -6,10 +6,10 @@ website: https://github.com/mhagger/git-multimail The version in this directory was obtained from the upstream project -on 2013-07-14 and consists of the "git-multimail" subdirectory from +on 2014-04-07 and consists of the "git-multimail" subdirectory from revision - 1a5cb09c698a74d15a715a86b09ead5f56bf4b06 + 1b32653bafc4f902535b9fc1cd9cae911325b870 Please see the README file in this directory for information about how to report bugs or contribute to git-multimail. diff --git a/contrib/hooks/multimail/git_multimail.py b/contrib/hooks/multimail/git_multimail.py index 81c6a51706..8b58ed6444 100755 --- a/contrib/hooks/multimail/git_multimail.py +++ b/contrib/hooks/multimail/git_multimail.py @@ -1,6 +1,6 @@ #! /usr/bin/env python2 -# Copyright (c) 2012,2013 Michael Haggerty +# Copyright (c) 2012-2014 Michael Haggerty and others # Derived from contrib/hooks/post-receive-email, which is # Copyright (c) 2007 Andy Parkins # and also includes contributions by other authors. @@ -49,21 +49,25 @@ import sys import os import re import bisect +import socket import subprocess import shlex import optparse import smtplib +import time try: from email.utils import make_msgid from email.utils import getaddresses from email.utils import formataddr + from email.utils import formatdate from email.header import Header except ImportError: # Prior to Python 2.5, the email module used different names: from email.Utils import make_msgid from email.Utils import getaddresses from email.Utils import formataddr + from email.Utils import formatdate from email.Header import Header @@ -73,6 +77,7 @@ ZEROS = '0' * 40 LOGBEGIN = '- Log -----------------------------------------------------------------\n' LOGEND = '-----------------------------------------------------------------------\n' +ADDR_HEADERS = set(['from', 'to', 'cc', 'bcc', 'reply-to', 'sender']) # It is assumed in many places that the encoding is uniformly UTF-8, # so changing these constants is unsupported. But define them here @@ -95,6 +100,7 @@ REF_DELETED_SUBJECT_TEMPLATE = ( ) REFCHANGE_HEADER_TEMPLATE = """\ +Date: %(send_date)s To: %(recipients)s Subject: %(subject)s MIME-Version: 1.0 @@ -103,6 +109,7 @@ Content-Transfer-Encoding: 8bit Message-ID: %(msgid)s From: %(fromaddr)s Reply-To: %(reply_to)s +X-Git-Host: %(fqdn)s X-Git-Repo: %(repo_shortname)s X-Git-Refname: %(refname)s X-Git-Reftype: %(refname_type)s @@ -221,6 +228,7 @@ how to provide full information about this reference change. REVISION_HEADER_TEMPLATE = """\ +Date: %(send_date)s To: %(recipients)s Subject: %(emailprefix)s%(num)02d/%(tot)02d: %(oneline)s MIME-Version: 1.0 @@ -230,6 +238,7 @@ From: %(fromaddr)s Reply-To: %(reply_to)s In-Reply-To: %(reply_to_msgid)s References: %(reply_to_msgid)s +X-Git-Host: %(fqdn)s X-Git-Repo: %(repo_shortname)s X-Git-Refname: %(refname)s X-Git-Reftype: %(refname_type)s @@ -263,13 +272,43 @@ class ConfigurationException(Exception): pass +# The "git" program (this could be changed to include a full path): +GIT_EXECUTABLE = 'git' + + +# How "git" should be invoked (including global arguments), as a list +# of words. This variable is usually initialized automatically by +# read_git_output() via choose_git_command(), but if a value is set +# here then it will be used unconditionally. +GIT_CMD = None + + +def choose_git_command(): + """Decide how to invoke git, and record the choice in GIT_CMD.""" + + global GIT_CMD + + if GIT_CMD is None: + try: + # Check to see whether the "-c" option is accepted (it was + # only added in Git 1.7.2). We don't actually use the + # output of "git --version", though if we needed more + # specific version information this would be the place to + # do it. + cmd = [GIT_EXECUTABLE, '-c', 'foo.bar=baz', '--version'] + read_output(cmd) + GIT_CMD = [GIT_EXECUTABLE, '-c', 'i18n.logoutputencoding=%s' % (ENCODING,)] + except CommandError: + GIT_CMD = [GIT_EXECUTABLE] + + def read_git_output(args, input=None, keepends=False, **kw): """Read the output of a Git command.""" - return read_output( - ['git', '-c', 'i18n.logoutputencoding=%s' % (ENCODING,)] + args, - input=input, keepends=keepends, **kw - ) + if GIT_CMD is None: + choose_git_command() + + return read_output(GIT_CMD + args, input=input, keepends=keepends, **kw) def read_output(cmd, input=None, keepends=False, **kw): @@ -297,6 +336,31 @@ def read_git_lines(args, keepends=False, **kw): return read_git_output(args, keepends=True, **kw).splitlines(keepends) +def header_encode(text, header_name=None): + """Encode and line-wrap the value of an email header field.""" + + try: + if isinstance(text, str): + text = text.decode(ENCODING, 'replace') + return Header(text, header_name=header_name).encode() + except UnicodeEncodeError: + return Header(text, header_name=header_name, charset=CHARSET, + errors='replace').encode() + + +def addr_header_encode(text, header_name=None): + """Encode and line-wrap the value of an email header field containing + email addresses.""" + + return Header( + ', '.join( + formataddr((header_encode(name), emailaddr)) + for name, emailaddr in getaddresses([text]) + ), + header_name=header_name + ).encode() + + class Config(object): def __init__(self, section, git_config=None): """Represent a section of the git configuration. @@ -578,11 +642,11 @@ class Change(object): % (e.args[0], line,) ) else: - try: - h = Header(value, header_name=name) - except UnicodeDecodeError: - h = Header(value, header_name=name, charset=CHARSET, errors='replace') - for splitline in ('%s: %s\n' % (name, h.encode(),)).splitlines(True): + if name.lower() in ADDR_HEADERS: + value = addr_header_encode(value, name) + else: + value = header_encode(value, name) + for splitline in ('%s: %s\n' % (name, value)).splitlines(True): yield splitline def generate_email_header(self): @@ -616,15 +680,19 @@ class Change(object): raise NotImplementedError() - def generate_email(self, push, body_filter=None): + def generate_email(self, push, body_filter=None, extra_header_values={}): """Generate an email describing this change. Iterate over the lines (including the header lines) of an email describing this change. If body_filter is not None, then use it to filter the lines that are intended for the - email body.""" + email body. + + The extra_header_values field is received as a dict and not as + **kwargs, to allow passing other keyword arguments in the + future (e.g. passing extra values to generate_email_intro()""" - for line in self.generate_email_header(): + for line in self.generate_email_header(**extra_header_values): yield line yield '\n' for line in self.generate_email_intro(): @@ -680,8 +748,10 @@ class Revision(Change): return values - def generate_email_header(self): - for line in self.expand_header_lines(REVISION_HEADER_TEMPLATE): + def generate_email_header(self, **extra_values): + for line in self.expand_header_lines( + REVISION_HEADER_TEMPLATE, **extra_values + ): yield line def generate_email_intro(self): @@ -692,11 +762,7 @@ class Revision(Change): """Show this revision.""" return read_git_lines( - [ - 'log', '-C', - '--stat', '-p', '--cc', - '-1', self.rev.sha1, - ], + ['log'] + self.environment.commitlogopts + ['-1', self.rev.sha1], keepends=True, ) @@ -800,6 +866,7 @@ class ReferenceChange(Change): self.msgid = make_msgid() self.diffopts = environment.diffopts self.logopts = environment.logopts + self.commitlogopts = environment.commitlogopts self.showlog = environment.refchange_showlog def _compute_values(self): @@ -835,9 +902,12 @@ class ReferenceChange(Change): }[self.change_type] return self.expand(template) - def generate_email_header(self): + def generate_email_header(self, **extra_values): + if 'subject' not in extra_values: + extra_values['subject'] = self.get_subject() + for line in self.expand_header_lines( - REFCHANGE_HEADER_TEMPLATE, subject=self.get_subject(), + REFCHANGE_HEADER_TEMPLATE, **extra_values ): yield line @@ -1273,7 +1343,7 @@ class Mailer(object): class SendMailer(Mailer): - """Send emails using 'sendmail -t'.""" + """Send emails using 'sendmail -oi -t'.""" SENDMAIL_CANDIDATES = [ '/usr/sbin/sendmail', @@ -1302,7 +1372,7 @@ class SendMailer(Mailer): if command: self.command = command[:] else: - self.command = [self.find_sendmail(), '-t'] + self.command = [self.find_sendmail(), '-oi', '-t'] if envelopesender: self.command.extend(['-f', envelopesender]) @@ -1495,6 +1565,12 @@ class Environment(object): 'git log' when generating the detailed log for a set of commits (see refchange_showlog) + commitlogopts (list of strings) + + The options that should be passed to 'git log' for each + commit mail. The value should be a list of strings + representing words to be passed to the command. + """ REPO_NAME_RE = re.compile(r'^(?P<name>.+?)(?:\.git)$') @@ -1506,6 +1582,7 @@ class Environment(object): self.diffopts = ['--stat', '--summary', '--find-copies-harder'] self.logopts = [] self.refchange_showlog = False + self.commitlogopts = ['-C', '--stat', '-p', '--cc'] self.COMPUTED_KEYS = [ 'administrator', @@ -1672,6 +1749,10 @@ class ConfigOptionsEnvironmentMixin(ConfigEnvironmentMixin): if logopts is not None: self.logopts = shlex.split(logopts) + commitlogopts = config.get('commitlogopts') + if commitlogopts is not None: + self.commitlogopts = shlex.split(commitlogopts) + reply_to = config.get('replyTo') self.__reply_to_refchange = config.get('replyToRefchange', default=reply_to) if ( @@ -1829,6 +1910,47 @@ class ConfigMaxlinesEnvironmentMixin( ) +class FQDNEnvironmentMixin(Environment): + """A mixin that sets the host's FQDN to its constructor argument.""" + + def __init__(self, fqdn, **kw): + super(FQDNEnvironmentMixin, self).__init__(**kw) + self.COMPUTED_KEYS += ['fqdn'] + self.__fqdn = fqdn + + def get_fqdn(self): + """Return the fully-qualified domain name for this host. + + Return None if it is unavailable or unwanted.""" + + return self.__fqdn + + +class ConfigFQDNEnvironmentMixin( + ConfigEnvironmentMixin, + FQDNEnvironmentMixin, + ): + """Read the FQDN from the config.""" + + def __init__(self, config, **kw): + fqdn = config.get('fqdn') + super(ConfigFQDNEnvironmentMixin, self).__init__( + config=config, + fqdn=fqdn, + **kw + ) + + +class ComputeFQDNEnvironmentMixin(FQDNEnvironmentMixin): + """Get the FQDN by calling socket.getfqdn().""" + + def __init__(self, **kw): + super(ComputeFQDNEnvironmentMixin, self).__init__( + fqdn=socket.getfqdn(), + **kw + ) + + class PusherDomainEnvironmentMixin(ConfigEnvironmentMixin): """Deduce pusher_email from pusher by appending an emaildomain.""" @@ -1861,6 +1983,10 @@ class StaticRecipientsEnvironmentMixin(Environment): # actual *contents* of the change being reported, we only # choose based on the *type* of the change. Therefore we can # compute them once and for all: + if not (refchange_recipients + or announce_recipients + or revision_recipients): + raise ConfigurationException('No email recipients configured!') self.__refchange_recipients = refchange_recipients self.__announce_recipients = announce_recipients self.__revision_recipients = revision_recipients @@ -1911,17 +2037,8 @@ class ConfigRecipientsEnvironmentMixin( retval = config.get_recipients(name) if retval is not None: return retval - if len(names) == 1: - hint = 'Please set "%s.%s"' % (config.section, name) else: - hint = ( - 'Please set one of the following:\n "%s"' - % ('"\n "'.join('%s.%s' % (config.section, name) for name in names)) - ) - - raise ConfigurationException( - 'The list of recipients for %s is not configured.\n%s' % (names[0], hint) - ) + return '' class ProjectdescEnvironmentMixin(Environment): @@ -1956,6 +2073,7 @@ class GenericEnvironmentMixin(Environment): class GenericEnvironment( ProjectdescEnvironmentMixin, ConfigMaxlinesEnvironmentMixin, + ComputeFQDNEnvironmentMixin, ConfigFilterLinesEnvironmentMixin, ConfigRecipientsEnvironmentMixin, PusherDomainEnvironmentMixin, @@ -1980,9 +2098,27 @@ class GitoliteEnvironmentMixin(Environment): return self.osenv.get('GL_USER', 'unknown user') +class IncrementalDateTime(object): + """Simple wrapper to give incremental date/times. + + Each call will result in a date/time a second later than the + previous call. This can be used to falsify email headers, to + increase the likelihood that email clients sort the emails + correctly.""" + + def __init__(self): + self.time = time.time() + + def next(self): + formatted = formatdate(self.time, True) + self.time += 1 + return formatted + + class GitoliteEnvironment( ProjectdescEnvironmentMixin, ConfigMaxlinesEnvironmentMixin, + ComputeFQDNEnvironmentMixin, ConfigFilterLinesEnvironmentMixin, ConfigRecipientsEnvironmentMixin, PusherDomainEnvironmentMixin, @@ -2187,6 +2323,7 @@ class Push(object): # guarantee that one (and only one) email is generated for # each new commit. unhandled_sha1s = set(self.get_new_commits()) + send_date = IncrementalDateTime() for change in self.changes: # Check if we've got anyone to send to if not change.recipients: @@ -2197,7 +2334,11 @@ class Push(object): ) else: sys.stderr.write('Sending notification emails to: %s\n' % (change.recipients,)) - mailer.send(change.generate_email(self, body_filter), change.recipients) + extra_values = {'send_date' : send_date.next()} + mailer.send( + change.generate_email(self, body_filter, extra_values), + change.recipients, + ) sha1s = [] for sha1 in reversed(list(self.get_new_commits(change))): @@ -2217,7 +2358,11 @@ class Push(object): for (num, sha1) in enumerate(sha1s): rev = Revision(change, GitObject(sha1), num=num+1, tot=len(sha1s)) if rev.recipients: - mailer.send(rev.generate_email(self, body_filter), rev.recipients) + extra_values = {'send_date' : send_date.next()} + mailer.send( + rev.generate_email(self, body_filter, extra_values), + rev.recipients, + ) # Consistency check: if unhandled_sha1s: @@ -2288,6 +2433,7 @@ def choose_environment(config, osenv=None, env=None, recipients=None): environment_mixins = [ ProjectdescEnvironmentMixin, ConfigMaxlinesEnvironmentMixin, + ComputeFQDNEnvironmentMixin, ConfigFilterLinesEnvironmentMixin, PusherDomainEnvironmentMixin, ConfigOptionsEnvironmentMixin, diff --git a/contrib/hooks/multimail/post-receive b/contrib/hooks/multimail/post-receive index 93ebb437d1..4d46828ba5 100755 --- a/contrib/hooks/multimail/post-receive +++ b/contrib/hooks/multimail/post-receive @@ -66,10 +66,10 @@ mailer = git_multimail.choose_mailer(config, environment) # Alternatively, you may hardcode the mailer using code like one of # the following: -# Use "/usr/sbin/sendmail -t" to send emails. The envelopesender +# Use "/usr/sbin/sendmail -oi -t" to send emails. The envelopesender # argument is optional: #mailer = git_multimail.SendMailer( -# command=['/usr/sbin/sendmail', '-t'], +# command=['/usr/sbin/sendmail', '-oi', '-t'], # envelopesender='git-repo@example.com', # ) diff --git a/contrib/mw-to-git/t/t9360-mw-to-git-clone.sh b/contrib/mw-to-git/t/t9360-mw-to-git-clone.sh index 811a90c9ae..22f069db48 100755 --- a/contrib/mw-to-git/t/t9360-mw-to-git-clone.sh +++ b/contrib/mw-to-git/t/t9360-mw-to-git-clone.sh @@ -191,10 +191,10 @@ test_expect_success 'Git clone works with the shallow option' ' test_path_is_file mw_dir_11/Main_Page.mw && ( cd mw_dir_11 && - test `git log --oneline Nyan.mw | wc -l` -eq 1 && - test `git log --oneline Foo.mw | wc -l` -eq 1 && - test `git log --oneline Bar.mw | wc -l` -eq 1 && - test `git log --oneline Main_Page.mw | wc -l ` -eq 1 + test $(git log --oneline Nyan.mw | wc -l) -eq 1 && + test $(git log --oneline Foo.mw | wc -l) -eq 1 && + test $(git log --oneline Bar.mw | wc -l) -eq 1 && + test $(git log --oneline Main_Page.mw | wc -l ) -eq 1 ) && wiki_check_content mw_dir_11/Nyan.mw Nyan && wiki_check_content mw_dir_11/Foo.mw Foo && @@ -218,9 +218,9 @@ test_expect_success 'Git clone works with the shallow option with a delete page' test_path_is_file mw_dir_12/Main_Page.mw && ( cd mw_dir_12 && - test `git log --oneline Nyan.mw | wc -l` -eq 1 && - test `git log --oneline Bar.mw | wc -l` -eq 1 && - test `git log --oneline Main_Page.mw | wc -l ` -eq 1 + test $(git log --oneline Nyan.mw | wc -l) -eq 1 && + test $(git log --oneline Bar.mw | wc -l) -eq 1 && + test $(git log --oneline Main_Page.mw | wc -l ) -eq 1 ) && wiki_check_content mw_dir_12/Nyan.mw Nyan && wiki_check_content mw_dir_12/Bar.mw Bar && diff --git a/contrib/mw-to-git/t/t9362-mw-to-git-utf8.sh b/contrib/mw-to-git/t/t9362-mw-to-git-utf8.sh index 37021e200a..6b0dbdac4d 100755 --- a/contrib/mw-to-git/t/t9362-mw-to-git-utf8.sh +++ b/contrib/mw-to-git/t/t9362-mw-to-git-utf8.sh @@ -70,8 +70,8 @@ test_expect_success 'The shallow option works with accents' ' test_path_is_file mw_dir_4/Main_Page.mw && ( cd mw_dir_4 && - test `git log --oneline Néoà .mw | wc -l` -eq 1 && - test `git log --oneline Main_Page.mw | wc -l ` -eq 1 + test $(git log --oneline Néoà .mw | wc -l) -eq 1 && + test $(git log --oneline Main_Page.mw | wc -l ) -eq 1 ) && wiki_check_content mw_dir_4/Néoà .mw Néoà && wiki_check_content mw_dir_4/Main_Page.mw Main_Page diff --git a/contrib/remote-helpers/git-remote-bzr b/contrib/remote-helpers/git-remote-bzr index 5f4b2e3e16..9abb58e6ab 100755 --- a/contrib/remote-helpers/git-remote-bzr +++ b/contrib/remote-helpers/git-remote-bzr @@ -618,10 +618,12 @@ def parse_commit(parser): files[path] = f committer, date, tz = committer + author, _, _ = author parents = [mark_to_rev(p) for p in parents] revid = bzrlib.generate_ids.gen_revision_id(committer, date) props = {} props['branch-nick'] = branch.nick + props['authors'] = author mtree = CustomTree(branch, revid, parents, files) changes = mtree.iter_changes() @@ -784,7 +786,7 @@ def clone(path, remote_branch): def get_remote_branch(name): remote_branch = bzrlib.branch.Branch.open(branches[name], possible_transports=transports) - if isinstance(remote_branch.user_transport, bzrlib.transport.local.LocalTransport): + if isinstance(remote_branch.bzrdir.root_transport, bzrlib.transport.local.LocalTransport): return remote_branch branch_path = os.path.join(dirname, 'clone', name) @@ -867,7 +869,7 @@ def get_repo(url, alias): if not wanted: try: repo = origin.open_repository() - if not repo.user_transport.listable(): + if not repo.bzrdir.root_transport.listable(): # this repository is not usable for us raise bzrlib.errors.NoRepositoryPresent(repo.bzrdir) except bzrlib.errors.NoRepositoryPresent: diff --git a/contrib/remote-helpers/git-remote-hg b/contrib/remote-helpers/git-remote-hg index 36b526106b..34cda02759 100755 --- a/contrib/remote-helpers/git-remote-hg +++ b/contrib/remote-helpers/git-remote-hg @@ -260,6 +260,7 @@ class Parser: return (user, int(date), -tz) def fix_file_path(path): + path = os.path.normpath(path) if not os.path.isabs(path): return path return os.path.relpath(path, '/') diff --git a/contrib/remote-helpers/test-bzr.sh b/contrib/remote-helpers/test-bzr.sh index 4f379c2ab4..a4656ce412 100755 --- a/contrib/remote-helpers/test-bzr.sh +++ b/contrib/remote-helpers/test-bzr.sh @@ -382,7 +382,7 @@ test_expect_success 'strip' ' ' test_expect_success 'export utf-8 authors' ' - test_when_finished "rm -rf bzrrepo gitrepo && LC_ALL=C && unset GIT_COMMITTER_NAME" && + test_when_finished "rm -rf bzrrepo gitrepo && LC_ALL=C && GIT_COMMITTER_NAME=\"C O Mitter\"" LC_ALL=en_US.UTF-8 export LC_ALL @@ -411,4 +411,28 @@ test_expect_success 'export utf-8 authors' ' test_cmp expected actual ' +test_expect_success 'push different author' ' + test_when_finished "rm -rf bzrrepo gitrepo" && + + bzr init bzrrepo && + + ( + git init gitrepo && + cd gitrepo && + echo john >> content && + git add content && + git commit -m john --author "John Doe <jdoe@example.com>" && + git remote add bzr "bzr::../bzrrepo" && + git push bzr master + ) && + + ( + cd bzrrepo && + bzr log | grep "^author: " > ../actual + ) && + + echo "author: John Doe <jdoe@example.com>" > expected && + test_cmp expected actual +' + test_done diff --git a/contrib/remote-helpers/test-hg-bidi.sh b/contrib/remote-helpers/test-hg-bidi.sh index e24c51daad..d86e147d3d 100755 --- a/contrib/remote-helpers/test-hg-bidi.sh +++ b/contrib/remote-helpers/test-hg-bidi.sh @@ -8,7 +8,8 @@ test_description='Test bidirectionality of remote-hg' -. ./test-lib.sh +test -n "$TEST_DIRECTORY" || TEST_DIRECTORY=${0%/*}/../../t +. "$TEST_DIRECTORY"/test-lib.sh if ! test_have_prereq PYTHON then diff --git a/contrib/remote-helpers/test-hg-hg-git.sh b/contrib/remote-helpers/test-hg-hg-git.sh index 6dcd95d10f..b23909ae6c 100755 --- a/contrib/remote-helpers/test-hg-hg-git.sh +++ b/contrib/remote-helpers/test-hg-hg-git.sh @@ -8,7 +8,8 @@ test_description='Test remote-hg output compared to hg-git' -. ./test-lib.sh +test -n "$TEST_DIRECTORY" || TEST_DIRECTORY=${0%/*}/../../t +. "$TEST_DIRECTORY"/test-lib.sh if ! test_have_prereq PYTHON then @@ -144,8 +144,8 @@ void show_date_relative(unsigned long time, int tz, if (months) { struct strbuf sb = STRBUF_INIT; strbuf_addf(&sb, Q_("%lu year", "%lu years", years), years); - /* TRANSLATORS: "%s" is "<n> years" */ strbuf_addf(timebuf, + /* TRANSLATORS: "%s" is "<n> years" */ Q_("%s, %lu month ago", "%s, %lu months ago", months), sb.buf, months); strbuf_release(&sb); @@ -1461,20 +1461,12 @@ int print_stat_summary(FILE *fp, int files, int insertions, int deletions) * but nothing about added/removed lines? Is this a bug in Git?"). */ if (insertions || deletions == 0) { - /* - * TRANSLATORS: "+" in (+) is a line addition marker; - * do not translate it. - */ strbuf_addf(&sb, (insertions == 1) ? ", %d insertion(+)" : ", %d insertions(+)", insertions); } if (deletions || insertions == 0) { - /* - * TRANSLATORS: "-" in (-) is a line removal marker; - * do not translate it. - */ strbuf_addf(&sb, (deletions == 1) ? ", %d deletion(-)" : ", %d deletions(-)", deletions); diff --git a/git-rebase--am.sh b/git-rebase--am.sh index df46f4ca96..ca20e1e66f 100644 --- a/git-rebase--am.sh +++ b/git-rebase--am.sh @@ -4,6 +4,17 @@ # Copyright (c) 2010 Junio C Hamano. # +# The whole contents of this file is run by dot-sourcing it from +# inside a shell function. It used to be that "return"s we see +# below were not inside any function, and expected to return +# to the function that dot-sourced us. +# +# However, FreeBSD /bin/sh misbehaves on such a construct and +# continues to run the statements that follow such a "return". +# As a work-around, we introduce an extra layer of a function +# here, and immediately call it after defining it. +git_rebase__am () { + case "$action" in continue) git am --resolved --resolvemsg="$resolvemsg" \ @@ -75,3 +86,7 @@ then fi move_to_original_branch + +} +# ... and then we call the whole thing. +git_rebase__am diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 1c41cbd66c..6ec9d3cb40 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -820,6 +820,17 @@ add_exec_commands () { mv "$1.new" "$1" } +# The whole contents of this file is run by dot-sourcing it from +# inside a shell function. It used to be that "return"s we see +# below were not inside any function, and expected to return +# to the function that dot-sourced us. +# +# However, FreeBSD /bin/sh misbehaves on such a construct and +# continues to run the statements that follow such a "return". +# As a work-around, we introduce an extra layer of a function +# here, and immediately call it after defining it. +git_rebase__interactive () { + case "$action" in continue) # do we have anything to commit? @@ -1055,3 +1066,7 @@ GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $onto_name" output git checkout $onto || die_abort "could not detach HEAD" git update-ref ORIG_HEAD $orig_head do_rest + +} +# ... and then we call the whole thing. +git_rebase__interactive diff --git a/git-rebase--merge.sh b/git-rebase--merge.sh index 5381857c59..71429fd743 100644 --- a/git-rebase--merge.sh +++ b/git-rebase--merge.sh @@ -101,6 +101,17 @@ finish_rb_merge () { say All done. } +# The whole contents of this file is run by dot-sourcing it from +# inside a shell function. It used to be that "return"s we see +# below were not inside any function, and expected to return +# to the function that dot-sourced us. +# +# However, FreeBSD /bin/sh misbehaves on such a construct and +# continues to run the statements that follow such a "return". +# As a work-around, we introduce an extra layer of a function +# here, and immediately call it after defining it. +git_rebase__merge () { + case "$action" in continue) read_state @@ -151,3 +162,7 @@ do done finish_rb_merge + +} +# ... and then we call the whole thing. +git_rebase__merge diff --git a/git-rebase.sh b/git-rebase.sh index 2c75e9fa0f..4543815ffd 100755 --- a/git-rebase.sh +++ b/git-rebase.sh @@ -175,22 +175,13 @@ You can run "git stash pop" or "git stash drop" at any time. rm -rf "$state_dir" } -run_specific_rebase_internal () { +run_specific_rebase () { if [ "$interactive_rebase" = implied ]; then GIT_EDITOR=: export GIT_EDITOR autosquash= fi - # On FreeBSD, the shell's "return" returns from the current - # function, not from the current file inclusion. - # run_specific_rebase_internal has the file inclusion as a - # last statement, so POSIX and FreeBSD's return will do the - # same thing. . git-rebase--$type -} - -run_specific_rebase () { - run_specific_rebase_internal ret=$? if test $ret -eq 0 then diff --git a/git-svn.perl b/git-svn.perl index 7349ffea5a..0a323722a6 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -1389,17 +1389,7 @@ sub cmd_multi_init { usage(1); } - unless (defined $_prefix) { - $_prefix = ''; - warn <<EOF -WARNING: --prefix is not given, defaulting to empty prefix. - This is probably not what you want! In order to stay compatible - with regular remote-tracking refs, provide a prefix like - --prefix=origin/ (remember the trailing slash), which will cause - the SVN-tracking refs to be placed at refs/remotes/origin/*. -NOTE: In Git v2.0, the default prefix will change from empty to 'origin/'. -EOF - } + $_prefix = 'origin/' unless defined $_prefix; if (defined $url) { $url = canonicalize_url($url); init_subdir(@_); diff --git a/t/t5560-http-backend-noserver.sh b/t/t5560-http-backend-noserver.sh index 9be9ae3436..5abd11a563 100755 --- a/t/t5560-http-backend-noserver.sh +++ b/t/t5560-http-backend-noserver.sh @@ -9,8 +9,8 @@ test_have_prereq GREP_STRIPS_CR && export GREP_OPTIONS=-U run_backend() { echo "$2" | - QUERY_STRING="${1#*\?}" \ - PATH_TRANSLATED="$HTTPD_DOCUMENT_ROOT_PATH/${1%%\?*}" \ + QUERY_STRING="${1#*[?]}" \ + PATH_TRANSLATED="$HTTPD_DOCUMENT_ROOT_PATH/${1%%[?]*}" \ git http-backend >act.out 2>act.err } diff --git a/t/t7001-mv.sh b/t/t7001-mv.sh index 34fb1afbb3..54d78079e8 100755 --- a/t/t7001-mv.sh +++ b/t/t7001-mv.sh @@ -308,7 +308,7 @@ test_expect_success 'git mv moves a submodule with a .git directory and no .gitm ( cd sub && rm -f .git && - cp -a ../.git/modules/sub .git && + cp -R -P -p ../.git/modules/sub .git && GIT_WORK_TREE=. git config --unset core.worktree ) && mkdir mod && @@ -331,7 +331,7 @@ test_expect_success 'git mv moves a submodule with a .git directory and .gitmodu ( cd sub && rm -f .git && - cp -a ../.git/modules/sub .git && + cp -R -P -p ../.git/modules/sub .git && GIT_WORK_TREE=. git config --unset core.worktree ) && mkdir mod && diff --git a/t/t9107-git-svn-migrate.sh b/t/t9107-git-svn-migrate.sh index ee73013eed..6e69fc4c65 100755 --- a/t/t9107-git-svn-migrate.sh +++ b/t/t9107-git-svn-migrate.sh @@ -45,27 +45,27 @@ test_expect_success 'initialize old-style (v0) git svn layout' ' test_expect_success 'initialize a multi-repository repo' ' git svn init "$svnrepo" -T trunk -t tags -b branches && git config --get-all svn-remote.svn.fetch > fetch.out && - grep "^trunk:refs/remotes/trunk$" fetch.out && + grep "^trunk:refs/remotes/origin/trunk$" fetch.out && test -n "`git config --get svn-remote.svn.branches \ - "^branches/\*:refs/remotes/\*$"`" && + "^branches/\*:refs/remotes/origin/\*$"`" && test -n "`git config --get svn-remote.svn.tags \ - "^tags/\*:refs/remotes/tags/\*$"`" && + "^tags/\*:refs/remotes/origin/tags/\*$"`" && git config --unset svn-remote.svn.branches \ - "^branches/\*:refs/remotes/\*$" && + "^branches/\*:refs/remotes/origin/\*$" && git config --unset svn-remote.svn.tags \ - "^tags/\*:refs/remotes/tags/\*$" && - git config --add svn-remote.svn.fetch "branches/a:refs/remotes/a" && - git config --add svn-remote.svn.fetch "branches/b:refs/remotes/b" && + "^tags/\*:refs/remotes/origin/tags/\*$" && + git config --add svn-remote.svn.fetch "branches/a:refs/remotes/origin/a" && + git config --add svn-remote.svn.fetch "branches/b:refs/remotes/origin/b" && for i in tags/0.1 tags/0.2 tags/0.3; do git config --add svn-remote.svn.fetch \ - $i:refs/remotes/$i || exit 1; done && + $i:refs/remotes/origin/$i || exit 1; done && git config --get-all svn-remote.svn.fetch > fetch.out && - grep "^trunk:refs/remotes/trunk$" fetch.out && - grep "^branches/a:refs/remotes/a$" fetch.out && - grep "^branches/b:refs/remotes/b$" fetch.out && - grep "^tags/0\.1:refs/remotes/tags/0\.1$" fetch.out && - grep "^tags/0\.2:refs/remotes/tags/0\.2$" fetch.out && - grep "^tags/0\.3:refs/remotes/tags/0\.3$" fetch.out && + grep "^trunk:refs/remotes/origin/trunk$" fetch.out && + grep "^branches/a:refs/remotes/origin/a$" fetch.out && + grep "^branches/b:refs/remotes/origin/b$" fetch.out && + grep "^tags/0\.1:refs/remotes/origin/tags/0\.1$" fetch.out && + grep "^tags/0\.2:refs/remotes/origin/tags/0\.2$" fetch.out && + grep "^tags/0\.3:refs/remotes/origin/tags/0\.3$" fetch.out && grep "^:refs/${remotes_git_svn}" fetch.out ' @@ -73,14 +73,14 @@ test_expect_success 'initialize a multi-repository repo' ' test_expect_success 'multi-fetch works on partial urls + paths' " git svn multi-fetch && for i in trunk a b tags/0.1 tags/0.2 tags/0.3; do - git rev-parse --verify refs/remotes/\$i^0 >> refs.out || exit 1; + git rev-parse --verify refs/remotes/origin/\$i^0 >> refs.out || exit 1; done && test -z \"\`sort < refs.out | uniq -d\`\" && for i in trunk a b tags/0.1 tags/0.2 tags/0.3; do for j in trunk a b tags/0.1 tags/0.2 tags/0.3; do if test \$j != \$i; then continue; fi - test -z \"\`git diff refs/remotes/\$i \ - refs/remotes/\$j\`\" ||exit 1; done; done + test -z \"\`git diff refs/remotes/origin/\$i \ + refs/remotes/origin/\$j\`\" ||exit 1; done; done " test_expect_success 'migrate --minimize on old inited layout' ' @@ -98,27 +98,27 @@ test_expect_success 'migrate --minimize on old inited layout' ' git svn migrate --minimize && test -z "`git config -l | grep "^svn-remote\.git-svn\."`" && git config --get-all svn-remote.svn.fetch > fetch.out && - grep "^trunk:refs/remotes/trunk$" fetch.out && - grep "^branches/a:refs/remotes/a$" fetch.out && - grep "^branches/b:refs/remotes/b$" fetch.out && - grep "^tags/0\.1:refs/remotes/tags/0\.1$" fetch.out && - grep "^tags/0\.2:refs/remotes/tags/0\.2$" fetch.out && - grep "^tags/0\.3:refs/remotes/tags/0\.3$" fetch.out && + grep "^trunk:refs/remotes/origin/trunk$" fetch.out && + grep "^branches/a:refs/remotes/origin/a$" fetch.out && + grep "^branches/b:refs/remotes/origin/b$" fetch.out && + grep "^tags/0\.1:refs/remotes/origin/tags/0\.1$" fetch.out && + grep "^tags/0\.2:refs/remotes/origin/tags/0\.2$" fetch.out && + grep "^tags/0\.3:refs/remotes/origin/tags/0\.3$" fetch.out && grep "^:refs/${remotes_git_svn}" fetch.out ' test_expect_success ".rev_db auto-converted to .rev_map.UUID" ' git svn fetch -i trunk && - test -z "$(ls "$GIT_DIR"/svn/refs/remotes/trunk/.rev_db.* 2>/dev/null)" && - expect="$(ls "$GIT_DIR"/svn/refs/remotes/trunk/.rev_map.*)" && + test -z "$(ls "$GIT_DIR"/svn/refs/remotes/origin/trunk/.rev_db.* 2>/dev/null)" && + expect="$(ls "$GIT_DIR"/svn/refs/remotes/origin/trunk/.rev_map.*)" && test -n "$expect" && rev_db="$(echo $expect | sed -e "s,_map,_db,")" && convert_to_rev_db "$expect" "$rev_db" && rm -f "$expect" && test -f "$rev_db" && git svn fetch -i trunk && - test -z "$(ls "$GIT_DIR"/svn/refs/remotes/trunk/.rev_db.* 2>/dev/null)" && - test ! -e "$GIT_DIR"/svn/refs/remotes/trunk/.rev_db && + test -z "$(ls "$GIT_DIR"/svn/refs/remotes/origin/trunk/.rev_db.* 2>/dev/null)" && + test ! -e "$GIT_DIR"/svn/refs/remotes/origin/trunk/.rev_db && test -f "$expect" ' diff --git a/t/t9114-git-svn-dcommit-merge.sh b/t/t9114-git-svn-dcommit-merge.sh index d33d714006..fb41876677 100755 --- a/t/t9114-git-svn-dcommit-merge.sh +++ b/t/t9114-git-svn-dcommit-merge.sh @@ -48,7 +48,7 @@ test_expect_success 'setup svn repository' ' test_expect_success 'setup git mirror and merge' ' git svn init "$svnrepo" -t tags -T trunk -b branches && git svn fetch && - git checkout -b svn remotes/trunk && + git checkout -b svn remotes/origin/trunk && git checkout -b merge && echo new file > new_file && git add new_file && @@ -81,7 +81,7 @@ test_debug 'gitk --all & sleep 1' test_expect_success 'verify post-merge ancestry' " test x\`git rev-parse --verify refs/heads/svn\` = \ - x\`git rev-parse --verify refs/remotes/trunk \` && + x\`git rev-parse --verify refs/remotes/origin/trunk \` && test x\`git rev-parse --verify refs/heads/svn^2\` = \ x\`git rev-parse --verify refs/heads/merge\` && git cat-file commit refs/heads/svn^ | grep '^friend$' diff --git a/t/t9116-git-svn-log.sh b/t/t9116-git-svn-log.sh index cf4c05261b..45773ee560 100755 --- a/t/t9116-git-svn-log.sh +++ b/t/t9116-git-svn-log.sh @@ -20,20 +20,20 @@ test_expect_success 'setup repository and import' ' ) && git svn init "$svnrepo" -T trunk -b branches -t tags && git svn fetch && - git reset --hard trunk && + git reset --hard origin/trunk && echo bye >> README && git commit -a -m bye && git svn dcommit && - git reset --hard a && + git reset --hard origin/a && echo why >> FEEDME && git update-index --add FEEDME && git commit -m feedme && git svn dcommit && - git reset --hard trunk && + git reset --hard origin/trunk && echo aye >> README && git commit -a -m aye && git svn dcommit && - git reset --hard b && + git reset --hard origin/b && echo spy >> README && git commit -a -m spy && echo try >> README && @@ -42,26 +42,26 @@ test_expect_success 'setup repository and import' ' ' test_expect_success 'run log' " - git reset --hard a && - git svn log -r2 trunk | grep ^r2 && - git svn log -r4 trunk | grep ^r4 && + git reset --hard origin/a && + git svn log -r2 origin/trunk | grep ^r2 && + git svn log -r4 origin/trunk | grep ^r4 && git svn log -r3 | grep ^r3 " test_expect_success 'run log against a from trunk' " - git reset --hard trunk && - git svn log -r3 a | grep ^r3 + git reset --hard origin/trunk && + git svn log -r3 origin/a | grep ^r3 " printf 'r1 \nr2 \nr4 \n' > expected-range-r1-r2-r4 test_expect_success 'test ascending revision range' " - git reset --hard trunk && + git reset --hard origin/trunk && git svn log -r 1:4 | grep '^r[0-9]' | cut -d'|' -f1 | test_cmp expected-range-r1-r2-r4 - " test_expect_success 'test ascending revision range with --show-commit' " - git reset --hard trunk && + git reset --hard origin/trunk && git svn log --show-commit -r 1:4 | grep '^r[0-9]' | cut -d'|' -f1 | test_cmp expected-range-r1-r2-r4 - " @@ -69,7 +69,7 @@ test_expect_success 'test ascending revision range with --show-commit (sha1)' " git svn find-rev r1 >expected-range-r1-r2-r4-sha1 && git svn find-rev r2 >>expected-range-r1-r2-r4-sha1 && git svn find-rev r4 >>expected-range-r1-r2-r4-sha1 && - git reset --hard trunk && + git reset --hard origin/trunk && git svn log --show-commit -r 1:4 | grep '^r[0-9]' | cut -d'|' -f2 >out && git rev-parse \$(cat out) >actual && test_cmp expected-range-r1-r2-r4-sha1 actual @@ -78,67 +78,67 @@ test_expect_success 'test ascending revision range with --show-commit (sha1)' " printf 'r4 \nr2 \nr1 \n' > expected-range-r4-r2-r1 test_expect_success 'test descending revision range' " - git reset --hard trunk && + git reset --hard origin/trunk && git svn log -r 4:1 | grep '^r[0-9]' | cut -d'|' -f1 | test_cmp expected-range-r4-r2-r1 - " printf 'r1 \nr2 \n' > expected-range-r1-r2 test_expect_success 'test ascending revision range with unreachable revision' " - git reset --hard trunk && + git reset --hard origin/trunk && git svn log -r 1:3 | grep '^r[0-9]' | cut -d'|' -f1 | test_cmp expected-range-r1-r2 - " printf 'r2 \nr1 \n' > expected-range-r2-r1 test_expect_success 'test descending revision range with unreachable revision' " - git reset --hard trunk && + git reset --hard origin/trunk && git svn log -r 3:1 | grep '^r[0-9]' | cut -d'|' -f1 | test_cmp expected-range-r2-r1 - " printf 'r2 \n' > expected-range-r2 test_expect_success 'test ascending revision range with unreachable upper boundary revision and 1 commit' " - git reset --hard trunk && + git reset --hard origin/trunk && git svn log -r 2:3 | grep '^r[0-9]' | cut -d'|' -f1 | test_cmp expected-range-r2 - " test_expect_success 'test descending revision range with unreachable upper boundary revision and 1 commit' " - git reset --hard trunk && + git reset --hard origin/trunk && git svn log -r 3:2 | grep '^r[0-9]' | cut -d'|' -f1 | test_cmp expected-range-r2 - " printf 'r4 \n' > expected-range-r4 test_expect_success 'test ascending revision range with unreachable lower boundary revision and 1 commit' " - git reset --hard trunk && + git reset --hard origin/trunk && git svn log -r 3:4 | grep '^r[0-9]' | cut -d'|' -f1 | test_cmp expected-range-r4 - " test_expect_success 'test descending revision range with unreachable lower boundary revision and 1 commit' " - git reset --hard trunk && + git reset --hard origin/trunk && git svn log -r 4:3 | grep '^r[0-9]' | cut -d'|' -f1 | test_cmp expected-range-r4 - " printf -- '------------------------------------------------------------------------\n' > expected-separator test_expect_success 'test ascending revision range with unreachable boundary revisions and no commits' " - git reset --hard trunk && + git reset --hard origin/trunk && git svn log -r 5:6 | test_cmp expected-separator - " test_expect_success 'test descending revision range with unreachable boundary revisions and no commits' " - git reset --hard trunk && + git reset --hard origin/trunk && git svn log -r 6:5 | test_cmp expected-separator - " test_expect_success 'test ascending revision range with unreachable boundary revisions and 1 commit' " - git reset --hard trunk && + git reset --hard origin/trunk && git svn log -r 3:5 | grep '^r[0-9]' | cut -d'|' -f1 | test_cmp expected-range-r4 - " test_expect_success 'test descending revision range with unreachable boundary revisions and 1 commit' " - git reset --hard trunk && + git reset --hard origin/trunk && git svn log -r 5:3 | grep '^r[0-9]' | cut -d'|' -f1 | test_cmp expected-range-r4 - " diff --git a/t/t9117-git-svn-init-clone.sh b/t/t9117-git-svn-init-clone.sh index 69e9c0db5d..dfed76fedc 100755 --- a/t/t9117-git-svn-init-clone.sh +++ b/t/t9117-git-svn-init-clone.sh @@ -83,25 +83,25 @@ EOF rm -f expect actual } -test_expect_success 'init with -s/-T/-b/-t without --prefix warns' ' +test_expect_success 'init with -s/-T/-b/-t assumes --prefix=origin/' ' test ! -d project && git svn init -s "$svnrepo"/project project 2>warning && - grep -q prefix warning && - test_svn_configured_prefix "" && + test_must_fail grep -q prefix warning && + test_svn_configured_prefix "origin/" && rm -rf project && rm -f warning ' -test_expect_success 'clone with -s/-T/-b/-t without --prefix warns' ' +test_expect_success 'clone with -s/-T/-b/-t assumes --prefix=origin/' ' test ! -d project && git svn clone -s "$svnrepo"/project 2>warning && - grep -q prefix warning && - test_svn_configured_prefix "" && + test_must_fail grep -q prefix warning && + test_svn_configured_prefix "origin/" && rm -rf project && rm -f warning ' -test_expect_success 'init with -s/-T/-b/-t and --prefix does not warn' ' +test_expect_success 'init with -s/-T/-b/-t and --prefix="" still works' ' test ! -d project && git svn init -s "$svnrepo"/project project --prefix="" 2>warning && test_must_fail grep -q prefix warning && @@ -110,7 +110,7 @@ test_expect_success 'init with -s/-T/-b/-t and --prefix does not warn' ' rm -f warning ' -test_expect_success 'clone with -s/-T/-b/-t and --prefix does not warn' ' +test_expect_success 'clone with -s/-T/-b/-t and --prefix="" still works' ' test ! -d project && git svn clone -s "$svnrepo"/project --prefix="" 2>warning && test_must_fail grep -q prefix warning && diff --git a/t/t9118-git-svn-funky-branch-names.sh b/t/t9118-git-svn-funky-branch-names.sh index 15f93b4c28..ed4d1369cc 100755 --- a/t/t9118-git-svn-funky-branch-names.sh +++ b/t/t9118-git-svn-funky-branch-names.sh @@ -41,20 +41,20 @@ test_expect_success 'test clone with funky branch names' ' git svn clone -s "$svnrepo/pr ject" project && ( cd project && - git rev-parse "refs/remotes/fun%20plugin" && - git rev-parse "refs/remotes/more%20fun%20plugin!" && - git rev-parse "refs/remotes/$scary_ref" && - git rev-parse "refs/remotes/%2Eleading_dot" && - git rev-parse "refs/remotes/trailing_dot%2E" && - git rev-parse "refs/remotes/trailing_dotlock%2Elock" && - git rev-parse "refs/remotes/$non_reflog" + git rev-parse "refs/remotes/origin/fun%20plugin" && + git rev-parse "refs/remotes/origin/more%20fun%20plugin!" && + git rev-parse "refs/remotes/origin/$scary_ref" && + git rev-parse "refs/remotes/origin/%2Eleading_dot" && + git rev-parse "refs/remotes/origin/trailing_dot%2E" && + git rev-parse "refs/remotes/origin/trailing_dotlock%2Elock" && + git rev-parse "refs/remotes/origin/$non_reflog" ) ' test_expect_success 'test dcommit to funky branch' " ( cd project && - git reset --hard 'refs/remotes/more%20fun%20plugin!' && + git reset --hard 'refs/remotes/origin/more%20fun%20plugin!' && echo hello >> foo && git commit -m 'hello' -- foo && git svn dcommit @@ -64,7 +64,7 @@ test_expect_success 'test dcommit to funky branch' " test_expect_success 'test dcommit to scary branch' ' ( cd project && - git reset --hard "refs/remotes/$scary_ref" && + git reset --hard "refs/remotes/origin/$scary_ref" && echo urls are scary >> foo && git commit -m "eep" -- foo && git svn dcommit @@ -74,7 +74,7 @@ test_expect_success 'test dcommit to scary branch' ' test_expect_success 'test dcommit to trailing_dotlock branch' ' ( cd project && - git reset --hard "refs/remotes/trailing_dotlock%2Elock" && + git reset --hard "refs/remotes/origin/trailing_dotlock%2Elock" && echo who names branches like this anyway? >> foo && git commit -m "bar" -- foo && git svn dcommit diff --git a/t/t9120-git-svn-clone-with-percent-escapes.sh b/t/t9120-git-svn-clone-with-percent-escapes.sh index 1d92c05035..1c84ce1023 100755 --- a/t/t9120-git-svn-clone-with-percent-escapes.sh +++ b/t/t9120-git-svn-clone-with-percent-escapes.sh @@ -58,19 +58,19 @@ test_expect_success 'test clone --stdlayout with percent escapes' ' git svn clone --stdlayout "$svnrepo/pr%20ject" percent && ( cd percent && - git rev-parse refs/remotes/trunk^0 && - git rev-parse refs/remotes/b^0 && - git rev-parse refs/remotes/tags/v1^0 + git rev-parse refs/remotes/origin/trunk^0 && + git rev-parse refs/remotes/origin/b^0 && + git rev-parse refs/remotes/origin/tags/v1^0 ) ' test_expect_success 'test clone -s with unescaped space' ' - git svn clone -s "$svnrepo/pr ject" space && + git svn clone -s "$svnrepo/pr ject" --prefix origin/ space && ( cd space && - git rev-parse refs/remotes/trunk^0 && - git rev-parse refs/remotes/b^0 && - git rev-parse refs/remotes/tags/v1^0 + git rev-parse refs/remotes/origin/trunk^0 && + git rev-parse refs/remotes/origin/b^0 && + git rev-parse refs/remotes/origin/tags/v1^0 ) ' diff --git a/t/t9125-git-svn-multi-glob-branch-names.sh b/t/t9125-git-svn-multi-glob-branch-names.sh index 096abd1fe5..0d53fc9014 100755 --- a/t/t9125-git-svn-multi-glob-branch-names.sh +++ b/t/t9125-git-svn-multi-glob-branch-names.sh @@ -20,14 +20,14 @@ test_expect_success 'test clone with multi-glob in branch names' ' git svn clone -T trunk -b branches/*/* -t tags \ "$svnrepo/project" project && (cd project && - git rev-parse "refs/remotes/v14.1/beta" && - git rev-parse "refs/remotes/v14.1/gold" + git rev-parse "refs/remotes/origin/v14.1/beta" && + git rev-parse "refs/remotes/origin/v14.1/gold" ) ' test_expect_success 'test dcommit to multi-globbed branch' " (cd project && - git reset --hard 'refs/remotes/v14.1/gold' && + git reset --hard 'refs/remotes/origin/v14.1/gold' && echo hello >> foo && git commit -m 'hello' -- foo && git svn dcommit diff --git a/t/t9128-git-svn-cmd-branch.sh b/t/t9128-git-svn-cmd-branch.sh index 4b034a67f3..4e95f791db 100755 --- a/t/t9128-git-svn-cmd-branch.sh +++ b/t/t9128-git-svn-cmd-branch.sh @@ -29,30 +29,30 @@ test_expect_success 'initialize svnrepo' ' test_expect_success 'import into git' ' git svn init --stdlayout "$svnrepo" && git svn fetch && - git checkout remotes/trunk + git checkout remotes/origin/trunk ' test_expect_success 'git svn branch tests' ' git svn branch a && base=$(git rev-parse HEAD:) && - test $base = $(git rev-parse remotes/a:) && + test $base = $(git rev-parse remotes/origin/a:) && git svn branch -m "created branch b blah" b && - test $base = $(git rev-parse remotes/b:) && + test $base = $(git rev-parse remotes/origin/b:) && test_must_fail git branch -m "no branchname" && git svn branch -n c && - test_must_fail git rev-parse remotes/c && + test_must_fail git rev-parse remotes/origin/c && test_must_fail git svn branch a && git svn branch -t tag1 && - test $base = $(git rev-parse remotes/tags/tag1:) && + test $base = $(git rev-parse remotes/origin/tags/tag1:) && git svn branch --tag tag2 && - test $base = $(git rev-parse remotes/tags/tag2:) && + test $base = $(git rev-parse remotes/origin/tags/tag2:) && git svn tag tag3 && - test $base = $(git rev-parse remotes/tags/tag3:) && + test $base = $(git rev-parse remotes/origin/tags/tag3:) && git svn tag -m "created tag4 foo" tag4 && - test $base = $(git rev-parse remotes/tags/tag4:) && + test $base = $(git rev-parse remotes/origin/tags/tag4:) && test_must_fail git svn tag -m "no tagname" && git svn tag -n tag5 && - test_must_fail git rev-parse remotes/tags/tag5 && + test_must_fail git rev-parse remotes/origin/tags/tag5 && test_must_fail git svn tag tag1 ' diff --git a/t/t9135-git-svn-moved-branch-empty-file.sh b/t/t9135-git-svn-moved-branch-empty-file.sh index 5280e5f1e4..93db45db7d 100755 --- a/t/t9135-git-svn-moved-branch-empty-file.sh +++ b/t/t9135-git-svn-moved-branch-empty-file.sh @@ -12,7 +12,7 @@ test_expect_success 'clone using git svn' 'git svn clone -s "$svnrepo" x' test_expect_success 'test that b1 exists and is empty' ' ( cd x && - git reset --hard branch-c && + git reset --hard origin/branch-c && test -f b1 && ! test -s b1 ) diff --git a/t/t9141-git-svn-multiple-branches.sh b/t/t9141-git-svn-multiple-branches.sh index 3cd06718eb..8e7f7d68b7 100755 --- a/t/t9141-git-svn-multiple-branches.sh +++ b/t/t9141-git-svn-multiple-branches.sh @@ -66,18 +66,18 @@ test_expect_success 'clone multiple branch and tag paths' ' -t tags_A/* --tags tags_B \ "$svnrepo/project" git_project && ( cd git_project && - git rev-parse refs/remotes/first && - git rev-parse refs/remotes/second && - git rev-parse refs/remotes/1 && - git rev-parse refs/remotes/2 && - git rev-parse refs/remotes/tags/1.0 && - git rev-parse refs/remotes/tags/2.0 && - git rev-parse refs/remotes/tags/3.0 && - git rev-parse refs/remotes/tags/4.0 && - git rev-parse refs/remotes/tags/v5 && - git rev-parse refs/remotes/tags/v6 && - git rev-parse refs/remotes/tags/v7 && - git rev-parse refs/remotes/tags/v8 + git rev-parse refs/remotes/origin/first && + git rev-parse refs/remotes/origin/second && + git rev-parse refs/remotes/origin/1 && + git rev-parse refs/remotes/origin/2 && + git rev-parse refs/remotes/origin/tags/1.0 && + git rev-parse refs/remotes/origin/tags/2.0 && + git rev-parse refs/remotes/origin/tags/3.0 && + git rev-parse refs/remotes/origin/tags/4.0 && + git rev-parse refs/remotes/origin/tags/v5 && + git rev-parse refs/remotes/origin/tags/v6 && + git rev-parse refs/remotes/origin/tags/v7 && + git rev-parse refs/remotes/origin/tags/v8 ) ' @@ -85,8 +85,8 @@ test_expect_success 'Multiple branch or tag paths require -d' ' ( cd git_project && test_must_fail git svn branch -m "No new branch" Nope && test_must_fail git svn tag -m "No new tag" Tagless && - test_must_fail git rev-parse refs/remotes/Nope && - test_must_fail git rev-parse refs/remotes/tags/Tagless + test_must_fail git rev-parse refs/remotes/origin/Nope && + test_must_fail git rev-parse refs/remotes/origin/tags/Tagless ) && ( cd svn_project && svn_cmd up && diff --git a/t/t9145-git-svn-master-branch.sh b/t/t9145-git-svn-master-branch.sh index 16852d26ae..6559137493 100755 --- a/t/t9145-git-svn-master-branch.sh +++ b/t/t9145-git-svn-master-branch.sh @@ -17,7 +17,7 @@ test_expect_success 'git svn clone --stdlayout sets up trunk as master' ' git svn clone -s "$svnrepo" g && ( cd g && - test x`git rev-parse --verify refs/remotes/trunk^0` = \ + test x`git rev-parse --verify refs/remotes/origin/trunk^0` = \ x`git rev-parse --verify refs/heads/master^0` ) ' diff --git a/t/t9155-git-svn-fetch-deleted-tag.sh b/t/t9155-git-svn-fetch-deleted-tag.sh index a486a98f84..184336f346 100755 --- a/t/t9155-git-svn-fetch-deleted-tag.sh +++ b/t/t9155-git-svn-fetch-deleted-tag.sh @@ -35,8 +35,8 @@ test_expect_success 'fetch deleted tags from same revision with checksum error' cd git_project && git svn fetch && - git diff --exit-code mybranch:trunk/subdir/file tags/mytag:file && - git diff --exit-code master:subdir/file tags/mytag^:file + git diff --exit-code origin/mybranch:trunk/subdir/file origin/tags/mytag:file && + git diff --exit-code master:subdir/file origin/tags/mytag^:file ' test_done diff --git a/t/t9156-git-svn-fetch-deleted-tag-2.sh b/t/t9156-git-svn-fetch-deleted-tag-2.sh index 5ce7e2f3b0..7a6e33ba3c 100755 --- a/t/t9156-git-svn-fetch-deleted-tag-2.sh +++ b/t/t9156-git-svn-fetch-deleted-tag-2.sh @@ -36,9 +36,9 @@ test_expect_success 'fetch deleted tags from same revision with no checksum erro cd git_project && git svn fetch && - git diff --exit-code master:subdir3/file tags/mytag:file && - git diff --exit-code master:subdir2/file tags/mytag^:file && - git diff --exit-code master:subdir1/file tags/mytag^^:file + git diff --exit-code master:subdir3/file origin/tags/mytag:file && + git diff --exit-code master:subdir2/file origin/tags/mytag^:file && + git diff --exit-code master:subdir1/file origin/tags/mytag^^:file ' test_done diff --git a/t/t9161-git-svn-mergeinfo-push.sh b/t/t9161-git-svn-mergeinfo-push.sh index 1eab7015c7..6cb0909afe 100755 --- a/t/t9161-git-svn-mergeinfo-push.sh +++ b/t/t9161-git-svn-mergeinfo-push.sh @@ -18,8 +18,8 @@ test_expect_success 'load svn dump' " test_expect_success 'propagate merge information' ' git config svn.pushmergeinfo yes && - git checkout svnb1 && - git merge --no-ff svnb2 && + git checkout origin/svnb1 && + git merge --no-ff origin/svnb2 && git svn dcommit ' @@ -29,7 +29,7 @@ test_expect_success 'check svn:mergeinfo' ' ' test_expect_success 'merge another branch' ' - git merge --no-ff svnb3 && + git merge --no-ff origin/svnb3 && git svn dcommit ' @@ -40,7 +40,7 @@ test_expect_success 'check primary parent mergeinfo respected' ' ' test_expect_success 'merge existing merge' ' - git merge --no-ff svnb4 && + git merge --no-ff origin/svnb4 && git svn dcommit ' @@ -53,7 +53,7 @@ test_expect_success "check both parents' mergeinfo respected" ' ' test_expect_success 'make further commits to branch' ' - git checkout svnb2 && + git checkout origin/svnb2 && touch newb2file && git add newb2file && git commit -m "later b2 commit" && @@ -64,8 +64,8 @@ test_expect_success 'make further commits to branch' ' ' test_expect_success 'second forward merge' ' - git checkout svnb1 && - git merge --no-ff svnb2 && + git checkout origin/svnb1 && + git merge --no-ff origin/svnb2 && git svn dcommit ' @@ -78,8 +78,8 @@ test_expect_success 'check new mergeinfo added' ' ' test_expect_success 'reintegration merge' ' - git checkout svnb4 && - git merge --no-ff svnb1 && + git checkout origin/svnb4 && + git merge --no-ff origin/svnb1 && git svn dcommit ' @@ -92,11 +92,11 @@ test_expect_success 'check reintegration mergeinfo' ' ' test_expect_success 'dcommit a merge at the top of a stack' ' - git checkout svnb1 && + git checkout origin/svnb1 && touch anotherfile && git add anotherfile && git commit -m "a commit" && - git merge svnb4 && + git merge origin/svnb4 && git svn dcommit ' diff --git a/t/t9163-git-svn-reset-clears-caches.sh b/t/t9163-git-svn-reset-clears-caches.sh index cd4c662ba2..d6245cee08 100755 --- a/t/t9163-git-svn-reset-clears-caches.sh +++ b/t/t9163-git-svn-reset-clears-caches.sh @@ -70,9 +70,9 @@ test_expect_success 'rebase looses SVN merge (m)' ' # test_expect_success 'reset and fetch gets the SVN merge (m) correctly' ' git svn reset -r 3 && - git reset --hard trunk && + git reset --hard origin/trunk && git svn fetch && - test 2 = $(git cat-file -p trunk|grep parent|wc -l) + test 2 = $(git cat-file -p origin/trunk|grep parent|wc -l) ' test_done diff --git a/t/t9165-git-svn-fetch-merge-branch-of-branch.sh b/t/t9165-git-svn-fetch-merge-branch-of-branch.sh index 13ae7e33f9..fa3ef3b1f7 100755 --- a/t/t9165-git-svn-fetch-merge-branch-of-branch.sh +++ b/t/t9165-git-svn-fetch-merge-branch-of-branch.sh @@ -53,7 +53,7 @@ test_expect_success 'clone svn repo' ' ' test_expect_success 'verify merge commit' 'x=$(git rev-parse HEAD^2) && - y=$(git rev-parse branch2) && + y=$(git rev-parse origin/branch2) && test "x$x" = "x$y" ' diff --git a/t/t9166-git-svn-fetch-merge-branch-of-branch2.sh b/t/t9166-git-svn-fetch-merge-branch-of-branch2.sh index af0ec0e2e3..52f2e46a5b 100755 --- a/t/t9166-git-svn-fetch-merge-branch-of-branch2.sh +++ b/t/t9166-git-svn-fetch-merge-branch-of-branch2.sh @@ -46,7 +46,7 @@ test_expect_success 'clone svn repo' ' ' test_expect_success 'verify merge commit' 'x=$(git rev-parse HEAD^2) && - y=$(git rev-parse branch2) && + y=$(git rev-parse origin/branch2) && test "x$x" = "x$y" ' diff --git a/t/t9167-git-svn-cmd-branch-subproject.sh b/t/t9167-git-svn-cmd-branch-subproject.sh index 53def876ed..ba35fc06fc 100755 --- a/t/t9167-git-svn-cmd-branch-subproject.sh +++ b/t/t9167-git-svn-cmd-branch-subproject.sh @@ -31,7 +31,7 @@ test_expect_success 'import into git' ' git svn init --trunk=trunk/project --branches=branches/*/project \ --tags=tags/*/project "$svnrepo" && git svn fetch && - git checkout remotes/trunk + git checkout remotes/origin/trunk ' test_expect_success 'git svn branch tests' ' @@ -84,11 +84,10 @@ static int git_wcwidth(ucs_char_t ch) * "uniset +cat=Me +cat=Mn +cat=Cf -00AD +1160-11FF +200B c". */ static const struct interval combining[] = { - { 0x0300, 0x0357 }, { 0x035D, 0x036F }, { 0x0483, 0x0486 }, - { 0x0488, 0x0489 }, { 0x0591, 0x05A1 }, { 0x05A3, 0x05B9 }, - { 0x05BB, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 }, - { 0x05C4, 0x05C4 }, { 0x0600, 0x0603 }, { 0x0610, 0x0615 }, - { 0x064B, 0x0658 }, { 0x0670, 0x0670 }, { 0x06D6, 0x06E4 }, + { 0x0300, 0x036F }, { 0x0483, 0x0489 }, { 0x0591, 0x05BD }, + { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 }, { 0x05C4, 0x05C5 }, + { 0x05C7, 0x05C7 }, { 0x0600, 0x0604 }, { 0x0610, 0x061A }, + { 0x064B, 0x065F }, { 0x0670, 0x0670 }, { 0x06D6, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED }, { 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A }, { 0x07A6, 0x07B0 }, { 0x0901, 0x0902 }, { 0x093C, 0x093C }, { 0x0941, 0x0948 }, |