dir.c: optionally compute sha-1 of a .gitignore file
This is not used anywhere yet. But the goal is to compare quickly if a .gitignore file has changed when we have the SHA-1 of both old (cached somewhere) and new (from index or a tree) versions. Helped-by: Junio C Hamano <gitster@pobox.com> Helped-by: Torsten Bögershausen <tboegi@web.de> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Nguyễn Thái Ngọc Duy committed
Mar 8, 2015 at 17:12 UTC
55fe6f51f41f254d3d87994d18bff04664aa013b
2 files changed
+53
-7
dir.c
+47
-7
@@ -466,7 +466,8 @@ void add_exclude(const char *string, const char *base,
466
x->el = el;
467
}
468
469
-static void *read_skip_worktree_file_from_index(const char *path, size_t *size)
469
+static void *read_skip_worktree_file_from_index(const char *path, size_t *size,
470
+ struct sha1_stat *sha1_stat)
471
{
472
int pos, len;
473
unsigned long sz;
@@ -485,6 +486,10 @@ static void *read_skip_worktree_file_from_index(const char *path, size_t *size)
486
return NULL;
487
}
488
*size = xsize_t(sz);
489
+ if (sha1_stat) {
490
+ memset(&sha1_stat->stat, 0, sizeof(sha1_stat->stat));
491
+ hashcpy(sha1_stat->sha1, active_cache[pos]->sha1);
492
+ }
493
return data;
494
}
495
@@ -529,11 +534,18 @@ static void trim_trailing_spaces(char *buf)
534
*last_space = '\0';
535
}
536
532
-int add_excludes_from_file_to_list(const char *fname,
533
- const char *base,
534
- int baselen,
535
- struct exclude_list *el,
536
- int check_index)
537
+/*
538
+ * Given a file with name "fname", read it (either from disk, or from
539
+ * the index if "check_index" is non-zero), parse it and store the
540
+ * exclude rules in "el".
541
+ *
542
+ * If "ss" is not NULL, compute SHA-1 of the exclude file and fill
543
+ * stat data from disk (only valid if add_excludes returns zero). If
544
+ * ss_valid is non-zero, "ss" must contain good value as input.
545
+ */
546
+static int add_excludes(const char *fname, const char *base, int baselen,
547
+ struct exclude_list *el, int check_index,
548
+ struct sha1_stat *sha1_stat)
549
{
550
struct stat st;
551
int fd, i, lineno = 1;
@@ -547,7 +559,7 @@ int add_excludes_from_file_to_list(const char *fname,
559
if (0 <= fd)
560
close(fd);
561
if (!check_index ||
550
- (buf = read_skip_worktree_file_from_index(fname, &size)) == NULL)
562
+ (buf = read_skip_worktree_file_from_index(fname, &size, sha1_stat)) == NULL)
563
return -1;
564
if (size == 0) {
565
free(buf);
@@ -560,6 +572,11 @@ int add_excludes_from_file_to_list(const char *fname,
572
} else {
573
size = xsize_t(st.st_size);
574
if (size == 0) {
575
+ if (sha1_stat) {
576
+ fill_stat_data(&sha1_stat->stat, &st);
577
+ hashcpy(sha1_stat->sha1, EMPTY_BLOB_SHA1_BIN);
578
+ sha1_stat->valid = 1;
579
+ }
580
close(fd);
581
return 0;
582
}
@@ -571,6 +588,22 @@ int add_excludes_from_file_to_list(const char *fname,
588
}
589
buf[size++] = '\n';
590
close(fd);
591
+ if (sha1_stat) {
592
+ int pos;
593
+ if (sha1_stat->valid &&
594
+ !match_stat_data(&sha1_stat->stat, &st))
595
+ ; /* no content change, ss->sha1 still good */
596
+ else if (check_index &&
597
+ (pos = cache_name_pos(fname, strlen(fname))) >= 0 &&
598
+ !ce_stage(active_cache[pos]) &&
599
+ ce_uptodate(active_cache[pos]) &&
600
+ !would_convert_to_git(fname))
601
+ hashcpy(sha1_stat->sha1, active_cache[pos]->sha1);
602
+ else
603
+ hash_sha1_file(buf, size, "blob", sha1_stat->sha1);
604
+ fill_stat_data(&sha1_stat->stat, &st);
605
+ sha1_stat->valid = 1;
606
+ }
607
}
608
609
el->filebuf = buf;
@@ -589,6 +622,13 @@ int add_excludes_from_file_to_list(const char *fname,
622
return 0;
623
}
624
625
+int add_excludes_from_file_to_list(const char *fname, const char *base,
626
+ int baselen, struct exclude_list *el,
627
+ int check_index)
628
+{
629
+ return add_excludes(fname, base, baselen, el, check_index, NULL);
630
+}
631
+
632
struct exclude_list *add_exclude_list(struct dir_struct *dir,
633
int group_type, const char *src)
634
{
dir.h
+6
@@ -73,6 +73,12 @@ struct exclude_list_group {
73
struct exclude_list *el;
74
};
75
76
+struct sha1_stat {
77
+ struct stat_data stat;
78
+ unsigned char sha1[20];
79
+ int valid;
80
+};
81
+
82
struct dir_struct {
83
int nr, alloc;
84
int ignored_nr, ignored_alloc;