This repository has been archived by the owner on Jan 15, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
git-src
executable file
·159 lines (145 loc) · 6.52 KB
/
git-src
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
#!/usr/bin/env sh
export LC_ALL=C
# shellcheck disable=SC1091
. "$MBX_LIBPATH/_.sh" || exit 1
usage="$(cat << EOF
Usage: $(basename "$0") [COMMAND] [REPO] [OPTIONS]
Adds, updates or deletes git source files of third party vendors.
This tool is meant to clone third party sources to compile or use without further modification.
It will try to checkout the latest tag and fallback to the latest branch, unless a prefered branch/tag is given.
If you want to load a workspace, consider forking and cloning using the normal git utility instead.
COMMAND
ls Lists all locally added repositories/branches.
dir Outputs the directory of the given repository/branch.
sh Switches to the given repository/branch in a new shell.
add Clones the given repository/branch with all its submodules with depth of 1 into the localized source storage.
up Resets and pulls the latest changes on the given repository/branch.
up-all Resets and pulls the latest changes on all repositories/branches.
del Deletes the given repository/branch from the system.
REPO
Unused on the ls and up-all command.
For the add-command, needs to be a HTTPS URL or SSH destination ending with .git.
For any other command it can also be just the sub path (without branch) on the file system.
OPTIONS
-V, --version Prints the version of this script suite (MBX).
-v, --verbose Prints verbose information.
-p=*, --path=* Sets the working directory path (root) of the localized source storage (default: /usr/local/src/git).
-b=*, --branch=* Sets the branch/tag of the repo to work with.
-f, --force Forces the operation that will potentially result in destructive behavior to ensure a successful operation.
-h, --help Prints this help message.
EOF
)"
path="/usr/local/src/git"
while [ "$#" -gt 0 ]; do
case "$1" in
-V|--version) echo "$MBX_VERSION" && exit 0 ;;
-v|--verbose) verbose=1 ;;
-p=*|--path=*) path="${1#*=}" ;;
-b=*|--branch=*) branch="${1#*=}" ;;
-f|--force) force=1 ;;
-h|--help) echo "$usage" && exit 129 ;;
*)
if [ "$command" = "" ]; then
command="$1"
elif [ "$repo" = "" ]; then
repo="$1"
else
echo "! Invalid command line flag $1." >&2;
exit 1
fi
;;
esac
shift
done
test -n "$verbose" && set -x
set -e
lookupdir="share"
test ! "$command" = "" || { echo ! Missing command. >&2; exit 1; }
if [ ! -d "$path/$lookupdir" ]; then
echo - Setting up $lookupdir directory ...
erun mkdir -p "$path"
erun chown -R "$(whoami)" "$path"
mkdir -p "$path/$lookupdir"
fi
if [ "$command" = "ls" ]; then
find "$path/$lookupdir" -type l -execdir echo {} \; | sed 's/,,/ -b=/' | tr , /
exit
elif [ "$command" = "up-all" ]; then
"$0" ls | xargs -L1 "$0" up
exit
fi
test -n "$repo" || { echo ! Missing repo. >&2; exit 1; }
test "$repo" = "${repo% *}" || { echo ! Cannot have spaces in repo. >&2; exit 1; }
subpath="$repo"
subpath="${subpath#*//}" # remove ^https://
subpath="${subpath#*@}" # remove ^git@
subpath="${subpath%.git}" # remove .git$
subpath=$(printf '%s' "$subpath" | tr : /) # replace : with /
test ! "$(printf '%s' "$subpath" | tr -d / | tr -d '.')" = "" || { echo ! Local subpath results in empty or invalid path. >&2; exit 1; }
if [ "$branch" = "" ]; then
branch="$(git ls-remote --tags --sort="v:refname" "https://$subpath.git" | tail -n1 | awk -F '[/\^]' '{print $3}')" # get latest tag
test ! "$branch" = "" || branch="$(git ls-remote --symref "https://$subpath.git" HEAD | awk '/^ref:/ {sub(/refs\/heads\//, "", $2); print $2}')" # or get default branch
link="$path/$lookupdir/$(printf '%s' "$subpath" | tr / ,)" # will not include branch/tag for rolling release
else
link="$path/$lookupdir/$(printf "%s,,%s" "$subpath" "$branch" | tr / ,)"
fi
fullpath="$path/$subpath/$branch"
if [ "$command" = "dir" ]; then
test -d "$link" || exit 2
readlink -f "$link" && exit 0
elif [ "$command" = "sh" ]; then
test -d "$link" || { echo ! Repository doesn\'t exist on the local system. >&2; exit 2; }
cd "$path/$lookupdir/$(readlink "$link")"
"$SHELL" -i && exit 0
elif [ "$command" = "add" ]; then
if [ -n "$force" ]; then
rm -rf "$fullpath" || true
rm -rf "$link" || true
fi
test ! -d "$link" || { echo ! Repository already added to the local system, consider updating it using the up-command instead or add the -f flag to forcefully re-install. >&2; exit 2; }
echo "- Adding $repo \($branch\) to $fullpath ..."
if [ ! -d "$fullpath" ]; then
mkdir -p "$fullpath"
git clone --recursive --depth 1 --branch "$branch" "$repo" "$fullpath"
else
echo - Repository already found, version link will be added ...
fi
ln -sf "../$subpath/$branch" "$link"
elif [ "$command" = "up" ]; then
test -d "$link" || { echo ! Repository doesn\'t exist on the local system. >&2; exit 2; }
# TODO: Detect if on a tag at the moment. If so, check if there is a new tag. If so, update to new tag.
echo - Updating "$fullpath" ...
if [ ! -d "$fullpath" ]; then # link exists but determined fullpath does not?
rm -rf "${path:?}/$lookupdir/$(readlink "$link")" || true # try to remove old version
rm "$link"
# TODO: don't delete old version if it is installed seperately
mkdir -p "$fullpath"
git clone --recursive --depth 1 --branch "$branch" "$repo" "$fullpath"
ln -sf "../$subpath/$branch" "$link"
else
if ! git -C "$fullpath" pull --rebase; then
if [ "$force" ]; then
git -C "$fullpath" reset --hard
git -C "$fullpath" pull --ff-only
else
git rebase --abort
echo ! Update failed, because incoming changes cannot be merged with local changes. Use the -f flag to force a reset of local changes or manually rebase and solve the conflicts. >&2
exit 3
fi
fi
fi
elif [ "$command" = "del" ]; then
test -d "$link" || test -n "$force" || { echo ! Repository doesn\'t exist on the local system. Use the -f flag to forcefully try delete and clean up anyways. >&2; exit 2; }
test -d "$link" && fullpath="$path$(readlink "$link" | sed 's/^..//')" # get real fullpath in case of older rolling
echo "- Deleting $fullpath ..."
rm -rf "$fullpath" || test -n "$force"
echo - Cleaning up ...
rm -rf "$link" || test -n "$force"
rmdir "$path/$lookupdir" 2>/dev/null || true
find "$path/" -depth -mindepth 1 -type d -exec rmdir {} + 2>/dev/null || true
# TODO: Tackle invisible files
else
echo "! Unknown command $command." >&2
exit 1
fi
set +e && set +x && echo - Done!