diff --git a/lib/ulib/vcs b/lib/ulib/vcs index bf168ac..79cbad9 100644 --- a/lib/ulib/vcs +++ b/lib/ulib/vcs @@ -442,15 +442,36 @@ function git_status() { git status "$@" } function git_update() { - local args + local args autoff=1 parse_opts + "${PRETTYOPTS[@]}" \ -x '$_vcs_unsupported -x' \ + -n,--no-autoff autoff= \ @ args -- "$@" && set -- "${args[@]}" || { eerror "$args" return 1 } - git pull "$@" + git pull "$@" || return + if [ -n "$autoff" ]; then + local orig_branch restore_branch rbranch + local -a branches + git_check_cleancheckout || return 0 + orig_branch="$(git_get_branch)" + array_from_lines branches "$(git_list_branches)" + for branch in "${branches[@]}"; do + remote="$(git_get_branch_remote "$branch")" + rbranch="$(git_get_branch_rbranch "$branch" "$remote")" + [ -n "$remote" -a -n "$rbranch" ] || continue + if git_should_ff "$branch" "$rbranch"; then + echo "Fast-forwarding $branch..." + git checkout -q "$branch" + git merge -q --ff-only "$rbranch" + restore_branch=1 + fi + done + [ -n "$restore_branch" ] && git checkout -q "$orig_branch" + fi + return 0 } function git_push() { local all all_branches all_tags auto force args no_annex @@ -593,6 +614,28 @@ function git_have_rbranch() { function git_get_branch() { git rev-parse --abbrev-ref HEAD 2>/dev/null } +function git_get_branch_remote() { + local branch="$1" + [ -n "$branch" ] || branch="$(git_get_branch)" + [ -n "$branch" ] || return + git config --get "branch.$branch.remote" +} +function git_get_branch_merge() { + local branch="$1" + [ -n "$branch" ] || branch="$(git_get_branch)" + [ -n "$branch" ] || return + git config --get "branch.$branch.merge" +} +function git_get_branch_rbranch() { + local branch="$1" remote="$2" merge + [ -n "$branch" ] || branch="$(git_get_branch)" + [ -n "$branch" ] || return + [ -n "$remote" ] || remote="$(git_get_branch_remote "$branch")" + [ -n "$remote" ] || return + merge="$(git_get_branch_merge "$branch")" + [ -n "$merge" ] || return + echo "refs/remotes/$remote/${merge#refs/heads/}" +} function git_is_branch() { [ "$(git_get_branch)" == "${1:-master}" ] } @@ -638,7 +681,7 @@ function git_ensure_cleancheckout() { function __git_init_ff() { o="${3:-origin}" - b="$1" s="${2:-remotes/$o/$1}" + b="$1" s="${2:-refs/remotes/$o/$1}" b="$(git rev-parse --verify --quiet "$b")" || return 1 s="$(git rev-parse --verify --quiet "$s")" || return 1 return 0 @@ -648,30 +691,30 @@ function __git_can_ff() { } function git_is_ancestor() { # vérifier que la branche $1 est un ancêtre direct de la branche $2, qui - # vaut par défaut remotes/${3:-origin}/$1 + # vaut par défaut refs/remotes/${3:-origin}/$1 # note: cette fonction retourne vrai si $1 et $2 identifient le même commit local o b s; __git_init_ff "$@" || return __git_can_ff "$b" "$s" } function git_should_ff() { # vérifier si la branche $1 devrait être fast-forwardée à partir de la - # branche d'origine $2, qui vaut par défaut remotes/${3:-origin}/$1 + # branche d'origine $2, qui vaut par défaut refs/remotes/${3:-origin}/$1 # note: cette fonction est similaire à git_is_ancestor(), mais retourne # false si $1 et $2 identifient le même commit local o b s; __git_init_ff "$@" || return [ "$b" != "$s" ] || return 1 - __git_can_ff "$b" "$o" + __git_can_ff "$b" "$s" } function git_should_push() { # vérifier si la branche $1 devrait être poussée vers la branche de même nom # dans l'origine $2(=origin), parce que l'origin peut-être fast-forwardée à # partir de cette branche. - git_should_ff "remotes/${2:-origin}/$1" "$1" + git_should_ff "refs/remotes/${2:-origin}/$1" "$1" } function git_fast_forward() { # vérifier que la branche courante est bien $1, puis tester s'il faut la # fast-forwarder à partir de la branche d'origine $2, puis le faire si c'est - # nécessaire. la branche d'origine $2 vaut par défaut remotes/origin/$1 + # nécessaire. la branche d'origine $2 vaut par défaut refs/remotes/origin/$1 local o b s; __git_init_ff "$@" || return [ "$b" != "$s" ] || return 1 local head="$(git rev-parse HEAD)" diff --git a/uproject b/uproject index 6b22edf..eaf77fb 100755 --- a/uproject +++ b/uproject @@ -44,6 +44,10 @@ COMMANDS update [-x] Mettre à jour la copie locale avec la copie sur le serveur. -x Ne pas mettre à jour les références externes (si appliquable) + -n, --no-autoff + Ne pas faire de fast-forward automatique pour toutes les branches + traquées. Par défaut, s'il n'y a pas de modifications locales, + essayer de fast-fowarder toutes les branches locales traquées. diff [options] Afficher les différences. -l Afficher les différences non commitées (par défaut)