summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/revisions.txt43
-rw-r--r--attr.c12
-rw-r--r--builtin/checkout.c2
-rw-r--r--dir.c2
-rw-r--r--git-rebase--interactive.sh25
-rwxr-xr-xgit-submodule.sh7
-rwxr-xr-xt/t1306-xdg-files.sh39
-rwxr-xr-xt/t3404-rebase-interactive.sh8
-rw-r--r--t/t7409-submodule-detached-worktree.sh61
-rw-r--r--t/test-lib.sh46
10 files changed, 195 insertions, 50 deletions
diff --git a/Documentation/revisions.txt b/Documentation/revisions.txt
index 1725661837..dc0070bcb7 100644
--- a/Documentation/revisions.txt
+++ b/Documentation/revisions.txt
@@ -24,22 +24,22 @@ blobs contained in a commit.
object referenced by 'refs/heads/master'. If you
happen to have both 'heads/master' and 'tags/master', you can
explicitly say 'heads/master' to tell git which one you mean.
- When ambiguous, a '<name>' is disambiguated by taking the
+ When ambiguous, a '<refname>' is disambiguated by taking the
first match in the following rules:
- . If '$GIT_DIR/<name>' exists, that is what you mean (this is usually
+ . If '$GIT_DIR/<refname>' exists, that is what you mean (this is usually
useful only for 'HEAD', 'FETCH_HEAD', 'ORIG_HEAD', 'MERGE_HEAD'
and 'CHERRY_PICK_HEAD');
- . otherwise, 'refs/<name>' if it exists;
+ . otherwise, 'refs/<refname>' if it exists;
. otherwise, 'refs/tags/<refname>' if it exists;
- . otherwise, 'refs/heads/<name>' if it exists;
+ . otherwise, 'refs/heads/<refname>' if it exists;
- . otherwise, 'refs/remotes/<name>' if it exists;
+ . otherwise, 'refs/remotes/<refname>' if it exists;
- . otherwise, 'refs/remotes/<name>/HEAD' if it exists.
+ . otherwise, 'refs/remotes/<refname>/HEAD' if it exists.
+
'HEAD' names the commit on which you based the changes in the working tree.
'FETCH_HEAD' records the branch which you fetched from a remote repository
@@ -218,13 +218,44 @@ and its parent commits exist. The 'r1{caret}@' notation means all
parents of 'r1'. 'r1{caret}!' includes commit 'r1' but excludes
all of its parents.
+To summarize:
+
+'<rev>'::
+ Include commits that are reachable from (i.e. ancestors of)
+ <rev>.
+
+'{caret}<rev>'::
+ Exclude commits that are reachable from (i.e. ancestors of)
+ <rev>.
+
+'<rev1>..<rev2>'::
+ Include commits that are reachable from <rev2> but exclude
+ those that are reachable from <rev1>.
+
+'<rev1>\...<rev2>'::
+ Include commits that are reachable from either <rev1> or
+ <rev2> but exclude those that are reachable from both.
+
+'<rev>{caret}@', e.g. 'HEAD{caret}@'::
+ A suffix '{caret}' followed by an at sign is the same as listing
+ all parents of '<rev>' (meaning, include anything reachable from
+ its parents, but not the commit itself).
+
+'<rev>{caret}!', e.g. 'HEAD{caret}!'::
+ A suffix '{caret}' followed by an exclamation mark is the same
+ as giving commit '<rev>' and then all its parents prefixed with
+ '{caret}' to exclude them (and their ancestors).
+
Here are a handful of examples:
D G H D
D F G H I J D F
^G D H D
^D B E I J F B
+ B..C C
B...C G H D E B C
^D B C E I J F B C
+ C I J F C
C^@ I J F
+ C^! C
F^! D G H D F
diff --git a/attr.c b/attr.c
index aef93d896f..b52efb55a0 100644
--- a/attr.c
+++ b/attr.c
@@ -520,11 +520,13 @@ static void bootstrap_attr_stack(void)
home_config_paths(NULL, &xdg_attributes_file, "attributes");
git_attributes_file = xdg_attributes_file;
}
- elem = read_attr_from_file(git_attributes_file, 1);
- if (elem) {
- elem->origin = NULL;
- elem->prev = attr_stack;
- attr_stack = elem;
+ if (git_attributes_file) {
+ elem = read_attr_from_file(git_attributes_file, 1);
+ if (elem) {
+ elem->origin = NULL;
+ elem->prev = attr_stack;
+ attr_stack = elem;
+ }
}
if (!is_bare_repository() || direction == GIT_ATTR_INDEX) {
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 6acca75f47..d812219b30 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -606,7 +606,7 @@ static int add_pending_uninteresting_ref(const char *refname,
const unsigned char *sha1,
int flags, void *cb_data)
{
- add_pending_sha1(cb_data, refname, sha1, flags | UNINTERESTING);
+ add_pending_sha1(cb_data, refname, sha1, UNINTERESTING);
return 0;
}
diff --git a/dir.c b/dir.c
index a772c6dc6c..240bf0c49c 100644
--- a/dir.c
+++ b/dir.c
@@ -1313,7 +1313,7 @@ void setup_standard_excludes(struct dir_struct *dir)
}
if (!access(path, R_OK))
add_excludes_from_file(dir, path);
- if (!access(excludes_file, R_OK))
+ if (excludes_file && !access(excludes_file, R_OK))
add_excludes_from_file(dir, excludes_file);
}
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index bef7bc0444..0d2056f027 100644
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -493,25 +493,28 @@ do_next () {
author_script_content=$(get_author_ident_from_commit HEAD)
echo "$author_script_content" > "$author_script"
eval "$author_script_content"
- output git reset --soft HEAD^
- pick_one -n $sha1 || die_failed_squash $sha1 "$rest"
+ if ! pick_one -n $sha1
+ then
+ git rev-parse --verify HEAD >"$amend"
+ die_failed_squash $sha1 "$rest"
+ fi
case "$(peek_next_command)" in
squash|s|fixup|f)
# This is an intermediate commit; its message will only be
# used in case of trouble. So use the long version:
- do_with_author output git commit --no-verify -F "$squash_msg" ||
+ do_with_author output git commit --amend --no-verify -F "$squash_msg" ||
die_failed_squash $sha1 "$rest"
;;
*)
# This is the final command of this squash/fixup group
if test -f "$fixup_msg"
then
- do_with_author git commit --no-verify -F "$fixup_msg" ||
+ do_with_author git commit --amend --no-verify -F "$fixup_msg" ||
die_failed_squash $sha1 "$rest"
else
cp "$squash_msg" "$GIT_DIR"/SQUASH_MSG || exit
rm -f "$GIT_DIR"/MERGE_MSG
- do_with_author git commit --no-verify -e ||
+ do_with_author git commit --amend --no-verify -F "$GIT_DIR"/SQUASH_MSG -e ||
die_failed_squash $sha1 "$rest"
fi
rm -f "$squash_msg" "$fixup_msg"
@@ -748,7 +751,6 @@ In both case, once you're done, continue with:
fi
. "$author_script" ||
die "Error trying to find the author identity to amend commit"
- current_head=
if test -f "$amend"
then
current_head=$(git rev-parse --verify HEAD)
@@ -756,13 +758,12 @@ In both case, once you're done, continue with:
die "\
You have uncommitted changes in your working tree. Please, commit them
first and then run 'git rebase --continue' again."
- git reset --soft HEAD^ ||
- die "Cannot rewind the HEAD"
+ do_with_author git commit --amend --no-verify -F "$msg" -e ||
+ die "Could not commit staged changes."
+ else
+ do_with_author git commit --no-verify -F "$msg" -e ||
+ die "Could not commit staged changes."
fi
- do_with_author git commit --no-verify -F "$msg" -e || {
- test -n "$current_head" && git reset --soft $current_head
- die "Could not commit staged changes."
- }
fi
record_in_rewritten "$(cat "$state_dir"/stopped-sha)"
diff --git a/git-submodule.sh b/git-submodule.sh
index dba4d39e1f..9210f3af56 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -181,8 +181,11 @@ module_clone()
rm -f "$gitdir/index"
else
mkdir -p "$gitdir_base"
- git clone $quiet -n ${reference:+"$reference"} \
- --separate-git-dir "$gitdir" "$url" "$sm_path" ||
+ (
+ clear_local_git_env
+ git clone $quiet -n ${reference:+"$reference"} \
+ --separate-git-dir "$gitdir" "$url" "$sm_path"
+ ) ||
die "$(eval_gettext "Clone of '\$url' into submodule path '\$sm_path' failed")"
fi
diff --git a/t/t1306-xdg-files.sh b/t/t1306-xdg-files.sh
index 3c75c3f2e7..8b14ab187c 100755
--- a/t/t1306-xdg-files.sh
+++ b/t/t1306-xdg-files.sh
@@ -38,6 +38,13 @@ test_expect_success 'read with --get: xdg file exists and ~/.gitconfig doesn'\''
test_cmp expected actual
'
+test_expect_success '"$XDG_CONFIG_HOME overrides $HOME/.config/git' '
+ mkdir -p "$HOME"/xdg/git &&
+ echo "[user]name = in_xdg" >"$HOME"/xdg/git/config &&
+ echo in_xdg >expected &&
+ XDG_CONFIG_HOME="$HOME"/xdg git config --get-all user.name >actual &&
+ test_cmp expected actual
+'
test_expect_success 'read with --get: xdg file exists and ~/.gitconfig exists' '
>.gitconfig &&
@@ -80,6 +87,17 @@ test_expect_success 'Exclusion of a file in the XDG ignore file' '
test_must_fail git add to_be_excluded
'
+test_expect_success '$XDG_CONFIG_HOME overrides $HOME/.config/git/ignore' '
+ mkdir -p "$HOME"/xdg/git &&
+ echo content >excluded_by_xdg_only &&
+ echo excluded_by_xdg_only >"$HOME"/xdg/git/ignore &&
+ test_when_finished "git read-tree --empty" &&
+ (XDG_CONFIG_HOME="$HOME/xdg" &&
+ export XDG_CONFIG_HOME &&
+ git add to_be_excluded &&
+ test_must_fail git add excluded_by_xdg_only
+ )
+'
test_expect_success 'Exclusion in both XDG and local ignore files' '
echo to_be_excluded >.gitignore &&
@@ -95,6 +113,13 @@ test_expect_success 'Exclusion in a non-XDG global ignore file' '
test_must_fail git add to_be_excluded
'
+test_expect_success 'Checking XDG ignore file when HOME is unset' '
+ >expected &&
+ (sane_unset HOME &&
+ git config --unset core.excludesfile &&
+ git ls-files --exclude-standard --ignored >actual) &&
+ test_cmp expected actual
+'
test_expect_success 'Checking attributes in the XDG attributes file' '
echo foo >f &&
@@ -106,6 +131,20 @@ test_expect_success 'Checking attributes in the XDG attributes file' '
test_cmp expected actual
'
+test_expect_success 'Checking XDG attributes when HOME is unset' '
+ >expected &&
+ (sane_unset HOME &&
+ git check-attr -a f >actual) &&
+ test_cmp expected actual
+'
+
+test_expect_success '$XDG_CONFIG_HOME overrides $HOME/.config/git/attributes' '
+ mkdir -p "$HOME"/xdg/git &&
+ echo "f attr_f=xdg" >"$HOME"/xdg/git/attributes &&
+ echo "f: attr_f: xdg" >expected &&
+ XDG_CONFIG_HOME="$HOME/xdg" git check-attr -a f >actual &&
+ test_cmp expected actual
+'
test_expect_success 'Checking attributes in both XDG and local attributes files' '
echo "f -attr_f" >.gitattributes &&
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 8078db6856..3f75d328de 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -903,4 +903,12 @@ test_expect_success 'rebase -i --root temporary sentinel commit' '
git rebase --abort
'
+test_expect_success 'rebase -i --root fixup root commit' '
+ git checkout B &&
+ FAKE_LINES="1 fixup 2" git rebase -i --root &&
+ test A = $(git cat-file commit HEAD | sed -ne \$p) &&
+ test B = $(git show HEAD:file1) &&
+ test 0 = $(git cat-file commit HEAD | grep -c ^parent\ )
+'
+
test_done
diff --git a/t/t7409-submodule-detached-worktree.sh b/t/t7409-submodule-detached-worktree.sh
new file mode 100644
index 0000000000..db75642fc3
--- /dev/null
+++ b/t/t7409-submodule-detached-worktree.sh
@@ -0,0 +1,61 @@
+#!/bin/sh
+#
+# Copyright (c) 2012 Daniel GraƱa
+#
+
+test_description='Test submodules on detached working tree
+
+This test verifies that "git submodule" initialization, update and addition works
+on detahced working trees
+'
+
+TEST_NO_CREATE_REPO=1
+. ./test-lib.sh
+
+test_expect_success 'submodule on detached working tree' '
+ git init --bare remote &&
+ test_create_repo bundle1 &&
+ (cd bundle1 && test_commit "shoot") &&
+ mkdir home &&
+ (
+ cd home &&
+ export GIT_WORK_TREE="$(pwd)" GIT_DIR="$(pwd)/.dotfiles" &&
+ git clone --bare ../remote .dotfiles &&
+ git submodule add ../bundle1 .vim/bundle/sogood &&
+ test_commit "sogood" &&
+ git push origin master
+ ) &&
+ mkdir home2 &&
+ (
+ cd home2 &&
+ export GIT_WORK_TREE="$(pwd)" GIT_DIR="$(pwd)/.dotfiles" &&
+ git clone --bare ../remote .dotfiles &&
+ git submodule update --init
+ )
+'
+
+test_expect_success 'submodule on detached working pointed by core.worktree' '
+ mkdir home3 &&
+ (
+ cd home3 &&
+ export GIT_DIR="$(pwd)/.dotfiles" &&
+ git clone --bare ../remote "$GIT_DIR" &&
+ git config core.bare false &&
+ git config core.worktree .. &&
+ git submodule add ../bundle1 .vim/bundle/dupe &&
+ test_commit "dupe" &&
+ git push origin master
+ ) &&
+ (
+ cd home &&
+ export GIT_DIR="$(pwd)/.dotfiles" &&
+ git config core.bare false &&
+ git config core.worktree .. &&
+ git pull &&
+ git submodule update &&
+ git submodule status &&
+ test -d .vim/bundle/dupe
+ )
+'
+
+test_done
diff --git a/t/test-lib.sh b/t/test-lib.sh
index acda33d177..bb4f8865b2 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -34,6 +34,26 @@ esac
# Keep the original TERM for say_color
ORIGINAL_TERM=$TERM
+# Test the binaries we have just built. The tests are kept in
+# t/ subdirectory and are run in 'trash directory' subdirectory.
+if test -z "$TEST_DIRECTORY"
+then
+ # We allow tests to override this, in case they want to run tests
+ # outside of t/, e.g. for running tests on the test library
+ # itself.
+ TEST_DIRECTORY=$(pwd)
+fi
+if test -z "$TEST_OUTPUT_DIRECTORY"
+then
+ # Similarly, override this to store the test-results subdir
+ # elsewhere
+ TEST_OUTPUT_DIRECTORY=$TEST_DIRECTORY
+fi
+GIT_BUILD_DIR="$TEST_DIRECTORY"/..
+
+. "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS
+export PERL_PATH SHELL_PATH
+
# For repeatability, reset the environment to known value.
LANG=C
LC_ALL=C
@@ -46,7 +66,7 @@ EDITOR=:
# /usr/xpg4/bin/sh and /bin/ksh to bail out. So keep the unsets
# deriving from the command substitution clustered with the other
# ones.
-unset VISUAL EMAIL LANGUAGE COLUMNS $(perl -e '
+unset VISUAL EMAIL LANGUAGE COLUMNS $("$PERL_PATH" -e '
my @env = keys %ENV;
my $ok = join("|", qw(
TRACE
@@ -61,6 +81,7 @@ unset VISUAL EMAIL LANGUAGE COLUMNS $(perl -e '
my @vars = grep(/^GIT_/ && !/^GIT_($ok)/o, @env);
print join("\n", @vars);
')
+unset XDG_CONFIG_HOME
GIT_AUTHOR_EMAIL=author@example.com
GIT_AUTHOR_NAME='A U Thor'
GIT_COMMITTER_EMAIL=committer@example.com
@@ -229,7 +250,7 @@ trap 'die' EXIT
# The user-facing functions are loaded from a separate file so that
# test_perf subshells can have them too
-. "${TEST_DIRECTORY:-.}"/test-lib-functions.sh
+. "$TEST_DIRECTORY/test-lib-functions.sh"
# You are not expected to call test_ok_ and test_failure_ directly, use
# the text_expect_* functions instead.
@@ -380,23 +401,6 @@ test_done () {
esac
}
-# Test the binaries we have just built. The tests are kept in
-# t/ subdirectory and are run in 'trash directory' subdirectory.
-if test -z "$TEST_DIRECTORY"
-then
- # We allow tests to override this, in case they want to run tests
- # outside of t/, e.g. for running tests on the test library
- # itself.
- TEST_DIRECTORY=$(pwd)
-fi
-if test -z "$TEST_OUTPUT_DIRECTORY"
-then
- # Similarly, override this to store the test-results subdir
- # elsewhere
- TEST_OUTPUT_DIRECTORY=$TEST_DIRECTORY
-fi
-GIT_BUILD_DIR="$TEST_DIRECTORY"/..
-
if test -n "$valgrind"
then
make_symlink () {
@@ -492,10 +496,6 @@ GIT_CONFIG_NOSYSTEM=1
GIT_ATTR_NOSYSTEM=1
export PATH GIT_EXEC_PATH GIT_TEMPLATE_DIR GIT_CONFIG_NOSYSTEM GIT_ATTR_NOSYSTEM
-. "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS
-
-export PERL_PATH
-
if test -z "$GIT_TEST_CMP"
then
if test -n "$GIT_TEST_CMP_USE_COPIED_CONTEXT"