-
Notifications
You must be signed in to change notification settings - Fork 0
/
pigs-rm
executable file
·164 lines (141 loc) · 4.99 KB
/
pigs-rm
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#! /bin/dash
# check if the pigs repository is initialized
if ! test -d ".pig"; then
echo "pigs-rm: error: pigs repository directory .pig not found"
exit 1
fi
# check if the number of arguments is correct
if test $# -eq 0; then
echo "usage: pigs-rm [--force] [--cached] <filenames>"
exit 1
fi
force=0
cached=0
files=""
# parse the arguments
for arg in "$@"; do
case "$arg" in
"--force")
force=1
;;
"--cached")
cached=1
;;
"-")
echo "pigs-rm: error: invalid filename '$arg'"
exit 1
;;
-*)
echo "usage: pigs-rm [--force] [--cached] <filenames>"
exit 1
;;
"")
echo "usage: pigs-rm [--force] [--cached] <filenames>"
exit 1
;;
*)
files="$files $arg"
;;
esac
done
temp_log=$(mktemp)
index_temp=$(mktemp -d)
working_temp=$(mktemp -d)
trap 'rm "$temp_log"' INT HUP QUIT TERM EXIT
trap 'rm -rf "$index_temp" "$working_temp"' INT HUP QUIT TERM EXIT
current_branch=$(cat ".pig/active_branch")
branch_dir=".pig/branches/$current_branch"
index_dir="$branch_dir/index"
commit_history_dir="$branch_dir/commit_history"
commit_number=-1
# get the last commit number
if test -e ".pig/commit_total.log"; then
commit_number=$(head -n 1 ".pig/commit_total.log" | sed -E -- 's/^([0-9]+) .*$/\1/')
fi
# if test -e "$branch_dir/commit_msg.log"; then
# commit_number=$(head -n 1 "$branch_dir/commit_msg.log" | sed -E -- 's/^([0-9]+) .*$/\1/')
# fi
is_fail=0
for file in $files; do
# check if the name of the file is valid
if ! echo "$file" | grep -E -- '^[a-zA-Z0-9][a-zA-Z0-9.-_]*$' >/dev/null; then
echo "pigs-rm: error: invalid filename '$file'"
is_fail=1
break
fi
# check if the file is in the index
if ! test -e "$index_dir/$file"; then
echo "pigs-rm: error: '$file' is not in the pigs repository"
is_fail=1
break
fi
if test "$force" -eq 0; then
# check if the file is in the current directory
if ! test -e "$file"; then
cp "$index_dir/$file" "$index_temp/$file"
rm "$index_dir/$file"
echo "Removed $file from index" >>"$temp_log"
# exit 0
fi
# check if it is the first commit
if test "$commit_number" -eq -1; then
echo "pigs-rm: error: '$file' has staged changes in the index"
is_fail=1
break
fi
# Check if index is different to both the current directory and the repository
if ! diff "$file" "$index_dir/$file" >/dev/null &&
! diff "$index_dir/$file" "$commit_history_dir/commit_$commit_number/$file" >/dev/null; then
echo "pigs-rm: error: '$file' in index is different to both the working file and the repository"
is_fail=1
break
fi
# check if the file in the current directory is different from the one in the index
if ! diff "$file" "$index_dir/$file" >/dev/null &&
test "$cached" -eq 0; then
echo "pigs-rm: error: '$file' in the repository is different to the working file"
is_fail=1
break
fi
# check if the file has staged changes in the index
if test -e "$index_dir/$file"; then
# no --cached option is given
if test "$cached" -eq 0; then
# check if the file in the index exists in the last commit
if test -e "$commit_history_dir/commit_$commit_number/$file"; then
# check if the file in the index is different from the one in the last commit
if ! diff "$index_dir/$file" "$commit_history_dir/commit_$commit_number/$file" >/dev/null; then
echo "pigs-rm: error: '$file' has staged changes in the index"
is_fail=1
break
fi
else # if the file in the index does not exist in the last commit
echo "pigs-rm: error: '$file' has staged changes in the index"
is_fail=1
break
fi
fi
fi
fi
cp "$index_dir/$file" "$index_temp/$file"
rm "$index_dir/$file"
echo "Removed $file from index" >>"$temp_log"
if test "$cached" -eq 0 && test -e "$file"; then
cp "$file" "$working_temp/$file"
rm "$file"
echo "Removed $file from working directory" >>"$temp_log"
fi
done
# check if there is any error during the remove process
if test "$is_fail" -eq 1; then
while read -r line; do
filename=$(echo "$line" | sed -E -- 's/^Removed (.*) from .*$/\1/')
action=$(echo "$line" | sed -E -- 's/^Removed .* from (.*)$/\1/')
if test "$action" = "index"; then
# restore the file to the index
cp "$index_temp/$filename" "$index_dir/$filename"
elif test "$action" = "working directory"; then
cp "$working_temp/$filename" "$filename"
fi
done <"$temp_log"
fi