383 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			383 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
| #!/bin/bash
 | |
| # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
 | |
| source "$(dirname -- "$0")/../load.sh" || exit 1
 | |
| require: git pman pman.conf
 | |
| 
 | |
| git_cleancheckout_DIRTY="\
 | |
| Vous avez des modifications locales.
 | |
| Enregistrez ces modifications avant de fusionner la branche"
 | |
| 
 | |
| function _merge_action() {
 | |
|     enote "\
 | |
| Ce script va
 | |
| - fusionner la branche ${COULEUR_BLEUE}$MergeSrc${COULEUR_NORMALE} dans ${COULEUR_ROUGE}$MergeDest${COULEUR_NORMALE}${Push:+
 | |
| - pousser les branches modifiées}"
 | |
|     ask_yesno "Voulez-vous continuer?" O || die
 | |
| 
 | |
|     local script=".git/pman-merge.sh"
 | |
|     local -a push_branches delete_branches
 | |
|     local hook
 | |
|     local comment=
 | |
|     local or_die=" || exit 1"
 | |
| 
 | |
|     _mscript_start
 | |
|     _scripta <<EOF
 | |
| ################################################################################
 | |
| # merge
 | |
| if [ -n "\$merge" ]; then
 | |
| esection "Fusionner la branche"
 | |
| EOF
 | |
|     hook="BEFORE_MERGE_$MERGE_SRC"; [ -n "${!hook}" ] && _scripta <<EOF
 | |
| (
 | |
| ${!hook}
 | |
| )$or_die
 | |
| EOF
 | |
|     _mscript_merge_branch
 | |
|     hook="AFTER_MERGE_$MERGE_SRC"; [ -n "${!hook}" ] && _scripta <<EOF
 | |
| (
 | |
| ${!hook}
 | |
| )$or_die
 | |
| EOF
 | |
|     _scripta <<EOF
 | |
| fi
 | |
| EOF
 | |
| 
 | |
|     if [ -n "$ShouldDelete" ]; then
 | |
|         _scripta <<EOF
 | |
| ################################################################################
 | |
| # delete
 | |
| if [ -n "\$delete" ]; then
 | |
| esection "Supprimer la branche"
 | |
| EOF
 | |
|         _mscript_delete_branch
 | |
|         hook="AFTER_DELETE_$MERGE_SRC"; [ -n "${!hook}" ] && _scripta <<EOF
 | |
| (
 | |
| ${!hook}
 | |
| )$or_die
 | |
| EOF
 | |
|         _scripta <<EOF
 | |
| fi
 | |
| EOF
 | |
|     fi
 | |
| 
 | |
|     _scripta <<EOF
 | |
| ################################################################################
 | |
| # push
 | |
| if [ -n "\$push" ]; then
 | |
| esection "Pousser les branches"
 | |
| EOF
 | |
|     hook="BEFORE_PUSH_$MERGE_DEST"; [ -n "${!hook}" ] && _scripta <<EOF
 | |
| (
 | |
| ${!hook}
 | |
| )$or_die
 | |
| EOF
 | |
|     _script_push_branches
 | |
|     if [ ${#delete_branches[*]} -gt 0 ]; then
 | |
|         _scripta <<<"if [ -n \"\$delete\" ]; then"
 | |
|         push_branches=("${delete_branches[@]}")
 | |
|         _script_push_branches
 | |
|         _scripta <<<fi
 | |
|     fi
 | |
|     hook="AFTER_PUSH_$MERGE_DEST"; [ -n "${!hook}" ] && _scripta <<EOF
 | |
| (
 | |
| ${!hook}
 | |
| )$or_die
 | |
| EOF
 | |
|     _scripta <<EOF
 | |
| fi
 | |
| EOF
 | |
| 
 | |
|     [ -n "$Delete" -o -z "$ShouldDelete" ] && Deleted=1 || Deleted=
 | |
|     [ -n "$ShouldDelete" -a -n "$Delete" ] && ShouldDelete=
 | |
|     [ -n "$ShouldPush" -a -n "$Push" ] && ShouldPush=
 | |
|     if [ -n "$_Fake" ]; then
 | |
|         cat "$script"
 | |
|     elif ! "$script" merge ${Delete:+delete} ${Push:+push}; then
 | |
|         eimportant "\
 | |
| Le script $script a été lancé avec les arguments 'merge${Delete:+ delete}${Push:+ push}'
 | |
| En cas d'erreur de merge, veuillez corriger les erreurs puis continuer avec
 | |
|     git merge --continue
 | |
| Sinon, veuillez consulter le script et/ou le relancer
 | |
|     ./$script${Delete:+ delete}${Push:+ push}"
 | |
|         die
 | |
|     elif [ -n "$Deleted" -a -n "$Push" ]; then
 | |
|         [ -n "$_KeepScript" ] || rm "$script"
 | |
|         [ -n "$AfterMerge" ] && eval "$AfterMerge"
 | |
|     else
 | |
|         local msg="\
 | |
| Le script $script a été lancé avec les arguments 'merge${Delete:+ delete}${Push:+ push}'
 | |
| Vous pouvez consulter le script et/ou le relancer
 | |
|     ./$script${ShouldDelete:+ delete}${ShouldPush:+ push}"
 | |
|         [ -n "$AfterMerge" ] && msg="$msg
 | |
| Il y a aussi les commandes supplémentaires suivantes:
 | |
|     ${AfterMerge//
 | |
| /
 | |
|     }"
 | |
|         einfo "$msg"
 | |
|     fi
 | |
| }
 | |
| 
 | |
| function merge_action() {
 | |
|     [ -n "$REF_UNIQUE" ] || resolve_unique_branch "$@"
 | |
|     ensure_merge_branches -a
 | |
| 
 | |
|     if [ -n "$PREL_MERGE" ]; then
 | |
|         [ -n "$ForceMerge" ] || die "$MergeSrc: cette branche doit être fusionnée dans $MergeDest avec prel"
 | |
|     fi
 | |
|     if [ -n "$DELETE_MERGED" ]; then
 | |
|         ShouldDelete=1
 | |
|         [ -n "$AfterMerge" ] || setx AfterMerge=qvals git checkout -q "$MergeDest"
 | |
|     else
 | |
|         ShouldDelete=
 | |
|         Delete=
 | |
|         [ -n "$AfterMerge" ] || setx AfterMerge=qvals git checkout -q "$MergeSrc"
 | |
|     fi
 | |
|     [ -z "$_Fake" ] && git_ensure_cleancheckout
 | |
| 
 | |
|     if ! array_contains LocalBranches "$MergeSrc" && array_contains AllBranches "$MergeSrc"; then
 | |
|         enote "$MergeSrc: une branche du même nom existe dans l'origine"
 | |
|     fi
 | |
|     if ! array_contains LocalBranches "$MergeDest" && array_contains AllBranches "$MergeDest"; then
 | |
|         enote "$MergeDest: une branche du même nom existe dans l'origine"
 | |
|     fi
 | |
|     array_contains LocalBranches "$MergeSrc" || die "$MergeSrc: branche locale introuvable"
 | |
|     array_contains LocalBranches "$MergeDest" || die "$MergeDest: branche locale introuvable"
 | |
| 
 | |
|     resolve_should_push
 | |
|     _merge_action "$@"
 | |
| }
 | |
| 
 | |
| function rebase_action() {
 | |
|     die "non implémenté"
 | |
| }
 | |
| 
 | |
| ################################################################################
 | |
| 
 | |
| loaded_config=
 | |
| merge_dir=
 | |
| if [ "$MYNAME" == ptool ]; then
 | |
|     if [ "$1" == --help ]; then
 | |
|         exit_with eecho "$MYNAME: gérer les branches d'un projet
 | |
| 
 | |
| USAGE
 | |
|     $MYNAME [-t|-f] REF args...
 | |
| 
 | |
| OPTIONS
 | |
|     REF
 | |
|     -f, --merge-from REF
 | |
|         spécifier la branche de référence et indiquer que la fusion se fait dans
 | |
|         le sens REF --> DEST. DEST est calculé en fonction de REF
 | |
|     -t, --merge-to REF
 | |
|         spécifier la branche de référence et indiquer que la fusion se fait dans
 | |
|         le sens SRC --> REF. SRC est calculé en fonction de REF"
 | |
|     fi
 | |
| 
 | |
|     ref="$1"; shift
 | |
|     merge_dir=to
 | |
|     [ -n "$ref" ] || die "vous spécifier la branche de référence"
 | |
| 
 | |
|     case "$ref" in
 | |
|     -f|--merge-from)
 | |
|         ref="$1"; shift
 | |
|         merge_dir=from
 | |
|         ;;
 | |
|     -f*)
 | |
