Skip to content

Commit 51a2a51

Browse files
authoredMay 18, 2022
Merge pull request #11 from ethomson/updates
Handle unreachable and dangling blobs, plus --help information
2 parents 75e9be5 + 605ed8a commit 51a2a51

File tree

1 file changed

+44
-5
lines changed

1 file changed

+44
-5
lines changed
 

‎git-recover

+44-5
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,41 @@ DO_INTERACTIVE=0
1919
BLOBS=()
2020
FILENAMES=()
2121

22+
function print_usage {
23+
echo "usage: $PROGNAME [-a] [-i] [--full] [<id> [-f <filename>] ...]"
24+
}
25+
26+
function show_help {
27+
print_usage
28+
29+
echo ""
30+
echo "Recover deleted files in your git repository"
31+
echo ""
32+
echo "Options:"
33+
echo " -a, --all Write all orphaned blobs to the current working"
34+
echo " directory. Each file will be named using its 40"
35+
echo " character object ID."
36+
echo " -i, --interactive Display information about each orphaned blob and then"
37+
echo " prompt to recover it."
38+
echo " --full List or recover all orphaned blobs, even those that"
39+
echo " are in packfiles. By default, git-recover will only"
40+
echo " look at loose object files, which limits it to the"
41+
echo " most recently created files. Examining packfiles may"
42+
echo " be slow, especially in large repositories."
43+
echo " <id> The object ID (or its abbreviation) to recover. The"
44+
echo " file will be written to the current working directory"
45+
echo " and named using its 40 character object ID, unless the"
46+
echo " -f option is specified."
47+
echo " -f, --filename name When specified after an object ID, the file written"
48+
echo " will use this filename. In addition, any filters"
49+
echo " (for example: CRLF conversion or Git-LFS) will be run"
50+
echo " according to the gitattributes configuration."
51+
52+
exit 0
53+
}
54+
2255
function die_usage {
23-
echo "usage: $PROGNAME [-a] [-i] [--full] [<id> [-f <filename>] ...]" >&2
56+
print_usage >&2
2457
exit 1
2558
}
2659

@@ -35,6 +68,9 @@ while [[ $# -gt 0 ]]; do
3568
--full)
3669
DO_FULL=1
3770
;;
71+
-h|--help)
72+
show_help
73+
;;
3874
*)
3975
if [ "${1:0:1}" == "-" ]; then
4076
echo "$PROGNAME: unknown argument: $1" >&2
@@ -96,8 +132,10 @@ function find_unreachable() {
96132

97133
if [ $DO_FULL == 1 ]; then FULLNESS="--full"; fi
98134

99-
BLOBS=($(git fsck --unreachable --no-reflogs \
100-
"${FULLNESS}" --no-progress | sed -ne 's/^unreachable blob //p'))
135+
# shellcheck disable=SC2207
136+
BLOBS=($(git fsck --unreachable --no-reflogs "${FULLNESS}" \
137+
--no-progress 2>/dev/null | \
138+
sed -E -ne 's/^unreachable blob |dangling blob //p'))
101139
}
102140

103141
function read_one_file {
@@ -171,6 +209,7 @@ function timestamp_to_s {
171209

172210
function sort_by_timestamp {
173211
# sort blobs in loose objects by their timestamp (packed blobs last)
212+
# shellcheck disable=SC2207
174213
BLOB_AND_TIMESTAMPS=($(for BLOB in "${BLOBS[@]}"; do
175214
LOOSE="${BLOB::2}/${BLOB:2}"
176215
TIME=$(file_time "$GIT_DIR/objects/$LOOSE" 2>/dev/null || true)
@@ -186,7 +225,7 @@ function print_recoverable {
186225
for BLOB_AND_TIMESTAMP in "${BLOB_AND_TIMESTAMPS[@]}"; do
187226
BLOB=${BLOB_AND_TIMESTAMP::40}
188227
TIME=${BLOB_AND_TIMESTAMP:41}
189-
DATE=$([ ! -z "$TIME" ] && timestamp_to_s "$TIME" || echo "(Unknown)")
228+
DATE=$([ -n "$TIME" ] && timestamp_to_s "$TIME" || echo "(Unknown)")
190229

191230
echo "$BLOB $DATE"
192231
done
@@ -239,7 +278,7 @@ function interactive {
239278

240279
BLOB=${BLOB_AND_TIMESTAMP::40}
241280
TIME=${BLOB_AND_TIMESTAMP:41}
242-
DATE=$([ ! -z "$TIME" ] && timestamp_to_s "$TIME" || echo "(Unknown)")
281+
DATE=$([ -n "$TIME" ] && timestamp_to_s "$TIME" || echo "(Unknown)")
243282

244283
echo "$BLOB ($DATE)"
245284
show_summary "${BLOB}" | head -4 | sed -e 's/^/> /'

0 commit comments

Comments
 (0)
Please sign in to comment.