#!/usr/bin/env bash # git-update --- combine fetch/pull/submodules/lfs/rebase of workspace # Author: Noah Friedman # Created: 2015-10-31 # Public domain # $Id: git-update,v 1.10 2019/08/21 19:43:42 friedman Exp $ git() { command ${GITPROG-git} "$@"; } git_revno() { git rev-list -n1 HEAD } bare_repo_p() { case `git config --bool --local --get core.bare` in true ) return 0 ;; * ) return 1 ;; esac } has_remotes() { # exit code 1 if no matches git config --local --get-regexp '^remote\..*\.url$' > /dev/null } # Fast forward, without checkout, any non up-to-date local branches that # have no local commits which would need merging with the upstream. fastforward_refs() { ref_cur=`git symbolic-ref HEAD` git for-each-ref --format='%(refname) %(upstream)' refs/heads | while read ref_loc ref_rem; do # check if no upstream or ref is current checkout case $ref_rem:$ref_loc in :* | *:$ref_cur ) continue ;; esac rev_loc=`git rev-parse $ref_loc` rev_rem=`git rev-parse $ref_rem` case $rev_loc in $rev_rem ) continue ;; esac case `git merge-base $ref_loc $ref_rem` in $rev_loc ) git update-ref $ref_loc $ref_rem ;; esac done } apush() { eval "$1=(\"\${$1[@]}\" \"\${@:2}\")"; } main() { while :; do case $1 in -r | --rebase ) shift; apush gitargs --rebase=preserve ;; -p | --prune ) shift; apush gitargs --prune ;; * ) break ;; esac done case $# in 0 ) set . ;; esac for dir in "$@"; do if [ $# -gt 1 ]; then case $dir in . ) gdir=`pwd` ;; .. ) gdir=`cd .. && pwd` ;; * ) gdir=$dir ;; esac echo "* $gdir" fi ( cd "$dir" || exit $? if ! has_remotes; then #echo "repository has no upstream remotes" return 0 fi if bare_repo_p; then git fetch --all test -d lfs/objects && git lfs fetch --all else revno_old=`git_revno` git pull "${gitargs[@]}" --all --no-stat --recurse-submodules revno_new=`git_revno` git restore-commit-mtime $revno_old..$revno_new fastforward_refs fi ) test $# -gt 1 && echo done } main "$@" # eof