|         ref="${ref#-f}"
 | |
|         merge_dir=from
 | |
|         ;;
 | |
|     -t|--merge-to)
 | |
|         ref="$1"; shift
 | |
|         merge_dir=to
 | |
|         ;;
 | |
|     -t*)
 | |
|         ref="${ref#-t}"
 | |
|         merge_dir=to
 | |
|         ;;
 | |
|     esac
 | |
|     REF_BRANCH="${ref^^}"
 | |
|     array_contains PMAN_BRANCHES "$REF_BRANCH" || die "$ref: invalid branch"
 | |
| 
 | |
| else
 | |
|     REF_BRANCH="PMAN_TOOL_${MYNAME^^}"; REF_BRANCH="${!REF_BRANCH}"
 | |
| fi
 | |
| 
 | |
| if check_gitdir; then
 | |
|     load_branches all
 | |
|     load_config
 | |
|     set_pman_vars "$merge_dir"
 | |
|     load_branches current
 | |
|     loaded_config=1
 | |
| else
 | |
|     set_pman_vars "$merge_dir"
 | |
| fi
 | |
| 
 | |
| BranchDesc=
 | |
| MergeSrcDesc=
 | |
| MergeDestDesc=
 | |
| if [ -n "$REF_BRANCH" ]; then
 | |
