Merge branch 'maint'

* maint:
  Update release notes for 1.6.0.3
  Teach rebase -i to honor pre-rebase hook
  docs: describe pre-rebase hook
  do not segfault if make_cache_entry failed
  make prefix_path() never return NULL
  fix bogus "diff --git" header from "diff --no-index"
  Fix fetch/clone --quiet when stdout is connected
  builtin-blame: Fix blame -C -C with submodules.
  bash: remove fetch, push, pull dashed form leftovers

Conflicts:
	diff.c
This commit is contained in:
Shawn O. Pearce 2008-10-06 08:56:07 -07:00
commit 276328ffb8
11 changed files with 246 additions and 44 deletions

View file

@ -13,33 +13,83 @@ Fixes since v1.6.0.2
* Continuing "git rebase -i" was also very confused when the user left
some staged changes in the index after "edit".
* "git rebase -i" now honors the pre-rebase hook, just like the
other rebase implementations "git rebase" and "git rebase -m".
* Behaviour of "git diff --quiet" was inconsistent with "diff --exit-code"
with the output redirected to /dev/null.
* "git diff --no-index" on binary files no longer outputs a bogus
"diff --git" header line.
* Hunk headers in "git diff" default to using extended regular
expressions, fixing some of the internal patterns on non-GNU
platforms.
* New config "diff.*.xfuncname" exposes extended regular expressions
for user specified hunk header patterns.
* "git stash apply sash@{1}" was fixed to error out. Prior versions
would have applied stash@{0} incorrectly.
* "git stash apply" now offers a better suggestion on how to continue
if the working tree is currently dirty.
* "git for-each-ref --format=%(subject)" fixed for commits with no
no newline in the message body.
* "git remote" fixed to protect printf from user input.
* "git remote show -v" now displays all URLs of a remote.
* "git checkout -q" once again suppresses the locally modified file list.
* "git clone -q", "git fetch -q" asks remote side to not send
progress messages, actually making their output quiet.
* Cross-directory renames are no longer used when creating packs. This
allows more graceful behavior on filesystems like sshfs.
* Stale temporary files under $GIT_DIR/objects/pack are now cleaned up
automatically by "git prune".
* "git merge" once agrain removes directories after the last file has
been removed from it during the merge.
* "git blame -C -C" no longer segfaults while trying to pass blame if
it encounters a submodule reference.
* "git svn" fixed to display an error message when 'set-tree' failed,
instead of a Perl compile error.
* "git submodule" fixed to handle checking out a different commit
than HEAD after initializing the submodule.
* The "git commit" error message when there are still unmerged
files present was clarified to match "git write-tree".
* Some segfaults due to uncaught NULL pointers were fixed multiple
tools such as apply, reset, update-index.
* Solaris bulds now default to OLD_ICONV=1 to avoid compile warnings.
* "Git.pm" tests relied on unnecessarily more recent version of Perl.
* "gitweb" triggered undef warning on commits without log messages.
* "gitweb" triggered undef warnings on missing trees.
* "gitweb" now removes PATH_INFO from its URLs so users don't have
to manually set the url in the gitweb configuration.
* Bash completion removed support for legacy "git-fetch", "git-push"
and "git-pull" as these are no longer installed. Dashless form
("git fetch") is still however supported.
Many other documentation updates.
--
exec >/var/tmp/1
O=v1.6.0.2-41-g7fe4a72
O=v1.6.0.2-76-gd70b4a8
echo O=$(git describe maint)
git shortlog --no-merges $O..maint

View file

@ -130,6 +130,13 @@ parameter, and is invoked after a commit is made.
This hook is meant primarily for notification, and cannot affect
the outcome of 'git-commit'.
pre-rebase
----------
This hook is called by 'git-rebase' and can be used to prevent a branch
from getting rebased.
post-checkout
-----------

View file

