summaryrefslogtreecommitdiff
path: root/fsck.c
diff options
context:
space:
mode:
authorJohannes Schindelin <johannes.schindelin@gmx.de>2015-06-22 15:27:18 (GMT)
committerJunio C Hamano <gitster@pobox.com>2015-06-23 21:27:37 (GMT)
commitcd94c6f91ee92ffb0592696170fa84f426b839ab (patch)
tree1e437d580bb4b5087d248d69149350ebf14ed94b /fsck.c
parent02976bf856bc47ea2bcb9423cd13b6f69ce58929 (diff)
downloadgit-cd94c6f91ee92ffb0592696170fa84f426b839ab.zip
git-cd94c6f91ee92ffb0592696170fa84f426b839ab.tar.gz
git-cd94c6f91ee92ffb0592696170fa84f426b839ab.tar.bz2
fsck: git receive-pack: support excluding objects from fsck'ing
The optional new config option `receive.fsck.skipList` specifies the path to a file listing the names, i.e. SHA-1s, one per line, of objects that are to be ignored by `git receive-pack` when `receive.fsckObjects = true`. This is extremely handy in case of legacy repositories where it would cause more pain to change incorrect objects than to live with them (e.g. a duplicate 'author' line in an early commit object). The intended use case is for server administrators to inspect objects that are reported by `git push` as being too problematic to enter the repository, and to add the objects' SHA-1 to a (preferably sorted) file when the objects are legitimate, i.e. when it is determined that those problematic objects should be allowed to enter the server. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'fsck.c')
-rw-r--r--fsck.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/fsck.c b/fsck.c
index 7a614bb..1523243 100644
--- a/fsck.c
+++ b/fsck.c
@@ -8,6 +8,7 @@
#include "fsck.h"
#include "refs.h"
#include "utf8.h"
+#include "sha1-array.h"
#define FSCK_FATAL -1
#define FSCK_INFO -2
@@ -127,6 +128,43 @@ static int fsck_msg_type(enum fsck_msg_id msg_id,
return msg_type;
}
+static void init_skiplist(struct fsck_options *options, const char *path)
+{
+ static struct sha1_array skiplist = SHA1_ARRAY_INIT;
+ int sorted, fd;
+ char buffer[41];
+ unsigned char sha1[20];
+
+ if (options->skiplist)
+ sorted = options->skiplist->sorted;
+ else {
+ sorted = 1;
+ options->skiplist = &skiplist;
+ }
+
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
+ die("Could not open skip list: %s", path);
+ for (;;) {
+ int result = read_in_full(fd, buffer, sizeof(buffer));
+ if (result < 0)
+ die_errno("Could not read '%s'", path);
+ if (!result)
+ break;
+ if (get_sha1_hex(buffer, sha1) || buffer[40] != '\n')
+ die("Invalid SHA-1: %s", buffer);
+ sha1_array_append(&skiplist, sha1);
+ if (sorted && skiplist.nr > 1 &&
+ hashcmp(skiplist.sha1[skiplist.nr - 2],
+ sha1) > 0)
+ sorted = 0;
+ }
+ close(fd);
+
+ if (sorted)
+ skiplist.sorted = 1;
+}
+
static int parse_msg_type(const char *str)
{
if (!strcmp(str, "error"))
@@ -191,6 +229,14 @@ void fsck_set_msg_types(struct fsck_options *options, const char *values)
buf[equal] = tolower(buf[equal]);
buf[equal] = '\0';
+ if (!strcmp(buf, "skiplist")) {
+ if (equal == len)
+ die("skiplist requires a path");
+ init_skiplist(options, buf + equal + 1);
+ buf += len + 1;
+ continue;
+ }
+
if (equal == len)
die("Missing '=': '%s'", buf);
@@ -229,6 +275,10 @@ static int report(struct fsck_options *options, struct object *object,
if (msg_type == FSCK_IGNORE)
return 0;
+ if (options->skiplist && object &&
+ sha1_array_lookup(options->skiplist, object->sha1) >= 0)
+ return 0;
+
if (msg_type == FSCK_FATAL)
msg_type = FSCK_ERROR;
else if (msg_type == FSCK_INFO)