|     BranchDesc="${COULEUR_BLANCHE}<$REF_BRANCH>"
 | |
|     [ -n "$RefBranch" -a -n "$REF_UNIQUE" ] && BranchDesc="$BranchDesc ($RefBranch)"
 | |
|     BranchDesc="$BranchDesc${COULEUR_NORMALE}"
 | |
| fi
 | |
| if [ -n "$MERGE_SRC" ]; then
 | |
|     MergeSrcDesc="${COULEUR_BLEUE}<$MERGE_SRC>"
 | |
|     [ -n "$MergeSrc" -a -n "$REF_UNIQUE" ] && MergeSrcDesc="$MergeSrcDesc ($MergeSrc)"
 | |
|     MergeSrcDesc="$MergeSrcDesc${COULEUR_NORMALE}"
 | |
| fi
 | |
| if [ -n "$MERGE_DEST" ]; then
 | |
|     MergeDestDesc="${COULEUR_ROUGE}<$MERGE_DEST>"
 | |
|     [ -n "$MergeDest" -a -n "$REF_UNIQUE" ] && MergeDestDesc="$MergeDestDesc ($MergeDest)"
 | |
|     MergeDestDesc="$MergeDestDesc${COULEUR_NORMALE}"
 | |
| fi
 | |
| 
 | |
| if [ -n "$REF_UNIQUE" ]
 | |
| then purpose="gérer la branche $BranchDesc"
 | |
| else purpose="gérer les branches $BranchDesc"
 | |
| fi
 | |
| usage="--checkout"
 | |
| variables=
 | |
| 
 | |
| chdir_def=(chdir= "répertoire dans lequel se placer avant de lancer les opérations")
 | |
