blob: e3ad4e087dfd540544eba1fb094e010e4046601b [file] [log] [blame]
Giorgi Lekveishvili285ab622023-11-22 13:50:45 +04001#!/bin/ash
2# Copyright (C) 2011, 2020 SAP SE
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16usage()
17{
18 echo "Usage: $0 [ -s ProjectName ] [ -p ProjectName ] [ -b ProjectName ]"
19 echo "-s ProjectName : skip this project"
20 echo "-p ProjectName : run git-gc for this project"
21 echo "-b ProjectName : do not write bitmaps for this project"
22 echo ""
23 echo "By default the script will run git-gc for all projects unless \"-p\" option is provided"
24 echo
25 echo "Examples:"
26 echo " Run git-gc for all projects but skip foo and bar/baz projects"
27 echo " $0 -s foo -s bar/baz"
28 echo " Run git-gc only for foo and bar/baz projects"
29 echo " $0 -p foo -p bar/baz"
30 echo " Run git-gc only for bar project without writing bitmaps"
31 echo " $0 -p bar -b bar"
32 echo
33 echo "To specify a one-time --aggressive git gc for a repository X, simply"
34 echo "create an empty file called \'gc-aggressive-once\' in the \$SITE/git/X.git"
35 echo "folder:"
36 echo
37 echo " \$ cd \$SITE/git/X.git"
38 echo " \$ touch gc-aggressive-once"
39 echo
40 echo "On the next run, gc.sh will use --aggressive option for gc-ing this"
41 echo "repository *and* will remove this file. Next time, gc.sh again runs"
42 echo "normal gc for this repository."
43 echo
44 echo "To specify a permanent --aggressive git gc for a repository, create"
45 echo "an empty file named "gc-aggresssive" in the same folder:"
46 echo
47 echo " \$ cd \$SITE/git/X.git"
48 echo " \$ touch gc-aggressive"
49 echo
50 echo "Every next git gc on this repository will use --aggressive option."
51 exit 2
52}
53
54gc_options()
55{
56 if test -f "$1/gc-aggressive" ; then
57 echo "--aggressive"
58 elif test -f "$1/gc-aggressive-once" ; then
59 echo "--aggressive"
60 rm -f "$1/gc-aggressive-once"
61 else
62 echo ""
63 fi
64}
65
66log_opts()
67{
68 if test -z $1 ; then
69 echo ""
70 else
71 echo " [$1]"
72 fi
73}
74
75log()
76{
77 # Rotate the $LOG if current date is different from the last modification of $LOG
78 if test -f "$LOG" ; then
79 TODAY=$(date +%Y-%m-%d)
80 LOG_LAST_MODIFIED=$(date +%Y-%m-%d -r $LOG)
81 if test "$TODAY" != "$LOG_LAST_MODIFIED" ; then
82 mv "$LOG" "$LOG.$LOG_LAST_MODIFIED"
83 gzip "$LOG.$LOG_LAST_MODIFIED"
84 fi
85 fi
86
87 # Do not log an empty line
88 if [[ ! "$1" =~ ^[[:space:]]*$ ]]; then
89 echo $1
90 echo $1 >>$LOG
91 fi
92}
93
94gc_all_projects()
95{
96 find $TOP -type d -path "*.git" -prune -o -name "*.git" | while IFS= read d
97 do
98 gc_project "${d#$TOP/}"
99 done
100}
101
102gc_specified_projects()
103{
104 for PROJECT_NAME in ${GC_PROJECTS}
105 do
106 gc_project "$PROJECT_NAME"
107 done
108}
109
110gc_project()
111{
112 PROJECT_NAME="$@"
113 PROJECT_DIR="$TOP/$PROJECT_NAME"
114
115 if [[ ! -d "$PROJECT_DIR" ]]; then
116 OUT=$(date +"%D %r Failed: Directory does not exist: $PROJECT_DIR") && log "$OUT"
117 return 1
118 fi
119
120 OPTS=$(gc_options "$PROJECT_DIR")
121 LOG_OPTS=$(log_opts $OPTS)
122
123 # Check if git-gc for this project has to be skipped
124 if [ $SKIP_PROJECTS_OPT -eq 1 ]; then
125 for SKIP_PROJECT in "${SKIP_PROJECTS}"; do
126 if [ "$SKIP_PROJECT" == "$PROJECT_NAME" ] ; then
127 OUT=$(date +"%D %r Skipped: $PROJECT_NAME") && log "$OUT"
128 return 0
129 fi
130 done
131 fi
132
133 # Check if writing bitmaps for this project has to be disabled
134 WRITEBITMAPS='true';
135 if [ $DONOT_WRITE_BITMAPS_OPT -eq 1 ]; then
136 for BITMAP_PROJECT in "${DONOT_WRITE_BITMAPS}"; do
137 if [ "$BITMAP_PROJECT" == "$PROJECT_NAME" ] ; then
138 WRITEBITMAPS='false';
139 fi
140 done
141 fi
142
143 OUT=$(date +"%D %r Started: $PROJECT_NAME$LOG_OPTS") && log "$OUT"
144
145 git --git-dir="$PROJECT_DIR" config core.logallrefupdates true
146
147 git --git-dir="$PROJECT_DIR" config repack.usedeltabaseoffset true
148 git --git-dir="$PROJECT_DIR" config repack.writebitmaps $WRITEBITMAPS
149 git --git-dir="$PROJECT_DIR" config pack.compression 9
150 git --git-dir="$PROJECT_DIR" config pack.indexversion 2
151
152 git --git-dir="$PROJECT_DIR" config gc.autodetach false
153 git --git-dir="$PROJECT_DIR" config gc.auto 0
154 git --git-dir="$PROJECT_DIR" config gc.autopacklimit 0
155 git --git-dir="$PROJECT_DIR" config gc.packrefs true
156 git --git-dir="$PROJECT_DIR" config gc.reflogexpire never
157 git --git-dir="$PROJECT_DIR" config gc.reflogexpireunreachable never
158 git --git-dir="$PROJECT_DIR" config receive.autogc false
159
160 git --git-dir="$PROJECT_DIR" config pack.window 250
161 git --git-dir="$PROJECT_DIR" config pack.depth 50
162
163 OUT=$(git -c gc.auto=6700 -c gc.autoPackLimit=4 --git-dir="$PROJECT_DIR" gc --auto --prune $OPTS || date +"%D %r Failed: $PROJECT_NAME") \
164 && log "$OUT"
165
166 (find "$PROJECT_DIR/refs/changes" -type d | xargs rmdir;
167 find "$PROJECT_DIR/refs/changes" -type d | xargs rmdir
168 ) 2>/dev/null
169
170 OUT=$(date +"%D %r Finished: $PROJECT_NAME$LOG_OPTS") && log "$OUT"
171}
172
173###########################
174# Main script starts here #
175###########################
176
177SKIP_PROJECTS=
178GC_PROJECTS=
179DONOT_WRITE_BITMAPS=
180SKIP_PROJECTS_OPT=0
181GC_PROJECTS_OPT=0
182DONOT_WRITE_BITMAPS_OPT=0
183
184while getopts 's:p:b:?h' c
185do
186 case $c in
187 s)
188 SKIP_PROJECTS="${SKIP_PROJECTS} ${OPTARG}.git"
189 SKIP_PROJECTS_OPT=1
190 ;;
191 p)
192 GC_PROJECTS="${GC_PROJECTS} ${OPTARG}.git"
193 GC_PROJECTS_OPT=1
194 ;;
195 b)
196 DONOT_WRITE_BITMAPS="${DONOT_WRITE_BITMAPS} ${OPTARG}.git"
197 DONOT_WRITE_BITMAPS_OPT=1
198 ;;
199 h|?)
200 usage
201 ;;
202 esac
203done
204
205test $# -eq 0 || usage
206
207TOP=/var/gerrit/git
208LOG=/var/log/git/gc.log
209
210OUT=$(date +"%D %r Started") && log "$OUT"
211
212if [ $GC_PROJECTS_OPT -eq 1 ]; then
213 gc_specified_projects
214else
215 gc_all_projects
216fi
217
218OUT=$(date +"%D %r Finished") && log "$OUT"
219
220exit 0