1161 lines
		
	
	
		
			35 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
			
		
		
	
	
			1161 lines
		
	
	
		
			35 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
| ##@cooked comments # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
 | |
| ## Fonctions pour gérer les outils de vcs (subversion, git)
 | |
| ##@cooked nocomments
 | |
| ##@require base
 | |
| uprovide vcs
 | |
| urequire ulib base
 | |
| 
 | |
| ################################################################################
 | |
| # Général
 | |
| 
 | |
| function __vcs_get_type() {
 | |
|     # Afficher le type de vcs du répertoire $1. L'arborescence n'est pas
 | |
|     # parcourue. Si l'information n'est pas immédiatement disponible, cette
 | |
|     # fonction échoue.
 | |
|     # retourner 1 si le type n'a pas été trouvé
 | |
|     [ -d "$1/.git" ] && { echo "git"; return; }
 | |
|     [ -d "$1/.svn" ] && { echo "svn"; return; }
 | |
|     [ -d "$1/CVS" ] && { echo "cvs"; return; }
 | |
|     return 1
 | |
| }
 | |
| 
 | |
| function __vcs_find_type() {
 | |
|     # Chercher le type de vcs du répertoire $1. L'arborescence jusqu'au
 | |
|     # répertoire $HOME est parcourue si nécessaire. $1 doit être un répertoire
 | |
|     # absolu.
 | |
|     # Retourner 1 si le type n'a pas été trouvé
 | |
|     local root="$1"
 | |
|     # soit on a l'information immédiatement...
 | |
|     __vcs_get_type "$root" && return
 | |
|     # soit il faut la chercher en parcourant l'arborescence...
 | |
|     while [ -n "$root" -a "$root" != "/" -a "$root" != "." -a "$root" != "$HOME" ]; do
 | |
|         __vcs_get_type "$root" && return
 | |
|         root="$(dirname "$root")"
 | |
|     done
 | |
|     return 1
 | |
| }
 | |
| 
 | |
| function __vcs_upward_until() {
 | |
|     local root="$1"
 | |
|     local type="$2"
 | |
|     while [ -n "$root" -a "$root" != "/" -a "$root" != "." -a "$(__vcs_get_type "$root/..")" == "$type" ]; do
 | |
|         root="$(dirname "$root")"
 | |
|     done
 | |
|     echo "$root"
 | |
| }
 | |
| 
 | |
| function __vcs_find_root() {
 | |
|     # A partir du répertoire $1, chercher le répertoire de base du checkout
 | |
|     # local. $1 doit être un répertoire absolu.
 | |
|     # retourner 1 si le type n'a pas été trouvé
 | |
|     local root="$1"
 | |
|     local type="$(__vcs_get_type "$root")"
 | |
|     if [ "$type" == "git" ]; then
 | |
|         # si le type est git, nous sommes forcément déjà à la racine
 | |
|         echo "$root"
 | |
|         return
 | |
|     elif [ "$type" == "svn" -o "$type" == "cvs" ]; then
 | |
|         # trouver le répertoire le plus haut
 | |
|         __vcs_upward_until "$root" "$type"
 | |
|         return
 | |
|     else
 | |
|         # sinon, il faut chercher dans les répertoire au dessus jusqu'à trouver
 | |
|         # un repository. On arrête la recherche à $HOME
 | |
|         local found
 | |
|         while [ -n "$root" -a "$root" != "/" -a "$root" != "." -a "$root" != "$HOME" ]; do
 | |
|             type="$(__vcs_get_type "$root")" && { found=1; break; }
 | |
|             root="$(dirname "$root")"
 | |
|         done
 | |
|         if [ -n "$found" ]; then
 | |
|             if [ "$type" == "git" ]; then
 | |
|                 echo "$root"
 | |
|                 return
 | |
|             elif [ "$type" == "svn" -o "$type" == "cvs" ]; then
 | |
|                 __vcs_upward_until "$root" "$type"
 | |
|                 return
 | |
|             fi
 | |
|         fi
 | |
|     fi
 | |
|     return 1
 | |
| }
 | |
| 
 | |
| function _vcs_get_dir() {
 | |
|     abspath "${1:-.}"
 | |
| }
 | |
| function _vcs_get_type() {
 | |
|     __vcs_find_type "$1" || {
 | |
|         eerror "$(ppath "$1"): Ce répertoire n'est pas versionné"
 | |
|         return 1
 | |
|     }
 | |
| }
 | |
| 
 | |
| function _vcs_unsupported() {
 | |
|     eerror "${1:+$1: }Opération ou option non supportée"
 | |
|     return 1
 | |
| }
 | |
| function _vcs_invalid_copy() {
 | |
|     eerror "Vous ne pouvez copier/déplacer qu'un fichier sur un fichier"
 | |
|     return 1
 | |
| }
 | |
| function _vcs_check_nbargs() {
 | |
|     [ "$1" -ge "$2" ] || {
 | |
|         eerror "Cette commande nécessite au moins $2 argument(s)"
 | |
|         return 1
 | |
|     }
 | |
|     if [ -n "$3" ]; then
 | |
|         [ "$1" -le "$3" ] || {
 | |
|             eerror "Cette commande supporte au plus $3 argument(s)"
 | |
|             return 1
 | |
|         }
 | |
|     fi
 | |
|     return 0
 | |
| }
 | |
| 
 | |
