Skip to content

Commit 68f6c01

Browse files
dschogitster
authored andcommitted
git-fsck: add --lost-found option
With this option, dangling objects are not only reported, but also written to .git/lost-found/commit/ or .git/lost-found/other/. This option implies '--full' and '--no-reflogs'. 'git fsck --lost-found' is meant as a replacement for git-lost-found. Signed-off-by: Johannes Schindelin <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 1a6f399 commit 68f6c01

File tree

3 files changed

+62
-1
lines changed

3 files changed

+62
-1
lines changed

Documentation/git-fsck.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ SYNOPSIS
1010
--------
1111
[verse]
1212
'git-fsck' [--tags] [--root] [--unreachable] [--cache] [--no-reflogs]
13-
[--full] [--strict] [--verbose] [<object>*]
13+
[--full] [--strict] [--verbose] [--lost-found] [<object>*]
1414

1515
DESCRIPTION
1616
-----------
@@ -64,6 +64,10 @@ index file and all SHA1 references in .git/refs/* as heads.
6464
--verbose::
6565
Be chatty.
6666

67+
--lost-found::
68+
Write dangling refs into .git/commit/ or .git/other/, depending
69+
on type.
70+
6771
It tests SHA1 and general object sanity, and it does full tracking of
6872
the resulting reachability and everything else. It prints out any
6973
corruption it finds (missing or bad objects), and if you use the

builtin-fsck.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ static int check_strict;
2020
static int keep_cache_objects;
2121
static unsigned char head_sha1[20];
2222
static int errors_found;
23+
static int write_lost_and_found;
2324
static int verbose;
2425
#define ERROR_OBJECT 01
2526
#define ERROR_REACHABLE 02
@@ -138,6 +139,21 @@ static void check_unreachable_object(struct object *obj)
138139
if (!obj->used) {
139140
printf("dangling %s %s\n", typename(obj->type),
140141
sha1_to_hex(obj->sha1));
142+
if (write_lost_and_found) {
143+
char *filename = git_path("lost-found/%s/%s",
144+
obj->type == OBJ_COMMIT ? "commit" : "other",
145+
sha1_to_hex(obj->sha1));
146+
FILE *f;
147+
148+
if (safe_create_leading_directories(filename)) {
149+
error("Could not create lost-found");
150+
return;
151+
}
152+
if (!(f = fopen(filename, "w")))
153+
die("Could not open %s", filename);
154+
fprintf(f, "%s\n", sha1_to_hex(obj->sha1));
155+
fclose(f);
156+
}
141157
return;
142158
}
143159

@@ -685,6 +701,12 @@ int cmd_fsck(int argc, char **argv, const char *prefix)
685701
verbose = 1;
686702
continue;
687703
}
704+
if (!strcmp(arg, "--lost-found")) {
705+
check_full = 1;
706+
include_reflogs = 0;
707+
write_lost_and_found = 1;
708+
continue;
709+
}
688710
if (*arg == '-')
689711
usage(fsck_usage);
690712
}

t/t1420-lost-found.sh

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#!/bin/sh
2+
#
3+
# Copyright (c) 2007 Johannes E. Schindelin
4+
#
5+
6+
test_description='Test fsck --lost-found'
7+
. ./test-lib.sh
8+
9+
test_expect_success setup '
10+
git config core.logAllRefUpdates 0 &&
11+
: > file1 &&
12+
git add file1 &&
13+
test_tick &&
14+
git commit -m initial &&
15+
echo 1 > file1 &&
16+
echo 2 > file2 &&
17+
git add file1 file2 &&
18+
test_tick &&
19+
git commit -m second &&
20+
echo 3 > file3 &&
21+
git add file3
22+
'
23+
24+
test_expect_success 'lost and found something' '
25+
git rev-parse HEAD > lost-commit &&
26+
git rev-parse :file3 > lost-other &&
27+
test_tick &&
28+
git reset --hard HEAD^ &&
29+
git fsck --lost-found &&
30+
test 2 = $(ls .git/lost-found/*/* | wc -l) &&
31+
test -f .git/lost-found/commit/$(cat lost-commit) &&
32+
test -f .git/lost-found/other/$(cat lost-other)
33+
'
34+
35+
test_done

0 commit comments

Comments
 (0)