Merge branch 'bp/post-index-change-hook'
A new hook "post-index-change" is called when the on-disk index file changes, which can help e.g. a virtualized working tree implementation. * bp/post-index-change-hook: read-cache: add post-index-change hook
This commit is contained in:
commit
5795a75f9b
@ -496,6 +496,24 @@ This hook is invoked by `git-p4 submit`. It takes no parameters and nothing
|
||||
from standard input. Exiting with non-zero status from this script prevent
|
||||
`git-p4 submit` from launching. Run `git-p4 submit --help` for details.
|
||||
|
||||
post-index-change
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
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
|
||||
|
@ -386,6 +386,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
|
||||
int flags = quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN;
|
||||
if (read_from_tree(&pathspec, &oid, intent_to_add))
|
||||
return 1;
|
||||
the_index.updated_skipworktree = 1;
|
||||
if (!quiet && get_git_work_tree()) {
|
||||
uint64_t t_begin, t_delta_in_ms;
|
||||
|
||||
|
@ -1082,6 +1082,8 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
|
||||
if (entries < 0)
|
||||
die("cache corrupted");
|
||||
|
||||
the_index.updated_skipworktree = 1;
|
||||
|
||||
/*
|
||||
* Custom copy of parse_options() because we want to handle
|
||||
* filename arguments as they come.
|
||||
|
4
cache.h
4
cache.h
@ -339,7 +339,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;
|
||||
|
14
read-cache.c
14
read-cache.c
@ -17,6 +17,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"
|
||||
@ -3049,8 +3050,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-index-change",
|
||||
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,
|
||||
|
144
t/t7113-post-index-change-hook.sh
Executable file
144
t/t7113-post-index-change-hook.sh
Executable file
@ -0,0 +1,144 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_description='post index change 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-index-change <<-\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-index-change <<-\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-index-change <<-\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 --quiet 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
|
@ -1618,6 +1618,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 {
|
||||
|
Loading…
Reference in New Issue
Block a user