statinfo: move stat_{data,validity} functions from cache/read-cache
These functions do not depend upon struct cache_entry or struct index_state in any way, and it seems more logical to break them out into this file, especially since statinfo.h already has the struct stat_data declaration. Diff best viewed with `--color-moved`. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Elijah Newren committed
May 16, 2023 at 06:33 UTC
90cbae9ce5d22df29867be9026c514b8c79e3d31
8 files changed
+142
-132
Makefile
+1
@@ -1142,6 +1142,7 @@ LIB_OBJS += sigchain.o
1142
LIB_OBJS += sparse-index.o
1143
LIB_OBJS += split-index.o
1144
LIB_OBJS += stable-qsort.o
1145
+LIB_OBJS += statinfo.o
1146
LIB_OBJS += strbuf.o
1147
LIB_OBJS += streaming.o
1148
LIB_OBJS += string-list.o
cache.h
-48
@@ -488,19 +488,6 @@ int has_racy_timestamp(struct index_state *istate);
488
int ie_match_stat(struct index_state *, const struct cache_entry *, struct stat *, unsigned int);
489
int ie_modified(struct index_state *, const struct cache_entry *, struct stat *, unsigned int);
490
491
-/*
492
- * Record to sd the data from st that we use to check whether a file
493
- * might have changed.
494
- */
495
-void fill_stat_data(struct stat_data *sd, struct stat *st);
496
-
497
-/*
498
- * Return 0 if st is consistent with a file not having been changed
499
- * since sd was filled. If there are differences, return a
500
- * combination of MTIME_CHANGED, CTIME_CHANGED, OWNER_CHANGED,
501
- * INODE_CHANGED, and DATA_CHANGED.
502
- */
503
-int match_stat_data(const struct stat_data *sd, struct stat *st);
491
int match_stat_data_racy(const struct index_state *istate,
492
const struct stat_data *sd, struct stat *st);
493
@@ -539,14 +526,6 @@ void set_alternate_index_output(const char *);
526
extern int verify_index_checksum;
527
extern int verify_ce_order;
528
542
-#define MTIME_CHANGED 0x0001
543
-#define CTIME_CHANGED 0x0002
544
-#define OWNER_CHANGED 0x0004
545
-#define MODE_CHANGED 0x0008
546
-#define INODE_CHANGED 0x0010
547
-#define DATA_CHANGED 0x0020
548
-#define TYPE_CHANGED 0x0040
549
-
529
int cmp_cache_name_compare(const void *a_, const void *b_);
530
531
/* add */
@@ -579,31 +558,4 @@ int checkout_fast_forward(struct repository *r,
558
559
int sane_execvp(const char *file, char *const argv[]);
560
582
-/*
583
- * A struct to encapsulate the concept of whether a file has changed
584
- * since we last checked it. This uses criteria similar to those used
585
- * for the index.
586
- */
587
-struct stat_validity {
588
- struct stat_data *sd;
589
-};
590
-
591
-void stat_validity_clear(struct stat_validity *sv);
592
-
593
-/*
594
- * Returns 1 if the path is a regular file (or a symlink to a regular
595
- * file) and matches the saved stat_validity, 0 otherwise. A missing
596
- * or inaccessible file is considered a match if the struct was just
597
- * initialized, or if the previous update found an inaccessible file.
598
- */
599
-int stat_validity_check(struct stat_validity *sv, const char *path);
600
-
601
-/*
602
- * Update the stat_validity from a file opened at descriptor fd. If
603
- * the file is missing, inaccessible, or not a regular file, then
604
- * future calls to stat_validity_check will match iff one of those
605
- * conditions continues to be true.
606
- */
607
-void stat_validity_update(struct stat_validity *sv, int fd);
608
-
561
#endif /* CACHE_H */
object.c
+1
@@ -6,6 +6,7 @@
6
#include "object-file.h"
7
#include "object-store.h"
8
#include "blob.h"
9
+#include "statinfo.h"
10
#include "tree.h"
11
#include "commit.h"
12
#include "tag.h"
read-cache.c
-84
@@ -177,61 +177,6 @@ void rename_index_entry_at(struct index_state *istate, int nr, const char *new_n
177
add_index_entry(istate, new_entry, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE);
178
}
179
180
-void fill_stat_data(struct stat_data *sd, struct stat *st)
181
-{
182
- sd->sd_ctime.sec = (unsigned int)st->st_ctime;
183
- sd->sd_mtime.sec = (unsigned int)st->st_mtime;
184
- sd->sd_ctime.nsec = ST_CTIME_NSEC(*st);
185
- sd->sd_mtime.nsec = ST_MTIME_NSEC(*st);
186
- sd->sd_dev = st->st_dev;
187
- sd->sd_ino = st->st_ino;
188
- sd->sd_uid = st->st_uid;
189
- sd->sd_gid = st->st_gid;
190
- sd->sd_size = st->st_size;
191
-}
192
-
193
-int match_stat_data(const struct stat_data *sd, struct stat *st)
194
-{
195
- int changed = 0;
196
-
197
- if (sd->sd_mtime.sec != (unsigned int)st->st_mtime)
198
- changed |= MTIME_CHANGED;
199
- if (trust_ctime && check_stat &&
200
- sd->sd_ctime.sec != (unsigned int)st->st_ctime)
201
- changed |= CTIME_CHANGED;
202
-
203
-#ifdef USE_NSEC
204
- if (check_stat && sd->sd_mtime.nsec != ST_MTIME_NSEC(*st))
205
- changed |= MTIME_CHANGED;
206
- if (trust_ctime && check_stat &&
207
- sd->sd_ctime.nsec != ST_CTIME_NSEC(*st))
208
- changed |= CTIME_CHANGED;
209
-#endif
210
-
211
- if (check_stat) {
212
- if (sd->sd_uid != (unsigned int) st->st_uid ||
213
- sd->sd_gid != (unsigned int) st->st_gid)
214
- changed |= OWNER_CHANGED;
215
- if (sd->sd_ino != (unsigned int) st->st_ino)
216
- changed |= INODE_CHANGED;
217
- }
218
-
219
-#ifdef USE_STDEV
220
- /*
221
- * st_dev breaks on network filesystems where different
222
- * clients will have different views of what "device"
223
- * the filesystem is on
224
- */
225
- if (check_stat && sd->sd_dev != (unsigned int) st->st_dev)
226
- changed |= INODE_CHANGED;
227
-#endif
228
-
229
- if (sd->sd_size != (unsigned int) st->st_size)
230
- changed |= DATA_CHANGED;
231
-
232
- return changed;
233
-}
234
-
180
/*
181
* This only updates the "non-critical" parts of the directory
182
* cache, ie the parts that aren't tracked by GIT, and only used
@@ -3536,35 +3481,6 @@ void *read_blob_data_from_index(struct index_state *istate,
3481
return data;
3482
}
3483
3539
-void stat_validity_clear(struct stat_validity *sv)
3540
-{
3541
- FREE_AND_NULL(sv->sd);
3542
-}
3543
-
3544
-int stat_validity_check(struct stat_validity *sv, const char *path)
3545
-{
3546
- struct stat st;
3547
-
3548
- if (stat(path, &st) < 0)
3549
- return sv->sd == NULL;
3550
- if (!sv->sd)
3551
- return 0;
3552
- return S_ISREG(st.st_mode) && !match_stat_data(sv->sd, &st);
3553
-}
3554
-
3555
-void stat_validity_update(struct stat_validity *sv, int fd)
3556
-{
3557
- struct stat st;
3558
-
3559
- if (fstat(fd, &st) < 0 || !S_ISREG(st.st_mode))
3560
- stat_validity_clear(sv);
3561
- else {
3562
- if (!sv->sd)
3563
- CALLOC_ARRAY(sv->sd, 1);
3564
- fill_stat_data(sv->sd, &st);
3565
- }
3566
-}
3567
-
3484
void move_index_extensions(struct index_state *dst, struct index_state *src)
3485
{
3486
dst->untracked = src->untracked;
refs/packed-backend.c
+1
@@ -10,6 +10,7 @@
10
#include "../iterator.h"
11
#include "../lockfile.h"
12
#include "../chdir-notify.h"
13
+#include "../statinfo.h"
14
#include "../wrapper.h"
15
#include "../write-or-die.h"
16
shallow.c
+1
@@ -17,6 +17,7 @@
17
#include "list-objects.h"
18
#include "commit-reach.h"
19
#include "shallow.h"
20
+#include "statinfo.h"
21
#include "trace.h"
22
#include "wrapper.h"
23
statinfo.c
new
+87
@@ -0,0 +1,87 @@
1
+#include "git-compat-util.h"
2
+#include "environment.h"
3
+#include "statinfo.h"
4
+
5
+void fill_stat_data(struct stat_data *sd, struct stat *st)
6
+{
7
+ sd->sd_ctime.sec = (unsigned int)st->st_ctime;
8
+ sd->sd_mtime.sec = (unsigned int)st->st_mtime;
9
+ sd->sd_ctime.nsec = ST_CTIME_NSEC(*st);
10
+ sd->sd_mtime.nsec = ST_MTIME_NSEC(*st);
11
+ sd->sd_dev = st->st_dev;
12
+ sd->sd_ino = st->st_ino;
13
+ sd->sd_uid = st->st_uid;
14
+ sd->sd_gid = st->st_gid;
15
+ sd->sd_size = st->st_size;
16
+}
17
+
18
+int match_stat_data(const struct stat_data *sd, struct stat *st)
19
+{
20
+ int changed = 0;
21
+
22
+ if (sd->sd_mtime.sec != (unsigned int)st->st_mtime)
23
+ changed |= MTIME_CHANGED;
24
+ if (trust_ctime && check_stat &&
25
+ sd->sd_ctime.sec != (unsigned int)st->st_ctime)
26
+ changed |= CTIME_CHANGED;
27
+
28
+#ifdef USE_NSEC
29
+ if (check_stat && sd->sd_mtime.nsec != ST_MTIME_NSEC(*st))
30
+ changed |= MTIME_CHANGED;
31
+ if (trust_ctime && check_stat &&
32
+ sd->sd_ctime.nsec != ST_CTIME_NSEC(*st))
33
+ changed |= CTIME_CHANGED;
34
+#endif
35
+
36
+ if (check_stat) {
37
+ if (sd->sd_uid != (unsigned int) st->st_uid ||
38
+ sd->sd_gid != (unsigned int) st->st_gid)
39
+ changed |= OWNER_CHANGED;
40
+ if (sd->sd_ino != (unsigned int) st->st_ino)
41
+ changed |= INODE_CHANGED;
42
+ }
43
+
44
+#ifdef USE_STDEV
45
+ /*
46
+ * st_dev breaks on network filesystems where different
47
+ * clients will have different views of what "device"
48
+ * the filesystem is on
49
+ */
50
+ if (check_stat && sd->sd_dev != (unsigned int) st->st_dev)
51
+ changed |= INODE_CHANGED;
52
+#endif
53
+
54
+ if (sd->sd_size != (unsigned int) st->st_size)
55
+ changed |= DATA_CHANGED;
56
+
57
+ return changed;
58
+}
59
+
60
+void stat_validity_clear(struct stat_validity *sv)
61
+{
62
+ FREE_AND_NULL(sv->sd);
63
+}
64
+
65
+int stat_validity_check(struct stat_validity *sv, const char *path)
66
+{
67
+ struct stat st;
68
+
69
+ if (stat(path, &st) < 0)
70
+ return sv->sd == NULL;
71
+ if (!sv->sd)
72
+ return 0;
73
+ return S_ISREG(st.st_mode) && !match_stat_data(sv->sd, &st);
74
+}
75
+
76
+void stat_validity_update(struct stat_validity *sv, int fd)
77
+{
78
+ struct stat st;
79
+
80
+ if (fstat(fd, &st) < 0 || !S_ISREG(st.st_mode))
81
+ stat_validity_clear(sv);
82
+ else {
83
+ if (!sv->sd)
84
+ CALLOC_ARRAY(sv->sd, 1);
85
+ fill_stat_data(sv->sd, &st);
86
+ }
87
+}
statinfo.h
+51
@@ -1,6 +1,8 @@
1
#ifndef STATINFO_H
2
#define STATINFO_H
3
4
+struct index_state;
5
+
6
/*
7
* The "cache_time" is just the low 32 bits of the
8
* time. It doesn't matter if it overflows - we only
@@ -21,4 +23,53 @@ struct stat_data {
23
unsigned int sd_size;
24
};
25
26
+/*
27
+ * A struct to encapsulate the concept of whether a file has changed
28
+ * since we last checked it. This uses criteria similar to those used
29
+ * for the index.
30
+ */
31
+struct stat_validity {
32
+ struct stat_data *sd;
33
+};
34
+
35
+#define MTIME_CHANGED 0x0001
36
+#define CTIME_CHANGED 0x0002
37
+#define OWNER_CHANGED 0x0004
38
+#define MODE_CHANGED 0x0008
39
+#define INODE_CHANGED 0x0010
40
+#define DATA_CHANGED 0x0020
41
+#define TYPE_CHANGED 0x0040
42
+
43
+/*
44
+ * Record to sd the data from st that we use to check whether a file
45
+ * might have changed.
46
+ */
47
+void fill_stat_data(struct stat_data *sd, struct stat *st);
48
+
49
+/*
50
+ * Return 0 if st is consistent with a file not having been changed
51
+ * since sd was filled. If there are differences, return a
52
+ * combination of MTIME_CHANGED, CTIME_CHANGED, OWNER_CHANGED,
53
+ * INODE_CHANGED, and DATA_CHANGED.
54
+ */
55
+int match_stat_data(const struct stat_data *sd, struct stat *st);
56
+
57
+void stat_validity_clear(struct stat_validity *sv);
58
+
59
+/*
60
+ * Returns 1 if the path is a regular file (or a symlink to a regular
61
+ * file) and matches the saved stat_validity, 0 otherwise. A missing
62
+ * or inaccessible file is considered a match if the struct was just
63
+ * initialized, or if the previous update found an inaccessible file.
64
+ */
65
+int stat_validity_check(struct stat_validity *sv, const char *path);
66
+
67
+/*
68
+ * Update the stat_validity from a file opened at descriptor fd. If
69
+ * the file is missing, inaccessible, or not a regular file, then
70
+ * future calls to stat_validity_check will match iff one of those
71
+ * conditions continues to be true.
72
+ */
73
+void stat_validity_update(struct stat_validity *sv, int fd);
74
+
75
#endif