Skip to content

Commit 55a39a1

Browse files
Kevin Willforddscho
Kevin Willford
authored andcommitted
Merge pull request #64 Index changed hook
Index changed hook
2 parents 9779611 + 66887e1 commit 55a39a1

File tree

7 files changed

+182
-3
lines changed

7 files changed

+182
-3
lines changed

Documentation/githooks.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,24 @@ of the working directory and are separated by a single NUL. Full paths
512512
The exit status determines whether git will use the data from the
513513
hook. On error, git will abort the command with an error message.
514514

515+
post-indexchanged
516+
~~~~~~~~~~~~~~~~~
517+
518+
This hook is invoked when the index is written in read-cache.c
519+
do_write_locked_index.
520+
521+
The first parameter passed to the hook is the indicator for the
522+
working directory being updated. "1" meaning working directory
523+
was updated or "0" when the working directory was not updated.
524+
525+
The second parameter passed to the hook is the indicator for whether
526+
or not the index was updated and the skip-worktree bit could have
527+
changed. "1" meaning skip-worktree bits could have been updated
528+
and "0" meaning they were not.
529+
530+
Only one parameter should be set to "1" when the hook runs. The hook
531+
running passing "1", "1" should not be possible.
532+
515533
GIT
516534
---
517535
Part of the linkgit:git[1] suite

