#!/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. -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. 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" while getopts ":hr: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";; \?) # invalid option echo "Error: Invalid option here" 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 "$repo" "$clone_dst" fi