Skip to content

Commit

Permalink
Merge pull request #64 Index changed hook
Browse files Browse the repository at this point in the history
Index changed hook
  • Loading branch information
Kevin Willford authored and dscho committed Dec 15, 2018
2 parents 9779611 + 66887e1 commit 55a39a1
Show file tree
Hide file tree
Showing 7 changed files with 182 additions and 3 deletions.
18 changes: 18 additions & 0 deletions Documentation/githooks.txt
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,24 @@ of the working directory and are separated by a single NUL. Full paths
The exit status determines whether git will use the data from the
hook. On error, git will abort the command with an error message.

post-indexchanged
~~~~~~~~~~~~~~~~~

This hook is invoked when the index is written in read-cache.c
do_write_locked_index.

The first parameter passed to the hook is the indicator for the
working directory being updated. "1" meaning working directory
was updated or "0" when the working directory was not updated.

The second parameter passed to the hook is the indicator for whether
or not the index was updated and the skip-worktree bit could have
changed. "1" meaning skip-worktree bits could have been updated
and "0" meaning they were not.

Only one parameter should be set to "1" when the hook runs. The hook
running passing "1", "1" should not be possible.

GIT
---
Part of the linkgit:git[1] suite
1 change: 1 addition & 0 deletions builtin/reset.c
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
"use '--quiet' to avoid this. Set the config setting reset.quiet to true\n"
"to make this the default.\n"), t_delta_in_ms / 1000.0);
}
the_index.updated_skipworktree = 1;
}
} else {
int err = reset_index(&oid, reset_type, quiet);
Expand Down
2 changes: 2 additions & 0 deletions builtin/update-index.c
Original file line number Diff line number Diff line change
Expand Up @@ -1069,6 +1069,8 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
entries = read_cache();
if (entries < 0)
die("cache corrupted");

the_index.updated_skipworktree = 1;

/*
* Custom copy of parse_options() because we want to handle
Expand Down
4 changes: 3 additions & 1 deletion cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,9 @@ struct index_state {
struct cache_time timestamp;
unsigned name_hash_initialized : 1,
initialized : 1,
drop_cache_tree : 1;
drop_cache_tree : 1,
updated_workdir : 1,
updated_skipworktree : 1;
struct hashmap name_hash;
struct hashmap dir_hash;
struct object_id oid;
Expand Down
14 changes: 12 additions & 2 deletions read-cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "commit.h"
#include "blob.h"
#include "resolve-undo.h"
#include "run-command.h"
#include "strbuf.h"
#include "varint.h"
#include "split-index.h"
Expand Down Expand Up @@ -3058,8 +3059,17 @@ static int do_write_locked_index(struct index_state *istate, struct lock_file *l
if (ret)
return ret;
if (flags & COMMIT_LOCK)
return commit_locked_index(lock);
return close_lock_file_gently(lock);
ret = commit_locked_index(lock);
else
ret = close_lock_file_gently(lock);

run_hook_le(NULL, "post-indexchanged",
istate->updated_workdir ? "1" : "0",
istate->updated_skipworktree ? "1" : "0", NULL);
istate->updated_workdir = 0;
istate->updated_skipworktree = 0;

return ret;
}

static int write_split_index(struct index_state *istate,
Expand Down
144 changes: 144 additions & 0 deletions t/t7113-post-index-changed-hook.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
#!/bin/sh

test_description='post index changed hook'

. ./test-lib.sh

test_expect_success 'setup' '
mkdir -p dir1 &&
touch dir1/file1.txt &&
echo testing >dir1/file2.txt &&
git add . &&
git commit -m "initial"
'

test_expect_success 'test status, add, commit, others trigger hook without flags set' '
mkdir -p .git/hooks &&
write_script .git/hooks/post-indexchanged <<-\EOF &&
if test "$1" -eq 1; then
echo "Invalid combination of flags passed to hook; updated_workdir is set." >testfailure
exit 1
fi
if test "$2" -eq 1; then
echo "Invalid combination of flags passed to hook; updated_skipworktree is set." >testfailure
exit 1
fi
if test -f ".git/index.lock"; then
echo ".git/index.lock exists" >testfailure
exit 3
fi
if ! test -f ".git/index"; then
echo ".git/index does not exist" >testfailure
exit 3
fi
echo "success" >testsuccess
EOF
mkdir -p dir2 &&
touch dir2/file1.txt &&
touch dir2/file2.txt &&
: force index to be dirty &&
test-tool chmtime +60 dir1/file1.txt &&
git status &&
test_path_is_file testsuccess && rm -f testsuccess &&
test_path_is_missing testfailure &&
git add . &&
test_path_is_file testsuccess && rm -f testsuccess &&
test_path_is_missing testfailure &&
git commit -m "second" &&
test_path_is_file testsuccess && rm -f testsuccess &&
test_path_is_missing testfailure &&
git checkout -- dir1/file1.txt &&
test_path_is_file testsuccess && rm -f testsuccess &&
test_path_is_missing testfailure &&
git update-index &&
test_path_is_missing testsuccess &&
test_path_is_missing testfailure &&
git reset --soft &&
test_path_is_missing testsuccess &&
test_path_is_missing testfailure
'

test_expect_success 'test checkout and reset trigger the hook' '
write_script .git/hooks/post-indexchanged <<-\EOF &&
if test "$1" -eq 1 && test "$2" -eq 1; then
echo "Invalid combination of flags passed to hook; updated_workdir and updated_skipworktree are both set." >testfailure
exit 1
fi
if test "$1" -eq 0 && test "$2" -eq 0; then
echo "Invalid combination of flags passed to hook; neither updated_workdir or updated_skipworktree are set." >testfailure
exit 2
fi
if test "$1" -eq 1; then
if test -f ".git/index.lock"; then
echo "updated_workdir set but .git/index.lock exists" >testfailure
exit 3
fi
if ! test -f ".git/index"; then
echo "updated_workdir set but .git/index does not exist" >testfailure
exit 3
fi
else
echo "update_workdir should be set for checkout" >testfailure
exit 4
fi
echo "success" >testsuccess
EOF
: force index to be dirty &&
test-tool chmtime +60 dir1/file1.txt &&
git checkout master &&
test_path_is_file testsuccess && rm -f testsuccess &&
test_path_is_missing testfailure &&
test-tool chmtime +60 dir1/file1.txt &&
git checkout HEAD &&
test_path_is_file testsuccess && rm -f testsuccess &&
test_path_is_missing testfailure &&
test-tool chmtime +60 dir1/file1.txt &&
git reset --hard &&
test_path_is_file testsuccess && rm -f testsuccess &&
test_path_is_missing testfailure &&
git checkout -B test &&
test_path_is_file testsuccess && rm -f testsuccess &&
test_path_is_missing testfailure
'

test_expect_success 'test reset --mixed and update-index triggers the hook' '
write_script .git/hooks/post-indexchanged <<-\EOF &&
if test "$1" -eq 1 && test "$2" -eq 1; then
echo "Invalid combination of flags passed to hook; updated_workdir and updated_skipworktree are both set." >testfailure
exit 1
fi
if test "$1" -eq 0 && test "$2" -eq 0; then
echo "Invalid combination of flags passed to hook; neither updated_workdir or updated_skipworktree are set." >testfailure
exit 2
fi
if test "$2" -eq 1; then
if test -f ".git/index.lock"; then
echo "updated_skipworktree set but .git/index.lock exists" >testfailure
exit 3
fi
if ! test -f ".git/index"; then
echo "updated_skipworktree set but .git/index does not exist" >testfailure
exit 3
fi
else
echo "updated_skipworktree should be set for reset --mixed and update-index" >testfailure
exit 4
fi
echo "success" >testsuccess
EOF
: force index to be dirty &&
test-tool chmtime +60 dir1/file1.txt &&
git reset --mixed HEAD~1 &&
test_path_is_file testsuccess && rm -f testsuccess &&
test_path_is_missing testfailure &&
git hash-object -w --stdin <dir1/file2.txt >expect &&
git update-index --cacheinfo 100644 "$(cat expect)" dir1/file1.txt &&
test_path_is_file testsuccess && rm -f testsuccess &&
test_path_is_missing testfailure &&
git update-index --skip-worktree dir1/file2.txt &&
git update-index --remove dir1/file2.txt &&
test_path_is_file testsuccess && rm -f testsuccess &&
test_path_is_missing testfailure
'

test_done
2 changes: 2 additions & 0 deletions unpack-trees.c
Original file line number Diff line number Diff line change
Expand Up @@ -1654,6 +1654,8 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
WRITE_TREE_SILENT |
WRITE_TREE_REPAIR);
}

o->result.updated_workdir = 1;
discard_index(o->dst_index);
*o->dst_index = o->result;
} else {
Expand Down

0 comments on commit 55a39a1

Please sign in to comment.