builtin/reset.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
470470
"use '--quiet' to avoid this. Set the config setting reset.quiet to true\n"
471471
"to make this the default.\n"), t_delta_in_ms / 1000.0);
472472
}
473+
the_index.updated_skipworktree = 1;
473474
}
474475
} else {
475476
int err = reset_index(&oid, reset_type, quiet);

builtin/update-index.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1069,6 +1069,8 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
10691069
entries = read_cache();
10701070
if (entries < 0)
10711071
die("cache corrupted");
1072+
1073+
the_index.updated_skipworktree = 1;
10721074

10731075
/*
10741076
* Custom copy of parse_options() because we want to handle

cache.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,9 @@ struct index_state {
329329
struct cache_time timestamp;
330330
unsigned name_hash_initialized : 1,
331331
initialized : 1,
332-
drop_cache_tree : 1;
332+
drop_cache_tree : 1,
333+
updated_workdir : 1,
334+
updated_skipworktree : 1;
333335
struct hashmap name_hash;
334336
struct hashmap dir_hash;
335337
struct object_id oid;

read-cache.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "commit.h"
1919
#include "blob.h"
2020
#include "resolve-undo.h"
21+
#include "run-command.h"
2122
#include "strbuf.h"
2223
#include "varint.h"
2324
#include "split-index.h"
@@ -3058,8 +3059,17 @@ static int do_write_locked_index(struct index_state *istate, struct lock_file *l
30583059
if (ret)
30593060
return ret;
30603061
if (flags & COMMIT_LOCK)
3061-
return commit_locked_index(lock);
3062-
return close_lock_file_gently(lock);
3062+
ret = commit_locked_index(lock);
3063+
else
3064+
ret = close_lock_file_gently(lock);
3065+
3066+
run_hook_le(NULL, "post-indexchanged",
3067+
istate->updated_workdir ? "1" : "0",
3068+
istate->updated_skipworktree ? "1" : "0", NULL);
3069+
istate->updated_workdir = 0;
3070+
istate->updated_skipworktree = 0;
3071+
3072+
return ret;
30633073
}
30643074

30653075
static int write_split_index(struct index_state *istate,

t/t7113-post-index-changed-hook.sh

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
#!/bin/sh
2+
3+
test_description='post index changed hook'
4+
5+
. ./test-lib.sh
6+
7+
test_expect_success 'setup' '
8+
mkdir -p dir1 &&
9+
touch dir1/file1.txt &&
10+
echo testing >dir1/file2.txt &&
11+
git add . &&
12+
git commit -m "initial"
13+
'
14+
15+
test_expect_success 'test status, add, commit, others trigger hook without flags set' '
16+
mkdir -p .git/hooks &&
17+
write_script .git/hooks/post-indexchanged <<-\EOF &&
18+
if test "$1" -eq 1; then
19+
echo "Invalid combination of flags passed to hook; updated_workdir is set." >testfailure
20+
exit 1
21+
fi
22+
if test "$2" -eq 1; then
23+
echo "Invalid combination of flags passed to hook; updated_skipworktree is set." >testfailure
24+
exit 1
25+
fi
26+
if test -f ".git/index.lock"; then
27+
echo ".git/index.lock exists" >testfailure
28+
exit 3
29+
fi
30+
if ! test -f ".git/index"; then
31+
echo ".git/index does not exist" >testfailure
32+
exit 3
33+
fi
34+
echo "success" >testsuccess
35+
EOF
36+
mkdir -p dir2 &&
37+
touch dir2/file1.txt &&
38+
touch dir2/file2.txt &&
39+
: force index to be dirty &&
40+
test-tool chmtime +60 dir1/file1.txt &&
41+
git status &&
42+
test_path_is_file testsuccess && rm -f testsuccess &&
43+
test_path_is_missing testfailure &&
44+
git add . &&
45+
test_path_is_file testsuccess && rm -f testsuccess &&
46+
test_path_is_missing testfailure &&
47+
git commit -m "second" &&
48+
test_path_is_file testsuccess && rm -f testsuccess &&
49+
test_path_is_missing testfailure &&
50+
git checkout -- dir1/file1.txt &&
51+
test_path_is_file testsuccess && rm -f testsuccess &&
52+
test_path_is_missing testfailure &&
53+
git update-index &&
54+
test_path_is_missing testsuccess &&
55+
test_path_is_missing testfailure &&
56+
git reset --soft &&
57+
test_path_is_missing testsuccess &&
58+
test_path_is_missing testfailure
59+
'
60+
61+
test_expect_success 'test checkout and reset trigger the hook' '
62+
write_script .git/hooks/post-indexchanged <<-\EOF &&
63+
if test "$1" -eq 1 && test "$2" -eq 1; then
64+
echo "Invalid combination of flags passed to hook; updated_workdir and updated_skipworktree are both set." >testfailure
65+
exit 1
66+
fi
67+
if test "$1" -eq 0 && test "$2" -eq 0; then
68+
echo "Invalid combination of flags passed to hook; neither updated_workdir or updated_skipworktree are set." >testfailure
69+
exit 2
70+
fi
71+
if test "$1" -eq 1; then
72+
if test -f ".git/index.lock"; then
73+
echo "updated_workdir set but .git/index.lock exists" >testfailure
74+
exit 3
75+
fi
76+
if ! test -f ".git/index"; then
77+
echo "updated_workdir set but .git/index does not exist" >testfailure
78+
exit 3
79+
fi
80+
else
81+
echo "update_workdir should be set for checkout" >testfailure
82+
exit 4
83+
fi
84+
echo "success" >testsuccess
85+
EOF
86+
: force index to be dirty &&
87+
test-tool chmtime +60 dir1/file1.txt &&
88+
git checkout master &&
89+
test_path_is_file testsuccess && rm -f testsuccess &&
90+
test_path_is_missing testfailure &&
91+
test-tool chmtime +60 dir1/file1.txt &&
92+
git checkout HEAD &&
93+
test_path_is_file testsuccess && rm -f testsuccess &&
94+
test_path_is_missing testfailure &&
95+
test-tool chmtime +60 dir1/file1.txt &&
96+
git reset --hard &&
97+
test_path_is_file testsuccess && rm -f testsuccess &&
98+
test_path_is_missing testfailure &&
99+
git checkout -B test &&
100+
test_path_is_file testsuccess && rm -f testsuccess &&
101+
test_path_is_missing testfailure
102+
'
103+
104+
test_expect_success 'test reset --mixed and update-index triggers the hook' '
105+
write_script .git/hooks/post-indexchanged <<-\EOF &&
106+
if test "$1" -eq 1 && test "$2" -eq 1; then
107+
echo "Invalid combination of flags passed to hook; updated_workdir and updated_skipworktree are both set." >testfailure
108+
exit 1
109+
fi
110+
if test "$1" -eq 0 && test "$2" -eq 0; then
111+
echo "Invalid combination of flags passed to hook; neither updated_workdir or updated_skipworktree are set." >testfailure
112+
exit 2
113+
fi
114+
if test "$2" -eq 1; then
115+
if test -f ".git/index.lock"; then
116+
echo "updated_skipworktree set but .git/index.lock exists" >testfailure
117+
exit 3
118+
fi
119+
if ! test -f ".git/index"; then
120+
echo "updated_skipworktree set but .git/index does not exist" >testfailure
121+
exit 3
122+
fi
123+
else
124+
echo "updated_skipworktree should be set for reset --mixed and update-index" >testfailure
125+
exit 4
126+
fi
127+
echo "success" >testsuccess
128+
EOF
129+
: force index to be dirty &&
130+
test-tool chmtime +60 dir1/file1.txt &&
131+
git reset --mixed HEAD~1 &&
132+
test_path_is_file testsuccess && rm -f testsuccess &&
133+
test_path_is_missing testfailure &&
134+
git hash-object -w --stdin <dir1/file2.txt >expect &&
135+
git update-index --cacheinfo 100644 "$(cat expect)" dir1/file1.txt &&
136+
test_path_is_file testsuccess && rm -f testsuccess &&
137+
test_path_is_missing testfailure &&
138+
git update-index --skip-worktree dir1/file2.txt &&
139+
git update-index --remove dir1/file2.txt &&
140+
test_path_is_file testsuccess && rm -f testsuccess &&
141+
test_path_is_missing testfailure
142+
'
143+
144+
test_done

unpack-trees.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1654,6 +1654,8 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
16541654
WRITE_TREE_SILENT |
16551655
WRITE_TREE_REPAIR);
16561656
}
1657+
1658+
o->result.updated_workdir = 1;
16571659
discard_index(o->dst_index);
16581660
*o->dst_index = o->result;
16591661
} else {

0 commit comments

Comments
 (0)