-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathls-files
executable file
·71 lines (61 loc) · 1.42 KB
/
ls-files
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#!/bin/sh -eu
SHIT_PATH=$(dirname "$0")
. $SHIT_PATH/common.sh
index="$GIT_DIR"/index
magic=$(od -An -tc -N4 "$index" | tr -d ' ')
version=$(read_int32 "$index" 4)
nentries=$(read_int32 "$index" 8)
if [ "$magic" != "DIRC" ]
then
printf "Invalid git index format\n" >&2
exit
fi
if [ $version -ne 2 ]
then
printf "Only git index version %d is supported, %d was found\n" \
"$INDEX_VERSION" "$version" >&2
exit 1
fi
offs=12
while [ $nentries -gt 0 ]
do
# mode @ 24 bytes
# sha @ 40 bytes
# flags @ 60 bytes
# name @ 62 bytes
mode=$(read_int32 "$index" $((offs+24)))
sha=$(read_hex "$index" $((offs+40)) 20)
flags=$(read_int16 "$index" $((offs+60)))
# 0bNNNNxxxMMMMMMMMM
# NNNN -> object type
# MMMMMMMMM -> unix file mode (644 or 755)
case $(printf "%X" $((mode & 0xF000))) in
8000)
objtype=file
;;
A000)
objtype=link
;;
E000)
objtype=gitlink
;;
*)
printf "Invalid object type %x\n" $(((mode & 0xF000) >> 12)) >&2
exit 1
;;
esac
unixmode=$((mode & 0x1FF))
if [ $unixmode -ne $((0644)) ] && [ $unixmode -ne $((0755)) ] && [ $unixmode -ne 0 ]
then
printf "Invalid file mode %o\n" $unixmode >&2
exit 1
fi
pathlen=$((flags & 0xFFF))
path="$(read_text "$index" $((offs+62)) $pathlen)"
printf "%o %s %s\n" "$mode" "$sha" "$path"
padding=$((${#path} + 1 + 62))
padding=$((padding % 8))
padding=$(((8 - padding) % 8))
offs=$((offs+62+${#path}+1+padding))
nentries=$((nentries-1))
done