@ -1132,6 +1132,8 @@ static int find_copy_in_parent(struct scoreboard *sb,
if (!DIFF_FILE_VALID(p->one))
continue; /* does not exist in parent */
if (S_ISGITLINK(p->one->mode))
continue; /* ignore git links */
if (porigin && !strcmp(p->one->path, porigin->path))
/* find_move already dealt with this path */
continue;

View file

@ -785,14 +785,9 @@ _git_fetch ()
{
local cur="${COMP_WORDS[COMP_CWORD]}"
case "${COMP_WORDS[0]},$COMP_CWORD" in
git-fetch*,1)
if [ "$COMP_CWORD" = 2 ]; then
__gitcomp "$(__git_remotes)"
;;
git,2)
__gitcomp "$(__git_remotes)"
;;
*)
else
case "$cur" in
*:*)
local pfx=""
@ -811,8 +806,7 @@ _git_fetch ()
__gitcomp "$(__git_refs2 "$remote")"
;;
esac
;;
esac
fi
}
_git_format_patch ()
@ -1049,36 +1043,25 @@ _git_pull ()
{
local cur="${COMP_WORDS[COMP_CWORD]}"
case "${COMP_WORDS[0]},$COMP_CWORD" in
git-pull*,1)
if [ "$COMP_CWORD" = 2 ]; then
__gitcomp "$(__git_remotes)"
;;
git,2)
__gitcomp "$(__git_remotes)"
;;
*)
else
local remote
case "${COMP_WORDS[0]}" in
git-pull) remote="${COMP_WORDS[1]}" ;;
git) remote="${COMP_WORDS[2]}" ;;
esac
__gitcomp "$(__git_refs "$remote")"
;;
esac
fi
}
_git_push ()
{
local cur="${COMP_WORDS[COMP_CWORD]}"
case "${COMP_WORDS[0]},$COMP_CWORD" in
git-push*,1)
if [ "$COMP_CWORD" = 2 ]; then
__gitcomp "$(__git_remotes)"
;;
git,2)
__gitcomp "$(__git_remotes)"
;;
*)
else
case "$cur" in
*:*)
local remote
@ -1102,8 +1085,7 @@ _git_push ()
__gitcomp "$(__git_refs)"
;;
esac
;;
esac
fi
}
_git_rebase ()

4
diff.c
View file

@ -1509,6 +1509,10 @@ static void builtin_diff(const char *name_a,
b_prefix = o->b_prefix;
}
/* Never use a non-valid filename anywhere if at all possible */
name_a = DIFF_FILE_VALID(one) ? name_a : name_b;
name_b = DIFF_FILE_VALID(two) ? name_b : name_a;
a_one = quote_two(a_prefix, name_a + (*name_a == '/'));
b_two = quote_two(b_prefix, name_b + (*name_b == '/'));
lbl[0] = DIFF_FILE_VALID(one) ? a_one : "/dev/null";

View file

@ -65,6 +65,16 @@ output () {
esac
}
run_pre_rebase_hook () {
if test -x "$GIT_DIR/hooks/pre-rebase"
then
"$GIT_DIR/hooks/pre-rebase" ${1+"$@"} || {
echo >&2 "The pre-rebase hook refused to rebase."
exit 1
}
fi
}
require_clean_work_tree () {
# test if working tree is dirty
git rev-parse --verify HEAD > /dev/null &&
@ -507,6 +517,7 @@ first and then run 'git rebase --continue' again."
;;
--)
shift
run_pre_rebase_hook ${1+"$@"}
test $# -eq 1 -o $# -eq 2 || usage
test -d "$DOTEST" &&
die "Interactive rebase already started"

View file

@ -144,6 +144,16 @@ is_interactive () {
done && test -n "$1"
}
run_pre_rebase_hook () {
if test -x "$GIT_DIR/hooks/pre-rebase"
then
"$GIT_DIR/hooks/pre-rebase" ${1+"$@"} || {
echo >&2 "The pre-rebase hook refused to rebase."
exit 1
}
fi
}
test -f "$GIT_DIR"/rebase-apply/applying &&
die 'It looks like git-am is in progress. Cannot rebase.'
@ -320,13 +330,7 @@ onto_name=${newbase-"$upstream_name"}
onto=$(git rev-parse --verify "${onto_name}^0") || exit
# If a hook exists, give it a chance to interrupt
if test -x "$GIT_DIR/hooks/pre-rebase"
then
"$GIT_DIR/hooks/pre-rebase" ${1+"$@"} || {
echo >&2 "The pre-rebase hook refused to rebase."
exit 1
}
fi
run_pre_rebase_hook ${1+"$@"}
# If the branch to rebase is given, that is the branch we will rebase
# $branch_name -- branch being rebased, or HEAD (already detached)

View file

@ -110,9 +110,7 @@ const char *prefix_path(const char *prefix, int len, const char *path)
if (strncmp(sanitized, work_tree, len) ||
(sanitized[len] != '\0' && sanitized[len] != '/')) {
error_out:
error("'%s' is outside repository", orig);
free(sanitized);
return NULL;
die("'%s' is outside repository", orig);
}
if (sanitized[len] == '/')
len++;
@ -216,10 +214,7 @@ const char **get_pathspec(const char *prefix, const char **pathspec)
prefixlen = prefix ? strlen(prefix) : 0;
while (*src) {
const char *p = prefix_path(prefix, prefixlen, *src);
if (p)
*(dst++) = p;
else
exit(128); /* error message already given */
*(dst++) = p;
src++;
}
*dst = NULL;

126
t/t3409-rebase-hook.sh Executable file
View file

