#!/bin/bash Help(){ echo " NAME git_update.sh SYNOPSIS git_update.sh [-h] [-r ref] [-d dest] [-H] [-a] repository OPTIONS -h prints the help. -r specifies the reference to the commit to be synchronized. It can be a tag or a branch. By default, it is the last commit of branch main. It can be different from the actual branch. CAREFUL, the command git branch will always show the original branch name even though a branch switch has happened. -d specifies the destination of the clone or update. Directory must be empty if a new clone is to be made. If the repository to be cloned is local, and its path is passed as a relative path, the path should start from the destination. To avoid mistakes, absolute paths are advised. -H allows the $HOME directory to be used by git_update.sh. By default, git_update.sh cannot access $HOME to prevent default behavior. If you need the global .gitconfig located in your $HOME to be used, you should supply the -H option. -a specifies that the aggressive option of the git garbage collection must be used. Only advised when changes happen in many different objects. Will slow down the execution. -o ssh options for ssh clone DESCRIPTION This script will replace the destination with the wanted commit of a git repository. The history is not preserved but tags are. Untracked files remain. The git commands have been chosen so as to minimize the memory and bandwidth usages." } #variables summary="$0 [options] " ref=main dst='.' use_home=false be_aggressive="false" ssh_opts="ssh" while getopts ":ho:r:d:H" option; do case $option in h) # display Help Help exit;; r) # desired branch or tag ref="$OPTARG";; d) # destination of clone dst="$OPTARG";; H) # use real home dir use_home="true";; a) #use -a in git gc call be_aggressive="true";; o) # ssh options ssh_opts="$ssh_opts $OPTARG";; \?) # invalid option echo "Error: Invalid option '$option'" exit;; esac done shift $((OPTIND-1)) repo="$1" if [ -z "$repo" ] ; then exit "$0: Empty repo given\n$summary" fi if [ ! $use_home ] ; then set -a export HOME=/dev/null set +a fi mkdir -p "$dst" cd "$dst" if [ -d .git ] ; then echo "updating..." git fetch --tags --depth=1 --prune --prune-tags --force origin $ref git reset --hard --recurse-submodules FETCH_HEAD git submodule update --init --recursive --force --depth=1 --remote #garbage collection of anything unreachable at the moment git reflog expire --expire=now --all if "$be_aggressive" ; then git gc --prune=now --aggressive elsels git gc --prune=now fi else echo "cloning..." clone_dst='.' git clone -b "$ref" --recurse-submodules --shallow-submodules --depth 1 --config core.sshCommand="$ssh_opts" "$repo" "$clone_dst" fi