| function _vcs_showhelp() {
 | |
|     local action func
 | |
|     action="$1"; shift
 | |
|     func="vcs_${action}_help"
 | |
|     [ $# == 1 -a "$1" == "--help" ] && { "$func" "$action"; return; }
 | |
|     return 1
 | |
| }
 | |
| 
 | |
| function _vcs_dispatch() {
 | |
|     local dir action type func
 | |
|     dir="$(_vcs_get_dir "$1")"; shift
 | |
|     action="$1"; shift
 | |
|     _vcs_showhelp "$action" "$@" && return
 | |
|     type="$(_vcs_get_type "$dir")" || return
 | |
|     func="${type}_${action}"
 | |
|     "$func" "$@"
 | |
| }
 | |
| 
 | |
| ########################################
 | |
| function vcs_getvcs_help() {
 | |
|     local OENC="$UTF8"
 | |
|     uecho "uproject $1: Afficher le type de vcs pour le répertoire spécifié
 | |
| 
 | |
| USAGE
 | |
|     uproject $1 [dir]"
 | |
| }
 | |
| function vcs_getvcs() {
 | |
|     _vcs_showhelp getvcs "$@" && return
 | |
|     __vcs_find_type "$(_vcs_get_dir "$1")"
 | |
| }
 | |
| ########################################
 | |
| function vcs_getroot_help() {
 | |
|     local OENC="$UTF8"
 | |
|     uecho "uproject $1: Afficher le répertoire racine du projet versionné correspondant au répertoire spécifié
 | |
| 
 | |
| USAGE
 | |
|     uproject $1 [dir]"
 | |
| }
 | |
| function vcs_getroot() {
 | |
|     _vcs_showhelp getvcs "$@" && return
 | |
|     __vcs_find_root "$(_vcs_get_dir "$1")"
 | |
| }
 | |
| ########################################
 | |
| function vcs_getrepos_help() {
 | |
|     local OENC="$UTF8"
 | |
|     uecho "uproject $1: Afficher l'url du repository du projet versionné correspondant au répertoire spécifié
 | |
| 
 | |
| USAGE
 | |
|     uproject $1 [dir]"
 | |
| }
 | |
| function vcs_getrepos() {
 | |
|     _vcs_dispatch "$1" getrepos "$@"
 | |
| }
 | |
| ########################################
 | |
| function vcs_geturl_help() {
 | |
|     local OENC="$UTF8"
 | |
|     uecho "uproject $1: Afficher l'url dans le repository du répertoire versionné spécifié
 | |
| 
 | |
| USAGE
 | |
|     uproject $1 [dir]"
 | |
| }
 | |
| function vcs_geturl() {
 | |
|     _vcs_dispatch "$1" geturl "$@"
 | |
| }
 | |
| ########################################
 | |
| function vcs_vcs_help() {
 | |
|     local OENC="$UTF8"
 | |
|     uecho "uproject $1: Appeler le gestionnaire de version approprié avec les arguments donnés
 | |
| 
 | |
| USAGE
 | |
|     uproject $1 [args]
 | |
| 
 | |
| note: les commandes suivantes permettent de lancer des opérations avancées:
 | |
| $(array_to_lines __VCS_GIT_ADVANCED "" "    ")"
 | |
| }
 | |
| function vcs_vcs() {
 | |
|     _vcs_showhelp vcs "$@" && return
 | |
| 
 | |
|     local i f t
 | |
|     for i in "${__VCS_GIT_ADVANCED_MAP[@]}"; do
 | |
|         splitpair "$i" f t
 | |
|         if [ "$1" == "$f" ]; then
 | |
|             shift
 | |
|             set -- "$t" "$@"
 | |
|             break
 | |
|         fi
 | |
|     done
 | |
|     if array_contains __VCS_GIT_ADVANCED "$1"; then
 | |
|         "$@"
 | |
|         return $?
 | |
|     fi
 | |
| 
 | |
|     local type
 | |
|     type="$(_vcs_get_type "$(_vcs_get_dir)")" || return
 | |
|     "$type" "$@"
 | |
| }
 | |
| ########################################
 | |
| function vcs_add_help() {
 | |
|     local OENC="$UTF8"
 | |
|     uecho "uproject $1: Ajouter les fichiers spécifiés dans le gestionnaire de version
 | |
| 
 | |
| USAGE
 | |
|     uproject $1 <files...>"
 | |
| }
 | |
| function vcs_add() {
 | |
|     # le répertoire de référence est le répertoire du premier fichier ajouté
 | |
|     _vcs_dispatch "$(dirname "$1")" add "$@"
 | |
| }
 | |
| ########################################
 | |
| function vcs_remove_help() {
 | |
|     local OENC="$UTF8"
 | |
|     uecho "uproject $1: Suppprimer les fichiers versionnés spécifiés du gestionaire de version
 | |
| 
 | |
| USAGE
 | |
|     uproject $1 <files...>"
 | |
| }
 | |
| function vcs_remove() {
 | |
|     # le répertoire de référence est le répertoire du premier fichier supprimé
 | |
|     _vcs_dispatch "$(dirname "$1")" remove "$@"
 | |
| }
 | |
| ########################################
 | |
| function vcs_copy_help() {
 | |
|     local OENC="$UTF8"
 | |
|     uecho "uproject $1: Copier les fichiers versionnés spécifiés
 | |
| 
 | |
| USAGE
 | |
|     uproject $1 <sources...> <dest>"
 | |
| }
 | |
| function vcs_copy() {
 | |
|     # le répertoire de référence est le répertoire de destination
 | |
|     local last=$#
 | |
|     _vcs_dispatch "$(dirname "${!last}")" copy "$@"
 | |
| }
 | |
| ########################################
 | |
| function vcs_move_help() {
 | |
|     local OENC="$UTF8"
 | |
|     uecho "uproject $1: Déplacer les fichiers versionnés spécifiés
 | |
| 
 | |
| USAGE
 | |
|     uproject $1 <sources...> <dest>"
 | |
| }
 | |
| function vcs_move() {
 | |
|     # le répertoire de référence est le répertoire de destination
 | |
|     local last=$#
 | |
|     _vcs_dispatch "$(dirname "${!last}")" move "$@"
 | |
| }
 | |
| ########################################
 | |
| function vcs_mkdir_help() {
 | |
|     local OENC="$UTF8"
 | |
|     uecho "uproject $1: Créer un nouveau répertoire versionné
 | |
| 
 | |
| USAGE
 | |
|     uproject $1"
 | |
| }
 | |
| function vcs_mkdir() {
 | |
|     # le répertoire de référence est le répertoire du premier répertoire créé
 | |
|     _vcs_dispatch "$(dirname "$1")" mkdir "$@"
 | |
| }
 | |
| ########################################
 | |
| function vcs_commit_help() {
 | |
|     local OENC="$UTF8"
 | |
|     uecho "uproject $1: Enregistrer les modifications sur les fichiers modifiés avec le message spécifiés
 | |
| 
 | |
| USAGE
 | |
|     uproject $1 <message> [files...]
 | |
| 
 | |
| Si files n'est pas spécifié, prendre tous les fichiers modifiés actuellement
 | |
| 
 | |
| OPTIONS
 | |
|     -a  Enregistrer les modifications sur les fichiers modifiés uniquement.
 | |
|     -A  Enregistrer les modifictions sur les nouveaux fichiers et les fichiers
 | |
|         modifiés.
 | |
|     -c  Enregistrer uniquement les modifications de l'index. (si applicable)
 | |
|     -p  Pousser les modifications sur le serveur après le commit (par défaut)
 | |
|     -l  Garder le commit local, i.e. les modifications ne sont pas poussées sur
 | |
|         le serveur. (si applicable)"
 | |
| }
 | |
| function vcs_commit() {
 | |
|     _vcs_dispatch "" commit "$@"
 | |
| }
 | |
| ########################################
 | |
| function vcs_status_help() {
 | |
|     local OENC="$UTF8"
 | |
|     uecho "uproject $1: Afficher l'état des fichiers versionnés et non versionnés
 | |
| 
 | |
| USAGE
 | |
|     uproject $1"
 | |
| }
 | |
| function vcs_status() {
 | |
|     _vcs_dispatch "" status "$@"
 | |
| }
 | |
| ########################################
 | |
| function vcs_update_help() {
 | |
|     local OENC="$UTF8"
 | |
|     uecho "uproject $1: Mettre à jour le checkout local avec les modifications présentes sur le serveur
 | |
| 
 | |
| USAGE
 | |
|     uproject $1
 | |
| 
 | |
| OPTIONS
 | |
|     -x  Ne pas mettre à jour les références externes"
 | |
| }
 | |
| function vcs_update() {
 | |
|     _vcs_dispatch "" update "$@"
 | |
| }
 | |
| ########################################
 | |
| function vcs_push_help() {
 | |
|     local OENC="$UTF8"
 | |
|     uecho "uproject $1: Pousser les modifications locales sur le serveur
 | |
| 
 | |
| USAGE
 | |
|     uproject $1"
 | |
| }
 | |
| function vcs_push() {
 | |
|     _vcs_dispatch "" push "$@"
 | |
| }
 | |
| ########################################
 | |
| function vcs_diff_help() {
 | |
|     local OENC="$UTF8"
 | |
|     uecho "uproject $1: Afficher les différences
 | |
| 
 | |
| USAGE
 | |
|     uproject $1
 | |
| 
 | |
| OPTIONS
 | |
|     -l  (par défaut) Afficher les différences non commitées
 | |
|     -c  Si cela a du sens, afficher les différences en passe d'être commitées
 | |
|     -r REVISION
 | |
|         Afficher les différences depuis la révision spécifiée
 | |
|     -R  Afficher les modifications effectuées depuis la dernière release
 | |
| Pour le moment, l'option -R n'est pas implémentée"
 | |
| }
 | |
| function vcs_diff() {
 | |
|     _vcs_dispatch "" diff "$@"
 | |
| }
 | |
| ########################################
 | |
| function vcs_tag_help() {
 | |
|     local OENC="$UTF8"
 | |
|     uecho "uproject $1: donner un nom symbolique à la révision courante
 | |
| 
 | |
| USAGE
 | |
|     uproject $1 <name>"
 | |
| }
 | |
| function vcs_tag() {
 | |
|     _vcs_dispatch "" tag "$@"
 | |
| }
 | |
| ########################################
 | |
| # XXX Ajouter vcs_revert, vcs_resolve, uproject_grep
 | |
| 
 | |
| ################################################################################
 | |
| # Git
 | |
| 
 | |
| function git_getrepos() {
 | |
|     git config --get remote.origin.url
 | |
| }
 | |
| function git_geturl() {
 | |
|     git config --get remote.origin.url
 | |
| }
 | |
| function git_have_annex() {
 | |
|     [ -n "$(git config --get annex.uuid)" ]
 | |
| }
 | |
| function git_add() {
 | |
|     git add "$@"
 | |
| }
 | |
| function git_remove() {
 | |
|     git rm "$@"
 | |
| }
 | |
| function git_copy() {
 | |
|     git cp "$@"
 | |
| }
 | |
| function git_move() {
 | |
|     git mv "$@"
 | |
| }
 | |
| function git_mkdir() {
 | |
|     git mkdir "$@"
 | |
| }
 | |
| function git_commit() {
 | |
|     local all=auto allnew push=auto nopush args
 | |
|     setyesval nopush "$UTOOLS_VCS_OFFLINE"
 | |
|     [ -n "$nopush" ] && push=
 | |
|     parse_opts + "${PRETTYOPTS[@]}" \
 | |
|         -a,--all all=1 \
 | |
|         -A,--all-new allnew=1 \
 | |
|         -c,--cached all= \
 | |
|         -p,--push push=1 \
 | |
|         -l,--local push= \
 | |
|         @ args -- "$@" && set -- "${args[@]}" || {
 | |
|         eerror "$args"
 | |
|         return 1
 | |
|     }
 | |
| 
 | |
|     if [ -n "$allnew" ]; then
 | |
|         git add -A
 | |
|         all=
 | |
|     fi
 | |
| 
 | |
|     local message="$1"; shift
 | |
|     local -a cmd
 | |
|     cmd=(git commit)
 | |
|     [ -n "$message" ] && cmd=("${cmd[@]}" -m "$message")
 | |
|     if [ "$all" == "auto" ]; then
 | |
|         # Si des fichiers sont spécifiés, prendre ceux-là.
 | |
|         if [ -z "$*" ]; then
 | |
|             # Sinon, s'il y a des fichiers dans l'index, commiter uniquement ces
 | |
|             # fichiers
 | |
|             # Sinon, committer tous les fichiers modifiés
 | |
|             # le code suivant retourne vrai si l'index contient au moins fichier
 | |
|             git status --porcelain 2>/dev/null | awk '
 | |
|                 BEGIN { ec = 1 }
 | |
|                 substr($0, 1, 1) ~ /[^ ?]/ { ec = 0; exit }
 | |
|                 END { exit ec }' ||
 | |
|             cmd=("${cmd[@]}" -a)
 | |
|         fi
 | |
|     else
 | |
|         [ -n "$all" ] && cmd=("${cmd[@]}" -a)
 | |
|     fi
 | |
| 
 | |
|     if ! "${cmd[@]}" "$@"; then
 | |
|         [ "$push" == auto ] && return 1
 | |
|     fi
 | |
|     if [ "$push" == auto ]; then
 | |
|         git_push --auto || return
 | |
|     elif [ -n "$push" ]; then
 | |
|         git_push --force || return
 | |
|     fi
 | |
|     return 0
 | |
| }
 | |
| function git_status() {
 | |
|     git status "$@"
 | |
| }
 | |
| function __gu_list_lbranches() {
 | |
|     git for-each-ref refs/heads/ --format='%(refname:short)' |
 | |
|         grep -vF master |
 | |
|         grep -vF develop |
 | |
|         grep -v '^release-' |
 | |
|         grep -v '^hotfix-'
 | |
| }
 | |
| function git_update() {
 | |
|     local args clean= autoff=1
 | |
|     parse_opts + "${PRETTYOPTS[@]}" \
 | |
|         -x '$_vcs_unsupported -x' \
 | |
|         -c,--clean-before clean=1 \
 | |
|         -n,--no-autoff autoff= \
 | |
|         @ args -- "$@" && set -- "${args[@]}" || {
 | |
|         eerror "$args"
 | |
|         return 1
 | |
|     }
 | |
| 
 | |
|     if [ -z "$autoff" ]; then
 | |
|         git pull "$@"
 | |
|         return $?
 | |
|     fi
 | |
| 
 | |
|     local branch orig_branch restore_branch remote rbranch pbranch
 | |
|     local -a branches prbranches crbranches dbranches
 | |
| 
 | |
|     orig_branch="$(git_get_branch)"
 | |
| 
 | |
|     if [ -n "$clean" ]; then
 | |
|         local l r; local -a error
 | |
|         git_ensure_cleancheckout
 | |
|         if git_have_branch develop; then
 | |
|             if [ "$orig_branch" != develop ]; then
 | |
|                 estep "basculement sur la branche develop"
 | |
|                 git checkout -q develop
 | |
|                 restore_branch=1
 | |
|             fi
 | |
|             array_from_lines prbranches "$(git_list_rbranches)"
 | |
|             array_from_lines branches "$(__gu_list_lbranches)"
 | |
|             for branch in "${branches[@]}"; do
 | |
|                 if array_contains prbranches "origin/$branch"; then
 | |
|                     l="$(git rev-parse --verify --quiet "$branch")"
 | |
|                     r="$(git rev-parse --verify --quiet "origin/$branch")"
 | |
|                     if [ "$l" == "$r" ]; then
 | |
|                         estepn "$branch: branche locale supprimée"
 | |
|                         git branch -q -D "$branch"
 | |
|                     else
 | |
|                         array_add error "$branch"
 | |
|                     fi
 | |
|                 else
 | |
|                     estep "$branch: branche locale gardée"
 | |
|                 fi
 | |
|             done
 | |
|             if [ "${#error[*]}" -gt 0 ]; then
 | |
|                 eerror "Les branches locales suivantes diffèrent de l'origine: ${COULEUR_JAUNE}${error[*]}${COULEUR_NORMALE}"
 | |
|                 enote "Si vous êtes *certains* qu'il n'y a aucune modification locale à garder:
 | |
| - supprimez ces branches manuellement
 | |
| - ou faites-en une copie locale
 | |
| puis relancez cette commande."
 | |
|                 return 1
 | |
|             fi
 | |
|         fi
 | |
|     fi
 | |
| 
 | |
|     array_from_lines prbranches "$(git_list_rbranches)"
 | |
|     git fetch -p "$@" || return
 | |
|     array_from_lines crbranches "$(git_list_rbranches)"
 | |
| 
 | |
|     # vérifier s'il n'y a pas des branches distantes qui ont été supprimées
 | |
|     for branch in "${prbranches[@]}"; do
 | |
|         if ! array_contains crbranches "$branch"; then
 | |
|             array_add dbranches "${branch#*/}"
 | |
|         fi
 | |
|     done
 | |
|     if [ ${#dbranches[*]} -gt 0 ]; then
 | |
|         eimportant "One or more distant branches where deleted"
 | |
|         for branch in "${dbranches[@]}"; do
 | |
|             if git_have_branch "$branch"; then
 | |
|                 if ! ask_yesno "Do you want to delete local branch $branch?" X; then
 | |
|                     array_del dbranches "$branch"
 | |
|                 fi
 | |
|             fi
 | |
|         done
 | |
|     fi
 | |
|     if [ ${#dbranches[*]} -gt 0 ]; then
 | |
|         array_from_lines branches "$(git_list_branches)"
 | |
|         branch="$(git_get_branch)"
 | |
|         if array_contains dbranches "$branch"; then
 | |
|             # si la branche courante est l'une des branches à supprimer, il faut
 | |
|             # basculer vers develop ou master
 | |
|             local swto
 | |
|             if [ -z "$swto" ] && array_contains branches develop && ! array_contains dbranches develop; then
 | |
|                 swto=develop
 | |
|             fi
 | |
|             if [ -z "$swto" ] && array_contains branches master && ! array_contains dbranches master; then
 | |
|                 swto=master
 | |
|             fi
 | |
|             if ! git_check_cleancheckout; then
 | |
|                 echo "* There are uncommitted local changes. However current branch is slated for removal.
 | |
| Make your verifications then delete the local branches:
 | |
|     ${swto:+$(qvals git checkout "$swto")
 | |
|     }$(qvals git branch -D "${dbranches[@]}")"
 | |
|                 return 1
 | |
|             fi
 | |
|             if [ -n "$swto" ]; then
 | |
|                 git checkout -q "$swto"
 | |
|             else
 | |
|                 echo "* Current branch is slated for removal but I don't know to which branch I should switch first.
 | |
| Make your choice then delete the local branches:
 | |
|     $(qvals git branch -D "${dbranches[@]}")"
 | |
|                 return 1
 | |
|             fi
 | |
|         fi
 | |
|         for branch in "${dbranches[@]}"; do
 | |
|             git branch -D "$branch"
 | |
|         done
 | |
|     fi
 | |
| 
 | |
|     # intégrer les modifications dans les branches locales
 | |
|     if ! git_check_cleancheckout; then
 | |
|         branch="$(git_get_branch)"
 | |
|         remote="$(git_get_branch_remote "$branch")"
 | |
|         rbranch="$(git_get_branch_rbranch "$branch" "$remote")"
 | |
|         pbranch="${rbranch#refs/remotes/}"
 | |
|         if git merge -q --ff-only "$rbranch"; then
 | |
|             echo "* There are uncommitted local changes: only CURRENT branch were updated"
 | |
|         fi
 | |
|         return 0
 | |
|     fi
 | |
| 
 | |
|     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")"
 | |
|         pbranch="${rbranch#refs/remotes/}"
 | |
|         [ -n "$remote" -a -n "$rbranch" ] || continue
 | |
|         if git_is_ancestor "$branch" "$rbranch"; then
 | |
|             if git_should_ff "$branch" "$rbranch"; then
 | |
|                 echo "* Fast-forwarding $branch -> $pbranch"
 | |
|                 git checkout -q "$branch"
 | |
|                 git merge -q --ff-only "$rbranch"
 | |
|                 restore_branch=1
 | |
|             fi
 | |
|         else
 | |
|             if [ "$branch" == "$orig_branch" ]; then
 | |
|                 echo "* Cannot fast-forward CURRENT branch $branch from $pbranch
 | |
| Try to merge manually with: git merge $pbranch"
 | |
|             else
 | |
|                 echo "* Cannot fast-forward local branch $branch from $pbranch
 | |
| You can merge manually with: git checkout $branch; git merge $pbranch"
 | |
|             fi
 | |
|         fi
 | |
|     done
 | |
|     if [ -n "$restore_branch" ]; then
 | |
|         [ -n "$clean" ] && estep "rebasculement sur la branche $orig_branch"
 | |
|         git checkout -q "$orig_branch"
 | |
|     fi
 | |
|     return 0
 | |
| }
 | |
| function git_push() {
 | |
|     local all all_branches all_tags auto force args no_annex
 | |
|     parse_opts + "${PRETTYOPTS[@]}" \
 | |
|         -a,--all all=1 \
 | |
|         -b,--branches,--all-branches all_branches=1 \
 | |
|         -t,--tags,--all-tags all_tags=1 \
 | |
|         --auto auto=1 \
 | |
|         -f,--force force=1 \
 | |
|         -n,--no-annex no_annex=1 \
 | |
|         @ args -- "$@" && set -- "${args[@]}" || {
 | |
|         eerror "$args"
 | |
|         return 1
 | |
|     }
 | |
| 
 | |
|     if [ -n "$all" ]; then
 | |
|         # On a demandé à pusher toutes les branches et tous les tags
 | |
|         local r
 | |
|         git push --all ${force:+--force} "$@"; r=$?
 | |
|         if [ $r -eq 0 ]; then
 | |
|             git push --tags ${force:+--force} "$@"; r=$?
 | |
|         fi
 | |
|         return $r
 | |
|     elif [ -n "$all_branches" ]; then
 | |
|         # On a demandé à pusher toutes les branches
 | |
|         git push --all ${force:+--force} "$@"
 | |
|         return $?
 | |
|     elif [ -n "$all_tags" ]; then
 | |
|         # On a demandé à pusher tous les tags
 | |
|         git push --tags ${force:+--force} "$@"
 | |
|         return $?
 | |
|     elif [ $# -gt 0 ]; then
 | |
|         # Sinon, si des arguments sont spécifiés, les passer à git sans
 | |
|         # modification
 | |
|         git push ${force:+--force} "$@"
 | |
|         return $?
 | |
|     elif git_have_annex; then
 | |
|         # Si une annexe existe dans le dépôt, demander à git-annex de faire la
 | |
|         # synchronisation, sauf si --no-annex est spécifié ou si on est en mode
 | |
|         # automatique
 | |
|         if [ -z "$no_annex" -a -z "$auto" ]; then
 | |
|             git annex sync
 | |
|             return $?
 | |
|         fi
 | |
|     fi
 | |
| 
 | |
|     # sinon on push vers origin. vérifier la présence du remote
 | |
|     [ -n "$(git config --get remote.origin.url)" ] || {
 | |
|         if [ -n "$auto" ]; then
 | |
|             # en mode automatique, ignorer l'absence de remote
 | |
|             return 0
 | |
|         else
 | |
|             eerror "Aucun remote origin n'est défini"
 | |
|             return 1
 | |
|         fi
 | |
|     }
 | |
| 
 | |
|     # puis calculer la branche à pusher
 | |
|     local branch="$(git rev-parse --abbrev-ref HEAD 2>/dev/null)"
 | |
|     local origin="$(git config --get "branch.$branch.remote")"
 | |
|     if [ -n "$branch" -a "$origin" == origin ]; then
 | |
|         if [ -n "$auto" ]; then
 | |
|             # en mode automatique, ne pousser que la branche courante
 | |
|             git push "$origin" "$branch" || return
 | |
|         else
 | |
|             # utiliser la configuration par défaut, qui est sous debian squeeze
 | |
|             # de pousser toutes les branches
 | |
|             git push || return
 | |
|         fi
 | |
|     elif [ -n "$force" ]; then
 | |
|         # utiliser la configuration par défaut, qui est sous debian squeeze de
 | |
|         # pousser toutes les branches
 | |
|         git push || return
 | |
|     fi
 | |
|     return 0
 | |
| }
 | |
| function git_diff() {
 | |
|     local dummy cached args
 | |
|     parse_opts + "${PRETTYOPTS[@]}" \
 | |
|         -l dummy \
 | |
|         -c cached \
 | |
|         -r: '$_vcs_unsupported -r' \
 | |
|         -R '$_vcs_unsupported -R' \
 | |
|         @ args -- "$@" && set -- "${args[@]}" || {
 | |
|         eerror "$args"
 | |
|         return 1
 | |
|     }
 | |
| 
 | |
|     git diff ${cached:+--cached} "$@"
 | |
| }
 | |
| function git_tag() {
 | |
|     _vcs_unsupported tag #XXX
 | |
| }
 | |
| 
 | |
| # Fonctions avancées de git
 | |
| __VCS_GIT_ADVANCED_MAP=(
 | |
|     cg:git_check_gitvcs eg:git_ensure_gitvcs
 | |
|     lbs:git_list_branches rbs:git_list_rbranches
 | |
|     hlb:git_have_branch hrb:git_have_rbranch
 | |
|     gb:git_get_branch ib:git_is_branch
 | |
|     hr:git_have_remote tb:git_track_branch
 | |
|     cc:git_check_cleancheckout ec:git_ensure_cleancheckout
 | |
|     ia:git_is_ancestor sff:git_should_ff spu:git_should_push
 | |
|     im:git_is_merged
 | |
| )
 | |
| __VCS_GIT_ADVANCED=(
 | |
|     git_check_gitvcs git_ensure_gitvcs
 | |
|     git_list_branches git_list_rbranches
 | |
|     git_have_branch git_have_rbranch
 | |
|     git_get_branch git_is_branch
 | |
|     git_have_remote git_track_branch
 | |
|     git_check_cleancheckout git_ensure_cleancheckout
 | |
|     git_is_ancestor git_should_ff git_should_push
 | |
|     git_is_merged
 | |
| )
 | |
| function git_check_gitvcs() {
 | |
|     git rev-parse --show-toplevel >&/dev/null
 | |
| }
 | |
| function git_ensure_gitvcs() {
 | |
|     git_check_gitvcs || die "Ce n'est pas un dépôt git"
 | |
| }
 | |
| function git_list_branches() {
 | |
|     git for-each-ref refs/heads/ --format='%(refname:short)' | csort
 | |
| }
 | |
| function git_list_rbranches() {
 | |
|     git for-each-ref "refs/remotes/${1:-origin}/" --format='%(refname:short)' | csort
 | |
| }
 | |
| function git_list_pbranches() {
 | |
|     # lister les branches locales et celles qui existent dans l'origine
 | |
|     # $1(=origin) et qui pourraient devenir une branche locale avec la commande
 | |
|     # git checkout -b
 | |
|     local prefix="${1:-origin}/"
 | |
|     {
 | |
|         git for-each-ref refs/heads/ --format='%(refname:short)'
 | |
|         git for-each-ref "refs/remotes/$prefix" --format='%(refname:short)' | grep -F "$prefix" | cut -c $((${#prefix} + 1))-
 | |
|     } | grep -vF HEAD | csort -u
 | |
| }
 | |
| function git_have_branch() {
 | |
|     git_list_branches | grep -qF "$1"
 | |
| }
 | |
| function git_have_rbranch() {
 | |
|     git_list_rbranches "${2:-origin}" | grep -qF "$1"
 | |
| }
 | |
| 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}" ]
 | |
| }
 | |
| function git_have_remote() {
 | |
|     [ -n "$(git config --get remote.${1:-origin}.url)" ]
 | |
| }
 | |
| function git_track_branch() {
 | |
|     local branch="$1" origin="${2:-origin}"
 | |
|     [ -n "$branch" ] || return
 | |
|     git_have_remote "$origin" || return
 | |
|     [ "$(git config --get branch.$branch.remote)" == "$origin" ] && return
 | |
|     if git_have_rbranch "$branch" "$origin"; then
 | |
|         if git_have_branch "$branch"; then
 | |
|             local version="$(LANG=C git version)"
 | |
|             version="${version#git version }"
 | |
|             eval "version=(${version//./ })"
 | |
|             if [ ${version[0]} -le 1 -a ${version[1]} -le 7 ]; then
 | |
|                 git branch -t --set-upstream "$branch" "$origin/$branch"
 | |
|             else
 | |
|                 git branch -u "$origin/$branch" "$branch"
 | |
|             fi
 | |
|         else
 | |
|             git branch -t "$branch" "$origin/$branch"
 | |
|         fi
 | |
|     elif git_have_branch "$branch"; then
 | |
|         git push -u "$origin" "$branch" || return
 | |
|     fi
 | |
| }
 | |
| function git_ensure_branch() {
 | |
|     # retourner 0 si la branche a été créée, 1 si elle existait déjà, 2 en cas d'erreur
 | |
|     local branch="$1" source="${2:-master}" origin="${3:-origin}"
 | |
|     [ -n "$branch" ] || return 2
 | |
|     git_have_branch "$branch" && return 1
 | |
|     if git_have_rbranch "$branch" "$origin"; then
 | |
|         # une branche du même nom existe dans l'origine. faire une copie de cette branche
 | |
|         git branch -t "$branch" "$origin/$branch" || return 2
 | |
|     else
 | |
|         # créer une nouvelle branche du nom spécifié
 | |
|         git_have_branch "$source" || return 2
 | |
|         git branch "$branch" "$source" || return 2
 | |
|         if [ -z "$UTOOLS_VCS_OFFLINE" ]; then
 | |
|             git_have_remote "$origin" && git_track_branch "$branch" "$origin"
 | |
|         fi
 | |
|     fi
 | |
|     return 0
 | |
| }
 | |
| function git_check_cleancheckout() {
 | |
|     # vérifier qu'il n'y a pas de modification locales dans le dépôt
 | |
|     # correspondant au répertoire courant.
 | |
|     [ -z "$(git status --porcelain 2>/dev/null)" ]
 | |
| }
 | |
| function git_ensure_cleancheckout() {
 | |
|     git_check_cleancheckout || die "Vous avez des modifications locales. Enregistrez ces modifications avant de continuer"
 | |
| }
 | |
| 
 | |
| function __git_init_ff() {
 | |
|     o="${3:-origin}"
 | |
|     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
 | |
| }
 | |
| function __git_can_ff() {
 | |
|     [ "$1" == "$(git merge-base "$1" "$2")" ]
 | |
| }
 | |
| function git_is_ancestor() {
 | |
|     # vérifier que la branche $1 est un ancêtre direct de la branche $2, qui
 | |
|     # 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 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" "$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 "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 refs/remotes/origin/$1
 | |
|     local o b s; __git_init_ff "$@" || return
 | |
|     [ "$b" != "$s" ] || return 1
 | |
|     local head="$(git rev-parse HEAD)"
 | |
|     [ "$head" == "$b" ] || return 1
 | |
|     __git_can_ff "$b" "$s" || return 1
 | |
|     git merge --ff-only "$s"
 | |
| }
 | |
| 
 | |
| function git_is_merged() {
 | |
|     # vérifier que les branches $1 et $2 ont un ancêtre commun, et que la
 | |
|     # branche $1 a été complètement fusionnée dans la branche destination $2
 | |
|     local b="$1" d="$2"
 | |
|     b="$(git rev-parse --verify --quiet "$b")" || return 1
 | |
|     d="$(git rev-parse --verify --quiet "$d")" || return 1
 | |
|     [ -n "$(git merge-base "$b" "$d")" ] || return 1
 | |
|     [ -z "$(git rev-list "$d..$b")" ]
 | |
| }
 | |
| 
 | |
| # fonctions pour git annex
 | |
| function git_annex_use_ssh_wrapper() {
 | |
|     __UTOOLS_FORCE_PATH="$PATH"
 | |
|     __UTOOLS_FORCE_SSH="${GIT_SSH:-ssh}"
 | |
|     export __UTOOLS_FORCE_PATH __UTOOLS_FORCE_SSH
 | |
|     udelpath "$ULIBDIR/support/ssh-wrapper" __UTOOLS_FORCE_PATH
 | |
|     uinspath "$ULIBDIR/support/ssh-wrapper" PATH
 | |
| }
 | |
| 
 | |
| function git_annex_initial() {
 | |
|     # sur le dépôt $1 fraichement cloné, vérifier s'il faut faire git annex
 | |
|     # init. Si oui, l'initialiser avec le nom d'hôte, et récupérer tous les
 | |
|     # fichiers annexés
 | |
|     # retourner 1 si une erreur s'est produite
 | |
|     local repodir="${1:-.}"
 | |
|     [ -d "$repodir" ] || return 1
 | |
|     repodir="$(abspath "$repodir")"
 | |
| 
 | |
|     local GIT_DIR GIT_WORK_TREE
 | |
|     [ "$(cd "$repodir"; git rev-parse --is-bare-repository)" == false ] || return 0
 | |
|     [ -n "$(GIT_DIR="$repodir/.git" git config --get annex.uuid)" ] && return 0
 | |
| 
 | |
|     # ici, on sait que git annex n'a pas encore été configuré
 | |
|     # vérifier s'il existe des fichiers annexés
 | |
|     local -a links
 | |
|     array_from_lines links "$(find "$repodir" -type l)"
 | |
|     local link hasannex=
 | |
|     for link in "${links[@]}"; do
 | |
|         link="$(readlink "$link")"
 | |
|         if [ "${link#.git/annex/}" != "$link" ]; then
 | |
|             hasannex=1
 | |
|             break
 | |
|         elif [[ "$link" == */.git/annex/* ]]; then
 | |
|             hasannex=1
 | |
|             break
 | |
|         fi
 | |
|     done
 | |
| 
 | |
|     if [ -n "$hasannex" ]; then
 | |
|         progexists git-annex || {
 | |
|             eerror "Vous devez installer git-annex"
 | |
|             return 1
 | |
|         }
 | |
|         (cd "$repodir"
 | |
|             git annex init "$MYHOSTNAME" &&
 | |
|             git annex get &&
 | |
|             git annex sync
 | |
|         ) || return 1
 | |
|     fi
 | |
| }
 | |
| 
 | |
| ################################################################################
 | |
| # Subversion
 | |
| 
 | |
| function svn_getrepos() {
 | |
|     LANG=C svn info "${@:-.}" | awk '/^Repository Root: / { print substr($0, 18) }'
 | |
| }
 | |
| function svn_geturl() {
 | |
|     LANG=C svn info "${@:-.}" | awk '/^URL: / { print substr($0, 6) }'
 | |
| }
 | |
| function svn_add() {
 | |
|     svn add "$@"
 | |
| }
 | |
| function svn_remove() {
 | |
|     svn delete "$@"
 | |
| }
 | |
| function svn_copy() {
 | |
|     svn copy --parents "$@"
 | |
| }
 | |
| function svn_move() {
 | |
|     svn move --parents "$@"
 | |
| }
 | |
| function svn_mkdir() {
 | |
|     svn mkdir --parents "$@"
 | |
| }
 | |
| function svn_commit() {
 | |
|     local dummy args
 | |
|     parse_opts + "${PRETTYOPTS[@]}" \
 | |
|         -a,--all dummy \
 | |
|         -A,--all-new '$_vcs_unsupported -A' \
 | |
|         -c,--cached '$_vcs_unsupported -c' \
 | |
|         -p,--push dummy \
 | |
|         -l,--local '$_vcs_unsupported -l' \
 | |
|         @ args -- "$@" && set -- "${args[@]}" || {
 | |
|         eerror "$args"
 | |
|         return 1
 | |
|     }
 | |
| 
 | |
|     local message="$1"; shift
 | |
|     local -a cmd
 | |
|     cmd=(svn commit)
 | |
|     [ -n "$message" ] && cmd=("${cmd[@]}" -m "$message")
 | |
|     cmd=("${cmd[@]}" "${@:-.}")
 | |
|     "${cmd[@]}"
 | |
| }
 | |
| function svn_status() {
 | |
|     svn status "$@"
 | |
| }
 | |
| function svn_update() {
 | |
|     local ignore_externals args
 | |
|     parse_opts + "${PRETTYOPTS[@]}" \
 | |
|         -x ignore_externals \
 | |
|         @ args -- "$@" && set -- "${args[@]}" || {
 | |
|         eerror "$args"
 | |
|         return 1
 | |
|     }
 | |
| 
 | |
|     svn update ${ignore_externals:+--ignore-externals} "$@"
 | |
| }
 | |
| function svn_push() {
 | |
|     local args
 | |
|     parse_opts + "${PRETTYOPTS[@]}" \
 | |
|         @ args -- "$@" && set -- "${args[@]}" || {
 | |
|         eerror "$args"
 | |
|         return 1
 | |
|     }
 | |
| }
 | |
| function svn_diff() {
 | |
|     local dummy revision args tmpfile0 tmpfile
 | |
|     parse_opts + "${PRETTYOPTS[@]}" \
 | |
|         -l dummy \
 | |
|         -r: revision \
 | |
|         -c '$_vcs_unsupported -c' \
 | |
|         -R '$_vcs_unsupported -R' \
 | |
|         @ args -- "$@" && set -- "${args[@]}" || {
 | |
|         eerror "$args"
 | |
|         return 1
 | |
|     }
 | |
| 
 | |
|     ac_set_tmpfile tmpfile0
 | |
|     ac_set_tmpfile tmpfile
 | |
|     LANG=C svn status 2>/dev/null | awk '/^$/ { next } /^(M|X|Performing status on external item at)/ { next } { print }' >"$tmpfile0"
 | |
|     if [ -s "$tmpfile0" ]; then
 | |
|         echo "Fichiers non modifiés dans un état spécial:" >>"$tmpfile"
 | |
|         cat "$tmpfile0" >>"$tmpfile"
 | |
|         echo "===================================================================" >>"$tmpfile"
 | |
|     fi
 | |
|     ac_clean "$tmpfile0"
 | |
| 
 | |
|     svn diff -x -u ${revision:+-r "$revision"} "$@" >>"$tmpfile"
 | |
| 
 | |
|     if [ -s "$tmpfile" ]; then
 | |
|         "${PAGER:-less}" "$tmpfile"
 | |
|         ac_clean "$tmpfile"
 | |
|         return 0
 | |
|     else
 | |
|         einfo "Aucune différence détectée"
 | |
|         ac_clean "$tmpfile"
 | |
|         return 1
 | |
|     fi
 | |
| }
 | |
| function svn_tag() {
 | |
|     _vcs_unsupported tag #XXX
 | |
| }
 | |
| 
 | |
| ################################################################################
 | |
| # CVS
 | |
| 
 | |
| function cvs_getrepos() {
 | |
|     _vcs_unsupported getrepos
 | |
| }
 | |
| function cvs_geturl() {
 | |
|     _vcs_unsupported geturl
 | |
| }
 | |
| function cvs_add() {
 | |
|     cvs add "$@"
 | |
| }
 | |
| function cvs_remove() {
 | |
|     rm "$@"
 | |
|     cvs remove "$@"
 | |
| }
 | |
| 
 | |
| function cvs_copy() {
 | |
|     _vcs_check_nbargs $# 2 2 || return
 | |
|     local src="$1" dest="$2"
 | |
|     if [ -d "$dest" ]; then
 | |
|         # copie d'un fichier vers un répertoire
 | |
|         cp "$src" "$dest" || return
 | |
|         cvs add "$dest/$(basename "$src")"
 | |
|     elif [ -f "$src" ]; then
 | |
|         # copie d'un fichier vers un fichier
 | |
|         cp "$src" "$dest" || return
 | |
|         cvs add "$dest"
 | |
|     else
 | |
|         _vcs_invalid_copy
 | |
|         return 1
 | |
|     fi
 | |
| }
 | |
| function cvs_move() {
 | |
|     _vcs_check_nbargs $# 2 2 || return
 | |
|     local src="$1" dest="$2"
 | |
|     if [ -d "$dest" ]; then
 | |
|         # copie d'un fichier vers un répertoire
 | |
|         mv "$src" "$dest" || return
 | |
|         cvs remove "$src"
 | |
|         cvs add "$dest/$(basename "$src")"
 | |
|     elif [ -f "$src" ]; then
 | |
|         # copie d'un fichier vers un fichier
 | |
|         mv "$src" "$dest" || return
 | |
|         cvs remove "$src"
 | |
|         cvs add "$dest"
 | |
|     else
 | |
|         _vcs_invalid_copy
 | |
|         return 1
 | |
|     fi
 | |
| }
 | |
| function cvs_mkdir() {
 | |
|     mkdir -p "$@"
 | |
|     cvs add "$@"
 | |
| }
 | |
| function cvs_commit() {
 | |
|     local dummy args
 | |
|     parse_opts + "${PRETTYOPTS[@]}" \
 | |
|         -a,--all dummy \
 | |
|         -A,--all-new '$_vcs_unsupported -A' \
 | |
|         -c,--cached '$_vcs_unsupported -c' \
 | |
|         -p,--push dummy \
 | |
|         -l,--local '$_vcs_unsupported -l' \
 | |
|         @ args -- "$@" && set -- "${args[@]}" || {
 | |
|         eerror "$args"
 | |
|         return 1
 | |
|     }
 | |
| 
 | |
|     local message="$1"; shift
 | |
|     local -a cmd
 | |
|     cmd=(cvs commit)
 | |
|     [ -n "$message" ] && cmd=("${cmd[@]}" -m "$message")
 | |
|     cmd=("${cmd[@]}" "${@:-.}")
 | |
|     "${cmd[@]}"
 | |
| }
 | |
| function cvs_status() {
 | |
|     cvs update "$@"
 | |
| }
 | |
| function cvs_update() {
 | |
|     local dummy args
 | |
|     parse_opts + "${PRETTYOPTS[@]}" \
 | |
|         -x dummy \
 | |
|         @ args -- "$@" && set -- "${args[@]}" || {
 | |
|         eerror "$args"
 | |
|         return 1
 | |
|     }
 | |
| 
 | |
|     cvs update "$@"
 | |
| }
 | |
| function cvs_push() {
 | |
|     local args
 | |
|     parse_opts + "${PRETTYOPTS[@]}" \
 | |
|         @ args -- "$@" && set -- "${args[@]}" || {
 | |
|         eerror "$args"
 | |
|         return 1
 | |
|     }
 | |
| }
 | |
| function cvs_diff() {
 | |
|     local dummy revision args tmpfile
 | |
|     parse_opts + "${PRETTYOPTS[@]}" \
 | |
|         -l dummy \
 | |
|         -r: revision \
 | |
|         -c '$_vcs_unsupported -c' \
 | |
|         -R '$_vcs_unsupported -R' \
 | |
|         @ args -- "$@" && set -- "${args[@]}" || {
 | |
|         eerror "$args"
 | |
|         return 1
 | |
|     }
 | |
|     ac_set_tmpfile tmpfile
 | |
|     cvs diff -u ${revision:+-r "$revision"} "$@" >"$tmpfile"
 | |
| 
 | |
|     if [ -s "$tmpfile" ]; then
 | |
|         "${PAGER:-less}" "$tmpfile"
 | |
|         ac_clean "$tmpfile"
 | |
|         return 0
 | |
|     else
 | |
|         ac_clean "$tmpfile"
 | |
|         einfo "Aucune différence détectée"
 | |
|         return 1
 | |
|     fi
 | |
| }
 | |
| function cvs_tag() {
 | |
|     local cwd rootdir
 | |
|     cwd="$(pwd)"
 | |
|     rootdir="$(__vcs_find_root "$cwd")"
 | |
|     cvs tag "$1" "$(relpath "$rootdir" "$cwd")"
 | |
| }
 |