-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathgit-create-repo.sh
executable file
·248 lines (223 loc) · 7.67 KB
/
git-create-repo.sh
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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
#!/bin/sh
########################################################################
# git-create-repo.sh: Git Repository Management Script
#
# Description:
# This script automates the creation and deletion of Git repositories.
# It allows for setting a custom path for the repository and includes options
# for a dry run, deleting an existing repository, and explicitly controlling
# the use of sudo. The default repository path is set to /var/lib/git if not
# specified. It checks for Git installation before proceeding.
#
# Author: id774 (More info: http://id774.net)
# Source Code: https://github.com/id774/scripts
# License: The GPL version 3, or LGPL version 3 (Dual License).
# Contact: idnanashi@gmail.com
#
# Version History:
# v1.7 2025-03-22
# Unify usage information by extracting help text from header comments.
# v1.6 2025-03-13
# Redirected error messages to stderr for better logging and debugging.
# v1.5 2025-03-05
# Added sudo privilege check when --sudo option is specified.
# v1.4 2024-06-23
# Changed the exit code from 1 to 0 for help message display.
# v1.3 2024-06-19
# Added --sudo and --no-sudo options to explicitly control sudo usage.
# Fixed bug where --dry-run option did not work during repository deletion.
# Added options to specify user and group for chown.
# v1.2 2024-01-07
# Updated command existence and execution permission checks
# using a common function for enhanced reliability and maintainability.
# v1.1 2023-12-07
# Added check for Git installation.
# v1.0 2023-11-26
# Initial release. Features include creating and deleting Git repositories,
# dry run option for creation, and custom repository path setting.
#
# Usage:
# This script automates the creation and deletion of Git repositories.
#
# To create a new repository:
# ./git-create-repo.sh <repository_name> [repository_path] [--dry-run] [--sudo] [--no-sudo] [--user USER] [--group GROUP]
#
# To delete an existing repository:
# ./git-create-repo.sh <repository_name> [repository_path] [--delete] [--dry-run] [--sudo] [--no-sudo] [--user USER] [--group GROUP]
#
# For help:
# ./git-create-repo.sh -h
#
# Options:
# --dry-run Show what would be done without making any changes.
# --delete Delete the specified repository instead of creating it.
# --sudo Explicitly use sudo for all operations, regardless of the repository path.
# --no-sudo Explicitly do not use sudo for any operations, regardless of the repository path.
# --user USER Specify the user for chown (default: git).
# --group GROUP Specify the group for chown (default: git).
#
# Examples:
# Create a new repository at /var/lib/git:
# ./git-create-repo.sh myrepo
#
# Create a new repository at a custom path without sudo:
# ./git-create-repo.sh myrepo /home/user/myrepo --no-sudo
#
# Delete an existing repository at /var/lib/git:
# ./git-create-repo.sh myrepo --delete
#
# Show what would be done without making changes:
# ./git-create-repo.sh myrepo /custom/path --dry-run
#
# Default Behavior:
# - The default repository path is /var/lib/git if not specified.
# - Sudo is used by default for system-wide paths like /var/lib/git.
# - Sudo is not used by default for paths within the user's home directory.
#
# Notes: The script may require sudo permissions for certain operations,
# especially when dealing with system-wide paths like /var/lib/git. By default,
# sudo is used for system-wide paths and not used for paths within the user's
# home directory. This behavior can be overridden with the --sudo or --no-sudo options.
#
########################################################################
# Display script usage information
usage() {
awk '
BEGIN { in_usage = 0 }
/^# Usage:/ { in_usage = 1; print substr($0, 4); next }
/^#{10}/ { if (in_usage) exit }
in_usage && /^#/ { print substr($0, 4) }
' "$0"
exit 0
}
# Check if the user has sudo privileges (password may be required)
check_sudo() {
if ! sudo -v 2>/dev/null; then
echo "Error: This script requires sudo privileges. Please run as a user with sudo access." >&2
exit 1
fi
}
# Check if necessary commands exist
check_commands() {
for cmd in "$@"; do
cmd_path=$(command -v "$cmd" 2>/dev/null)
if [ -z "$cmd_path" ]; then
echo "Error: Command '$cmd' is not installed. Please install $cmd and try again." >&2
exit 127
elif [ ! -x "$cmd_path" ]; then
echo "Error: Command '$cmd' is not executable. Please check the permissions." >&2
exit 126
fi
done
}
# Check if a directory exists
check_directory() {
dir=$1
if [ ! -d "$dir" ]; then
echo "Error: Directory '$dir' does not exist." >&2
exit 3
fi
}
# Check if a directory is a Git repository
is_git_repository() {
repo_path=$1
use_sudo=$2
if $use_sudo [ -d "${repo_path}/.git" ] || { $use_sudo [ -f "${repo_path}/HEAD" ] && $use_sudo [ -d "${repo_path}/objects" ]; }; then
return 0
else
return 1
fi
}
# Create a new Git repository with proper permissions
create_git_repo() {
repo_name=$1
repo_path=$2
dry_run=$3
use_sudo=$4
user=$5
group=$6
if [ "$dry_run" = true ]; then
echo "Dry run: A new repository would be created at '${repo_path}'"
return 0
fi
$use_sudo mkdir -p "${repo_path}" || return 1
cd "${repo_path}" || return 1
$use_sudo git init --bare --shared || return 1
$use_sudo chmod -R o-rwx,g+ws "${repo_path}" || return 1
if [ -z "$use_sudo" ]; then
chmod -R u+rwX "${repo_path}"
else
$use_sudo chown -R "${user}:${group}" "${repo_path}"
fi
echo "Repository '${repo_name}' created at '${repo_path}'"
}
# Delete a Git repository
delete_git_repo() {
repo_path=$1
dry_run=$2
use_sudo=$3
if [ "$dry_run" = true ]; then
echo "Dry run: The repository at '${repo_path}' would be deleted."
return 0
fi
if is_git_repository "$repo_path" "$use_sudo"; then
$use_sudo rm -rf "${repo_path}"
echo "Repository at '${repo_path}' has been deleted."
else
echo "Error: '${repo_path}' is not a Git repository." >&2
exit 4
fi
}
# Parse command-line arguments
parse_arguments() {
dry_run=false
delete_repo=false
explicit_sudo=""
user="git"
group="git"
while [ $# -gt 0 ]; do
case "$1" in
--dry-run) dry_run=true ;;
--delete) delete_repo=true ;;
--sudo) explicit_sudo="sudo" ;;
--no-sudo) explicit_sudo="" ;;
--user) user="$2"; shift ;;
--group) group="$2"; shift ;;
-h|--help) usage ;;
--) shift; break ;;
-*) usage ;;
*) break ;;
esac
shift
done
if [ "$#" -lt 1 ]; then
usage
fi
repo_name=$1
repo_base_path=${2:-"/var/lib/git"}
repo_full_path="${repo_base_path}/${repo_name}.git"
if [ -z "$explicit_sudo" ]; then
case "$repo_base_path" in
$HOME*) use_sudo="" ;;
*) use_sudo="sudo" ;;
esac
else
use_sudo="$explicit_sudo"
fi
}
# Main function to execute the script
main() {
parse_arguments "$@"
check_commands awk git
if [ "$use_sudo" = "sudo" ]; then
check_sudo
fi
if [ "$delete_repo" = true ]; then
delete_git_repo "${repo_full_path}" "$dry_run" "$use_sudo"
exit 0
fi
check_directory "$repo_base_path"
create_git_repo "${repo_name}" "${repo_full_path}" "$dry_run" "$use_sudo" "$user" "$group"
}
# Execute main function
main "$@"