66#include "run-command.h"
77#include "strbuf.h"
88
9- #define INDEX_EXTENSION_VERSION (1)
10- #define HOOK_INTERFACE_VERSION (1)
9+ #define INDEX_EXTENSION_VERSION1 (1)
10+ #define INDEX_EXTENSION_VERSION2 (2)
11+ #define HOOK_INTERFACE_VERSION (1)
1112
1213struct trace_key trace_fsmonitor = TRACE_KEY_INIT (FSMONITOR );
1314
@@ -32,17 +33,26 @@ int read_fsmonitor_extension(struct index_state *istate, const void *data,
3233 uint32_t ewah_size ;
3334 struct ewah_bitmap * fsmonitor_dirty ;
3435 int ret ;
36+ uint64_t timestamp ;
37+ struct strbuf last_update = STRBUF_INIT ;
3538
36- if (sz < sizeof (uint32_t ) + sizeof ( uint64_t ) + sizeof (uint32_t ))
39+ if (sz < sizeof (uint32_t ) + 1 + sizeof (uint32_t ))
3740 return error ("corrupt fsmonitor extension (too short)" );
3841
3942 hdr_version = get_be32 (index );
4043 index += sizeof (uint32_t );
41- if (hdr_version != INDEX_EXTENSION_VERSION )
44+ if (hdr_version == INDEX_EXTENSION_VERSION1 ) {
45+ timestamp = get_be64 (index );
46+ strbuf_addf (& last_update , "%" PRIu64 "" , timestamp );
47+ index += sizeof (uint64_t );
48+ } else if (hdr_version == INDEX_EXTENSION_VERSION2 ) {
49+ strbuf_addstr (& last_update , index );
50+ index += last_update .len + 1 ;
51+ } else {
4252 return error ("bad fsmonitor version %d" , hdr_version );
53+ }
4354
44- istate -> fsmonitor_last_update = get_be64 (index );
45- index += sizeof (uint64_t );
55+ istate -> fsmonitor_last_update = strbuf_detach (& last_update , NULL );
4656
4757 ewah_size = get_be32 (index );
4858 index += sizeof (uint32_t );
@@ -79,7 +89,6 @@ void fill_fsmonitor_bitmap(struct index_state *istate)
7989void write_fsmonitor_extension (struct strbuf * sb , struct index_state * istate )
8090{
8191 uint32_t hdr_version ;
82- uint64_t tm ;
8392 uint32_t ewah_start ;
8493 uint32_t ewah_size = 0 ;
8594 int fixup = 0 ;
@@ -89,11 +98,12 @@ void write_fsmonitor_extension(struct strbuf *sb, struct index_state *istate)
8998 BUG ("fsmonitor_dirty has more entries than the index (%" PRIuMAX " > %u)" ,
9099 (uintmax_t )istate -> fsmonitor_dirty -> bit_size , istate -> cache_nr );
91100
92- put_be32 (& hdr_version , INDEX_EXTENSION_VERSION );
101+ put_be32 (& hdr_version , INDEX_EXTENSION_VERSION2 );
93102 strbuf_add (sb , & hdr_version , sizeof (uint32_t ));
94103
95- put_be64 (& tm , istate -> fsmonitor_last_update );
96- strbuf_add (sb , & tm , sizeof (uint64_t ));
104+ strbuf_addstr (sb , istate -> fsmonitor_last_update );
105+ strbuf_addch (sb , 0 ); /* Want to keep a NUL */
106+
97107 fixup = sb -> len ;
98108 strbuf_add (sb , & ewah_size , sizeof (uint32_t )); /* we'll fix this up later */
99109
@@ -110,9 +120,9 @@ void write_fsmonitor_extension(struct strbuf *sb, struct index_state *istate)
110120}
111121
112122/*
113- * Call the query-fsmonitor hook passing the time of the last saved results.
123+ * Call the query-fsmonitor hook passing the last update token of the saved results.
114124 */
115- static int query_fsmonitor (int version , uint64_t last_update , struct strbuf * query_result )
125+ static int query_fsmonitor (int version , const char * last_update , struct strbuf * query_result )
116126{
117127 struct child_process cp = CHILD_PROCESS_INIT ;
118128
@@ -121,7 +131,7 @@ static int query_fsmonitor(int version, uint64_t last_update, struct strbuf *que
121131
122132 argv_array_push (& cp .args , core_fsmonitor );
123133 argv_array_pushf (& cp .args , "%d" , version );
124- argv_array_pushf (& cp .args , "%" PRIuMAX , ( uintmax_t ) last_update );
134+ argv_array_pushf (& cp .args , "%s" , last_update );
125135 cp .use_shell = 1 ;
126136 cp .dir = get_git_work_tree ();
127137
@@ -151,6 +161,7 @@ void refresh_fsmonitor(struct index_state *istate)
151161 int query_success = 0 ;
152162 size_t bol ; /* beginning of line */
153163 uint64_t last_update ;
164+ struct strbuf last_update_token = STRBUF_INIT ;
154165 char * buf ;
155166 unsigned int i ;
156167
@@ -164,6 +175,7 @@ void refresh_fsmonitor(struct index_state *istate)
164175 * should be inclusive to ensure we don't miss potential changes.
165176 */
166177 last_update = getnanotime ();
178+ strbuf_addf (& last_update_token , "%" PRIu64 "" , last_update );
167179
168180 /*
169181 * If we have a last update time, call query_fsmonitor for the set of
@@ -217,18 +229,21 @@ void refresh_fsmonitor(struct index_state *istate)
217229 }
218230 strbuf_release (& query_result );
219231
220- /* Now that we've updated istate, save the last_update time */
221- istate -> fsmonitor_last_update = last_update ;
232+ /* Now that we've updated istate, save the last_update_token */
233+ FREE_AND_NULL (istate -> fsmonitor_last_update );
234+ istate -> fsmonitor_last_update = strbuf_detach (& last_update_token , NULL );
222235}
223236
224237void add_fsmonitor (struct index_state * istate )
225238{
226239 unsigned int i ;
240+ struct strbuf last_update = STRBUF_INIT ;
227241
228242 if (!istate -> fsmonitor_last_update ) {
229243 trace_printf_key (& trace_fsmonitor , "add fsmonitor" );
230244 istate -> cache_changed |= FSMONITOR_CHANGED ;
231- istate -> fsmonitor_last_update = getnanotime ();
245+ strbuf_addf (& last_update , "%" PRIu64 "" , getnanotime ());
246+ istate -> fsmonitor_last_update = strbuf_detach (& last_update , NULL );
232247
233248 /* reset the fsmonitor state */
234249 for (i = 0 ; i < istate -> cache_nr ; i ++ )
@@ -250,7 +265,7 @@ void remove_fsmonitor(struct index_state *istate)
250265 if (istate -> fsmonitor_last_update ) {
251266 trace_printf_key (& trace_fsmonitor , "remove fsmonitor" );
252267 istate -> cache_changed |= FSMONITOR_CHANGED ;
253- istate -> fsmonitor_last_update = 0 ;
268+ FREE_AND_NULL ( istate -> fsmonitor_last_update ) ;
254269 }
255270}
256271
0 commit comments