@ -0,0 +1,126 @@
#!/bin/sh
test_description='git rebase with its hook(s)'
. ./test-lib.sh
test_expect_success setup '
echo hello >file &&
git add file &&
test_tick &&
git commit -m initial &&
echo goodbye >file &&
git add file &&
test_tick &&
git commit -m second &&
git checkout -b side HEAD^ &&
echo world >git &&
git add git &&
test_tick &&
git commit -m side &&
git checkout master &&
git log --pretty=oneline --abbrev-commit --graph --all &&
git branch test side
'
test_expect_success 'rebase' '
git checkout test &&
git reset --hard side &&
git rebase master &&
test "z$(cat git)" = zworld
'
test_expect_success 'rebase -i' '
git checkout test &&
git reset --hard side &&
EDITOR=true git rebase -i master &&
test "z$(cat git)" = zworld
'
test_expect_success 'setup pre-rebase hook' '
mkdir -p .git/hooks &&
cat >.git/hooks/pre-rebase <<EOF &&
#!$SHELL_PATH
echo "\$1,\$2" >.git/PRE-REBASE-INPUT
EOF
chmod +x .git/hooks/pre-rebase
'
test_expect_success 'pre-rebase hook gets correct input (1)' '
git checkout test &&
git reset --hard side &&
git rebase master &&
test "z$(cat git)" = zworld &&
test "z$(cat .git/PRE-REBASE-INPUT)" = zmaster,
'
test_expect_success 'pre-rebase hook gets correct input (2)' '
git checkout test &&
git reset --hard side &&
git rebase master test &&
test "z$(cat git)" = zworld &&
test "z$(cat .git/PRE-REBASE-INPUT)" = zmaster,test
'
test_expect_success 'pre-rebase hook gets correct input (3)' '
git checkout test &&
git reset --hard side &&
git checkout master &&
git rebase master test &&
test "z$(cat git)" = zworld &&
test "z$(cat .git/PRE-REBASE-INPUT)" = zmaster,test
'
test_expect_success 'pre-rebase hook gets correct input (4)' '
git checkout test &&
git reset --hard side &&
EDITOR=true git rebase -i master &&
test "z$(cat git)" = zworld &&
test "z$(cat .git/PRE-REBASE-INPUT)" = zmaster,
'
test_expect_success 'pre-rebase hook gets correct input (5)' '
git checkout test &&
git reset --hard side &&
EDITOR=true git rebase -i master test &&
test "z$(cat git)" = zworld &&
test "z$(cat .git/PRE-REBASE-INPUT)" = zmaster,test
'
test_expect_success 'pre-rebase hook gets correct input (6)' '
git checkout test &&
git reset --hard side &&
git checkout master &&
EDITOR=true git rebase -i master test &&
test "z$(cat git)" = zworld &&
test "z$(cat .git/PRE-REBASE-INPUT)" = zmaster,test
'
test_expect_success 'setup pre-rebase hook that fails' '
mkdir -p .git/hooks &&
cat >.git/hooks/pre-rebase <<EOF &&
#!$SHELL_PATH
false
EOF
chmod +x .git/hooks/pre-rebase
'
test_expect_success 'pre-rebase hook stops rebase (1)' '
git checkout test &&
git reset --hard side &&
test_must_fail git rebase master &&
test "z$(git symbolic-ref HEAD)" = zrefs/heads/test &&
test 0 = $(git rev-list HEAD...side | wc -l)
'
test_expect_success 'pre-rebase hook stops rebase (2)' '
git checkout test &&
git reset --hard side &&
EDITOR=true test_must_fail git rebase -i master &&
test "z$(git symbolic-ref HEAD)" = zrefs/heads/test &&
test 0 = $(git rev-list HEAD...side | wc -l)
'
test_done

View file

@ -77,4 +77,25 @@ test_expect_success 'apply binary patch' \
tree1=`git write-tree` &&
test "$tree1" = "$tree0"'
q_to_nul() {
perl -pe 'y/Q/\000/'
}
nul_to_q() {
perl -pe 'y/\000/Q/'
}
test_expect_success 'diff --no-index with binary creation' '
echo Q | q_to_nul >binary &&
(:# hide error code from diff, which just indicates differences
git diff --binary --no-index /dev/null binary >current ||
true
) &&
rm binary &&
git apply --binary <current &&
echo Q >expected &&
nul_to_q <binary >actual &&
test_cmp expected actual
'
test_done

View file

@ -643,8 +643,8 @@ static int fetch_refs_via_pack(struct transport *transport,
args.use_thin_pack = data->thin;
args.include_tag = data->followtags;
args.verbose = (transport->verbose > 0);
args.quiet = args.no_progress = (transport->verbose < 0);
args.no_progress = !isatty(1);
args.quiet = (transport->verbose < 0);
args.no_progress = args.quiet || !isatty(1);
args.depth = data->depth;
for (i = 0; i < nr_heads; i++)