| origin_def=(Origin= "++origine à partir de laquelle les branches distantes sont considérées")
 | |
| config_branch_def=(ConfigBranch= "++branche à partir de laquelle charger la configuration")
 | |
| config_file_def=(ConfigFile= "++\
 | |
| fichier de configuration des branches. le fichier .pman.conf dans le répertoire
 | |
| du dépôt est utilisé par défaut s'il existe. cette option est prioritaire sur
 | |
| --config-branch")
 | |
| fake_def=(_Fake=1 "++option non documentée")
 | |
| keep_script_def=(_KeepScript=1 "++option non documentée")
 | |
| dump_action_def=(action=dump "++afficher les noms des branches")
 | |
| checkout_action_def=('$:' "++non applicable")
 | |
| show_action_def=('$:' "++non applicable")
 | |
| rebase_action_def=('$:' "++non applicable")
 | |
| merge_action_def=('$:' "++non applicable")
 | |
| tech_merge_def=('$:' "++non applicable")
 | |
| squash_def=('$:' "++non applicable")
 | |
| force_merge_def=('$:' "++non applicable")
 | |
| no_push_def=('$:' "++non applicable")
 | |
| push_def=('$:' "++non applicable")
 | |
| no_delete_def=('$:' "++non applicable")
 | |
| delete_def=('$:' "++non applicable")
 | |
| after_merge_def=('$:' "++non applicable")
 | |
| 
 | |
| if [ -n "$RefBranch" -a -n "$REF_UNIQUE" ]; then
 | |
|     checkout_action_def=(action=checkout "++\
 | |
| créer le cas échéant la branche $BranchDesc et basculer vers elle.
 | |
| c'est l'option par défaut")
 | |
| elif [ -z "$REF_UNIQUE" ]; then
 | |
|     checkout_action_def=(action=checkout "\
 | |
| créer le cas échéant la branche $BranchDesc et basculer vers elle.
 | |
| c'est l'option par défaut")
 | |
| else
 | |
|     checkout_action_def=(action=checkout "\
 | |
| créer la branche $MergeDestDesc et basculer vers elle.
 | |
| c'est l'option par défaut")
 | |
| fi
 | |
| 
 | |
| if [ -n "$MERGE_SRC" -a -n "$MERGE_DEST" ]; then
 | |
|     if [ -n "$REF_UNIQUE" ]
 | |
|     then usage="${usage}|--show|--merge"
 | |
|     else usage="${usage} $REF_BRANCH
 | |
| --show|--merge"
 | |
|     fi
 | |
|     if [ "$REF_BRANCH" != "$MERGE_SRC" ]
 | |
|     then bewareDir="
 | |
| NB: la fusion se fait dans le sens inverse"
 | |
|     else bewareDir=
 | |
|     fi
 | |
|     variables="Les variables supplémentaires suivantes peuvent être définies:
 | |
|     BEFORE_MERGE_${MERGE_SRC}
 | |
|     AFTER_MERGE_${MERGE_SRC}"
 | |
| 
 | |
|     show_action_def=('$action=show; inc@ ShowLevel' "\
 | |
| lister ce qui serait fusionné dans la branche $MergeDestDesc")
 | |
|     rebase_action_def=('$:' "++non implémenté")
 | |
| #    rebase_action_def=(action=rebase "\
 | |
| #lancer git rebase -i sur la branche $MergeSrcDesc. cela permet de réordonner
 | |
| #les commits pour nettoyer l'historique avant la fusion")
 | |
|     merge_action_def=(action=merge "\
 | |
| fusionner la branche $MergeSrcDesc dans la branche $MergeDestDesc$bewareDir")
 | |
|     tech_merge_def=(TechMerge=1 "++option non documentée")
 | |
|     squash_def=(SquashMsg= "fusionner les modifications de la branche comme un seul commit")
 | |
|     [ -n "$PREL_MERGE" ] && force_merge_def=(ForceMerge=1 "++\
 | |
| forcer la fusion pour une branche qui devrait être traitée par prel")
 | |
|     no_push_def=(Push= "ne pas pousser les branches vers leur origine après la fusion")
 | |
|     push_def=(Push=1 "++\
 | |
| pousser les branches vers leur origine après la fusion.
 | |
| c'est l'option par défaut")
 | |
| 
 | |
|     if [ -n "$DELETE_MERGED" ]; then
 | |
|         variables="${variables}
 | |
|     AFTER_DELETE_${MERGE_SRC}"
 | |
|         no_delete_def=(Delete= "\
 | |
| ne pas supprimer la branche $MergeSrcDesc après la fusion dans la branche
 | |
| $MergeDestDesc. cette option ne devrait pas être utilisée avec --squash")
 | |
|         delete_def=(Delete=1 "++\
 | |
| supprimer la branche $MergeSrcDesc après la fusion dans la branche
 | |
| $MergeDestDesc.
 | |
| c'est l'option par défaut")
 | |
|     fi
 | |
| 
 | |
|     [ -n "$MERGE_DEST" ] && variables="${variables}
 | |
|     BEFORE_PUSH_${MERGE_DEST}
 | |
|     AFTER_PUSH_${MERGE_DEST}"
 | |
| 
 | |
|     after_merge_def=(AfterMerge= "évaluer le script spécifié après une fusion *réussie*")
 | |
| fi
 | |
| 
 | |
| chdir=
 | |
| Origin=
 | |
| ConfigBranch=
 | |
| ConfigFile=
 | |
| _Fake=
 | |
| _KeepScript=
 | |
| action=checkout
 | |
| ShowLevel=0
 | |
| TechMerge=
 | |
| SquashMsg=
 | |
| Push=1
 | |
| Delete=1
 | |
| AfterMerge=
 | |
| args=(
 | |
|     "$purpose"
 | |
|     "\
 | |
|  $usage
 | |
| 
 | |
| CONFIGURATION
 | |
| 
 | |
| Le fichier .pman.conf contient la configuration des branches.
 | |
| $variables"
 | |
|     -d:,--chdir:BASEDIR "${chdir_def[@]}"
 | |
|     -O:,--origin "${origin_def[@]}"
 | |
|     -B:,--config-branch "${config_branch_def[@]}"
 | |
|     -c:,--config-file:CONFIG  "${config_file_def[@]}"
 | |
|     --fake "${fake_def[@]}"
 | |
|     --keep-script "${keep_script_def[@]}"
 | |
|     --dump "${dump_action_def[@]}"
 | |
|     --checkout "${checkout_action_def[@]}"
 | |
|     -w,--show "${show_action_def[@]}"
 | |
|     -b,--rebase "${rebase_action_def[@]}"
 | |
|     -m,--merge "${merge_action_def[@]}"
 | |
|     --tech-merge "${tech_merge_def[@]}"
 | |
|     -s:,--squash:COMMIT_MSG "${squash_def[@]}"
 | |
|     -f,--force-merge "${force_merge_def[@]}"
 | |
|     -n,--no-push "${no_push_def[@]}"
 | |
|     --push "${push_def[@]}"
 | |
|     -k,--no-delete "${no_delete_def[@]}"
 | |
|     --delete "${delete_def[@]}"
 | |
|     -a:,--after-merge "${after_merge_def[@]}"
 | |
| )
 | |
| parse_args "$@"; set -- "${args[@]}"
 | |
| 
 | |
| if [ -z "$loaded_config" -o -n "$chdir" -o -n "$ConfigFile" -o -n "$ConfigBranch" ]; then
 | |
|     # charger la configuration
 | |
|     ensure_gitdir "$chdir"
 | |
|     load_branches all
 | |
|     load_config
 | |
|     set_pman_vars "$merge_dir"
 | |
|     load_branches current
 | |
| fi
 | |
| resolve_should_push quiet
 | |
| 
 | |
| "${action}_action" "$@"
 |