2018-04-26 23:19:17 +04:00
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
##@cooked nocomments
##@require nulib.sh
##@require base
module: git "" "Fonctions pour faciliter l'utilisation de git"
2018-09-25 14:49:58 +04:00
require: nulib base
2018-04-26 23:19:17 +04:00
function : git_geturl ""
function git_geturl( ) {
git config --get remote.origin.url
}
function : git_have_annex ""
function git_have_annex( ) {
[ -n " $( git config --get annex.uuid) " ]
}
NULIB_GIT_FUNCTIONS = (
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
)
NULIB_GIT_FUNCTIONS_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
)
function : git_check_gitvcs ""
function git_check_gitvcs( ) {
git rev-parse --show-toplevel >& /dev/null
}
function : git_ensure_gitvcs ""
function git_ensure_gitvcs( ) {
git_check_gitvcs || edie "Ce n'est pas un dépôt git" || return
}
function : git_list_branches ""
function git_list_branches( ) {
git for -each-ref refs/heads/ --format= '%(refname:short)' | csort
}
function : git_list_rbranches ""
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"
function git_list_pbranches( ) {
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 ""
function git_have_branch( ) {
git_list_branches | grep -qF " $1 "
}
function : git_have_rbranch ""
function git_have_rbranch( ) {
git_list_rbranches " ${ 2 :- origin } " | grep -qF " $1 "
}
function : git_get_branch ""
function git_get_branch( ) {
git rev-parse --abbrev-ref HEAD 2>/dev/null
}
function : git_get_branch_remote ""
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 ""
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 ""
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 ""
function git_is_branch( ) {
[ " $( git_get_branch) " = = " ${ 1 :- master } " ]
}
function : git_have_remote ""
function git_have_remote( ) {
[ -n " $( git config --get remote.${ 1 :- origin } .url) " ]
}
function : git_track_branch ""
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
git branch -u " $origin / $branch " " $branch "
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 "
@return 0 si la branche a été créée, 1 si elle existait déjà, 2 en cas d' erreur"
function git_ensure_branch( ) {
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 " $NULIB_GIT_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."
function git_check_cleancheckout( ) {
[ -z " $( git status --porcelain 2>/dev/null) " ]
}
function : git_ensure_cleancheckout ""
function git_ensure_cleancheckout( ) {
git_check_cleancheckout ||
edie "Vous avez des modifications locales. Enregistrez ces modifications avant de continuer" || return
}
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"
function git_is_ancestor( ) {
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"
function git_should_ff( ) {
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."
function git_should_push( ) {
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"
function git_fast_forward( ) {
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"
function git_is_merged( ) {
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 " ) " ]
}
################################################################################
# git annex
NULIB_GIT_SSH_WRAPPER =
function : git_annex_use_ssh_wrapper ""
function git_annex_use_ssh_wrapper( ) {
[ -n " $NULIB_GIT_SSH_WRAPPER " ] && return
NULIB_GIT_FORCE_PATH = " $PATH "
NULIB_GIT_FORCE_SSH = " ${ GIT_SSH :- ssh } "
export NULIB_GIT_FORCE_PATH NULIB_GIT_FORCE_SSH
base_delpath " $NULIBDIR /ssh-wrapper " NULIB_GIT_FORCE_PATH
base_inspath " $NULIBDIR /ssh-wrapper " PATH
NULIB_GIT_SSH_WRAPPER = 1
}
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
@return 1 si une erreur s' est produite"
function git_annex_initial( ) {
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
base_array_splitl 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
base_in_path git-annex || edie "Vous devez installer git-annex" || return
local cwd; base_push_cwd " $repodir " &&
git annex init " $MYHOSTNAME " &&
git annex get &&
git annex sync &&
base_pop_cwd || base_pop_cwd 1 || return
fi
}
################################################################################
# Outils de haut niveau
function : git_commit ""
function git_commit( ) {
local all = auto allnew push = auto nopush args
setyesval nopush " $NULIB_GIT_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 | lawk '
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_update ""
function git_update( ) {
local args autoff = 1
parse_opts + " ${ PRETTYOPTS [@] } " \
-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
base_array_splitl prbranches " $( git_list_rbranches) "
git fetch -p " $@ " || return
base_array_splitl 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 ! base_array_contains crbranches " $branch " ; then
base_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
base_array_del dbranches " $branch "
fi
fi
done
fi
if [ ${# dbranches [*] } -gt 0 ] ; then
base_array_splitl branches " $( git_list_branches) "
branch = " $( git_get_branch) "
if base_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 " ] && base_array_contains branches develop && ! base_array_contains dbranches develop; then
swto = develop
fi
if [ -z " $swto " ] && base_array_contains branches master && ! base_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
orig_branch = " $( git_get_branch) "
base_array_splitl 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
[ -n " $restore_branch " ] && git checkout -q " $orig_branch "
return 0
}
function : git_push ""
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 " $@ " ; r = $?
if [ $r -eq 0 ] ; then
git push --tags " $@ " ; r = $?
fi
return $r
elif [ -n " $all_branches " ] ; then
# On a demandé à pusher toutes les branches
git push --all " $@ "
return $?
elif [ -n " $all_tags " ] ; then
# On a demandé à pusher tous les tags
git push --tags " $@ "
return $?
elif [ $# -gt 0 ] ; then
# Sinon, si des arguments sont spécifiés, les passer à git sans
# modification
git push " $@ "
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__pclone( ) {
estep " $1 --> $( ppath " $2 " ) "
mkdirof " $2 " || return 1
git clone " $1 " " $2 " || return 1
if [ -z " $3 " ] ; then
(
cd " $2 "
if git_have_rbranch develop; then
git checkout develop || exit 1
fi
) || return 1
fi
git_annex_initial " $2 " || return 1
}
function git__gitolite_info( ) {
local mode = " $1 " urlbase = " $2 " pattern = " $3 "
case " $mode " in
http) curl -fs " $urlbase /info ${ pattern : + " ? $pattern " } " ; ;
ssh) ssh -q " $urlbase " info ${ pattern : + " $pattern " } 2>/dev/null; ;
esac
}
function git__filter_repos( ) {
lawk -v prefix = " $1 " '
NR <= 2 { next }
{
# filtrer les projets qui ne sont pas encore créés
if ( substr( $0 , 5, 2) = = " C" ) next
repo = substr( $0 , 6)
# filtrer les projets de type wildcard
if ( repo ~ /[ \[ \] \* ] /) next
# enlever le prefixe
if ( prefix != "" && substr( repo, 1, length( prefix) ) != prefix) next
print repo
} '
}
function : git_clone ""
function git_clone( ) {
no_clone =
update =
nodevelop =
recursive =
parse_opts " ${ PRETTYOPTS [@] } " \
-n,--no-clone no_clone = 1 \
-u,--update update = 1 \
-m,--master nodevelop = 1 \
-r,--recursive recursive = 1 \
@ args -- " $@ " && set -- " ${ args [@] } " || edie " $args " || return
if [ -n " $recursive " ] ; then
repobase = " $1 "
[ -n " $repobase " ] || edie "Vous devez spécifier l'url de base des dépôts à cloner" || return
if [ " ${ repobase #http : // } " != " $repobase " -o " ${ repobase #https : // } " != " $repobase " ] ; then
# accès par http
mode = http
splitfsep " $repobase " :// scheme hostuserpath
splitfsep " $hostuserpath " / host userpath
splitfsep " $userpath " / user basepath
[ -n " $host " -a -n " $user " ] || edie "Vous devez spécifier l'hôte e.g http://host/git/basepath" || return
urlbase = " $scheme :// $host / $user "
else
# accès par ssh
mode = ssh
splitfsep " $repobase " : userhost basepath
splituserhost " $userhost " user host
[ -n " $user " ] || user = git
[ -n " $host " ] || edie "Vous devez spécifier l'hôte" || return
urlbase = " $user @ $host "
fi
basepath = " ${ basepath %/ } "
destbase = " ${ 2 :- . } "
git_annex_use_ssh_wrapper
prefix = " ${ basepath : + $basepath / } "
base_array_splitl repos " $( set -o pipefail; git__gitolite_info " $mode " " $urlbase " " $prefix " | git__filter_repos " $prefix " ) " || edie || return
for repo in " ${ repos [@] } " ; do
case " $mode " in
http) repourl = " $urlbase / $repo " ; ;
ssh) repourl = " $urlbase : $repo " ; ;
esac
setx destdir = abspath " $destbase / ${ repo # $prefix } "
if [ -d " $destdir " ] ; then
if [ -n " $update " ] ; then
(
${ no_clone : +qvals } cd " $destdir "
${ no_clone : +qvals } git pull
) || edie || return
else
estepe " $( ppath2 " $destdir " ) : répertoire existant "
fi
elif [ -n " $no_clone " ] ; then
qvals git clone " $repourl " " $destdir "
else
git__pclone " $repourl " " $destdir " " $nodevelop " || edie || return
fi
done
else
repourl = " ${ 1 %.git } "
[ -n " $repourl " ] || edie "Vous devez spécifier l'url du dépôt git" || return
destdir = " $2 "
if [ -z " $destdir " ] ; then
splitfsep " $repourl " : userhost path
setx destdir = basename -- " $path "
destdir = " ${ destdir %.git } "
fi
setx destdir = abspath " $destdir "
git_annex_use_ssh_wrapper
if [ -d " $destdir " ] ; then
if [ -n " $update " ] ; then
(
${ no_clone : +qvals } cd " $destdir "
${ no_clone : +qvals } git pull
) || edie || return
else
estepe " $( ppath2 " $destdir " ) : répertoire existant "
fi
elif [ -n " $no_clone " ] ; then
qvals git clone " $repourl " " $destdir "
else
git__pclone " $repourl " " $destdir " " $nodevelop " || edie || return
fi
fi
}
function : git_crone ""
function git_crone( ) {
repourl = " ${ 1 %.git } "
[ -n " $repourl " ] || edie "Vous devez spécifier l'url du dépôt git" || return
if [ " ${ repourl #http : // } " != " $repourl " -o " ${ repourl #https : // } " != " $repourl " ] ; then
# accès par http
mode = http
splitfsep " $repourl " :// scheme hostuserpath
splitfsep " $hostuserpath " / host userpath
splitfsep " $userpath " / user path
[ -n " $host " -a -n " $user " ] || edie "Vous devez spécifier l'hôte e.g http://host/git/repo" || return
hostuser = " $scheme :// $host / $user "
else
# accès par ssh
mode = ssh
splitfsep " $repourl " : userhost path
splituserhost " $userhost " user host
[ -n " $user " ] || user = git
[ -n " $host " ] || edie "Vous devez spécifier l'hôte" || return
userhost = " $user @ $host "
fi
[ -n " $path " ] || edie "Vous devez spécifier le chemin du dépôt git" || return
destdir = " $2 "
if [ -z " $destdir " ] ; then
setx destdir = basename -- " $path "
destdir = " ${ destdir %.git } "
fi
tmpdestdir =
if [ -d " $destdir " ] ; then
[ -d " $destdir /.git " ] && edie " $( ppath2 " $destdir " ) : un dépôt existe déjà " || return
ac_set_tmpdir tmpdestdir
fi
if [ " $mode " = = http ] ; then
setx result = curl -fs " $hostuser /create? $path " || edie || return
echo " $result "
[ [ " $result " = = FATAL:* ] ] && edie || return
if [ -n " $tmpdestdir " ] ; then
setxx destname = abspath " $destdir " // basename
git clone " $hostuser / $path " " $tmpdestdir / $destname " || edie || return
mv " $tmpdestdir / $destname /.git " " $destdir " || edie || return
ac_clean " $tmpdestdir "
else
git clone " $hostuser / $path " " $destdir " || edie || return
fi
elif [ " $mode " = = ssh ] ; then
git_annex_use_ssh_wrapper
ssh " $userhost " create " $path " || edie || return
if [ -n " $tmpdestdir " ] ; then
setxx destname = abspath " $destdir " // basename
git clone " $userhost : $path " " $tmpdestdir / $destname " || edie || return
mv " $tmpdestdir / $destname /.git " " $destdir " || edie || return
ac_clean " $tmpdestdir "
else
git clone " $userhost : $path " " $destdir " || edie || return
fi
else
edie " $mode : mode non supporté " || return
fi
git_annex_initial " $destdir " || edie || return
}