250 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			250 lines
		
	
	
		
			7.9 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 show_action() {
 | |
|     local commits
 | |
|     setx commits=_list_commits
 | |
|     if [ -n "$commits" ]; then
 | |
|         einfo "Commits à fusionner $SrcBranch --> $DestBranch"
 | |
|         eecho "$commits"
 | |
|     fi
 | |
| }
 | |
| 
 | |
| function ensure_branches() {
 | |
|    [ -n "$SrcBranch" -a -n "$DestBranch" ] ||
 | |
|         die "$SrcBranch: Aucune configuration de fusion trouvée pour cette branche"
 | |
| 
 | |
|    array_contains LocalBranches "$SrcBranch" || die "$SrcBranch: branche source introuvable"
 | |
|    array_contains LocalBranches "$DestBranch" || die "$DestBranch: branche destination introuvable"
 | |
| }
 | |
| 
 | |
| function merge_action() {
 | |
|     [ -z "$ShouldPush" ] && enote "\
 | |
| L'option --no-push a été forcée puisque ce dépôt n'a pas d'origine"
 | |
| 
 | |
|     enote "\
 | |
| Ce script va
 | |
| - fusionner la branche ${COULEUR_BLEUE}$SrcBranch${COULEUR_NORMALE} dans ${COULEUR_ROUGE}$DestBranch${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_${SrcType^^}"; [ -n "${!hook}" ] && _scripta <<EOF
 | |
| (
 | |
| ${!hook}
 | |
| )$or_die
 | |
| EOF
 | |
|     _mscript_merge_branch
 | |
|     hook="AFTER_MERGE_${SrcType^^}"; [ -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_${SrcType^^}"; [ -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_${DestType^^}"; [ -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_${DestType^^}"; [ -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
 | |
| }
 | |
| 
 | |
| ################################################################################
 | |
| # Programme principal
 | |
| ################################################################################
 | |
| 
 | |
| chdir=
 | |
| Origin=
 | |
| ConfigBranch=
 | |
| ConfigFile=
 | |
| _Fake=
 | |
| _KeepScript=
 | |
| action=merge
 | |
| TechMerge=
 | |
| SquashMsg=
 | |
| [ -z "$PMAN_NO_PUSH" ] && Push=1 || Push=
 | |
| [ -z "$PMAN_NO_DELETE" ] && Delete=1 || Delete=
 | |
| AfterMerge=
 | |
| args=(
 | |
|     "fusionner la branche source dans la branche destination correspondante"
 | |
|     " [source]
 | |
| 
 | |
| CONFIGURATION
 | |
| Le fichier .pman.conf contient la configuration des branches. Les variables
 | |
| supplémentaires suivantes peuvent être définies:
 | |
|     BEFORE_MERGE_<srcType>
 | |
|     AFTER_MERGE_<srcType>
 | |
|     AFTER_DELETE_<srcType>
 | |
|     BEFORE_PUSH_<destType>
 | |
|     AFTER_PUSH_<destType>
 | |
| srcType et destType pouvant valoir UPSTREAM, DEVELOP, FEATURE, RELEASE, MAIN, HOTFIX, DIST"
 | |
|     -d:,--chdir:BASEDIR chdir= "répertoire dans lequel se placer avant de lancer les opérations"
 | |
|     -O:,--origin Origin= "++\
 | |
| origine à partir de laquelle les branches distantes sont considérées"
 | |
|     -B:,--config-branch ConfigBranch= "++\
 | |
| branche à partir de laquelle charger la configuration"
 | |
|     -c:,--config-file:CONFIG ConfigFile= "++\
 | |
| fichier de configuration des branches. cette option est prioritaire sur --config-branch
 | |
| par défaut, utiliser le fichier .pman.conf dans le répertoire du dépôt s'il existe"
 | |
|     --fake _Fake=1 "++option non documentée"
 | |
|     --keep-script _KeepScript=1 "++option non documentée"
 | |
|     -w,--show action=show "\
 | |
| lister les modifications qui seraient fusionnées dans la branche destination"
 | |
|     -b,--rebase action=rebase "\
 | |
| lancer git rebase -i sur la branche source. cela permet de réordonner les
 | |
| commits pour nettoyer l'historique avant la fusion"
 | |
|     --merge action=merge "++\
 | |
| fusionner la branche source dans la branche destination correspondante.
 | |
| c'est l'action par défaut"
 | |
|     --tech-merge TechMerge=1 "++option non documentée"
 | |
|     -s:,--squash:COMMIT_MSG SquashMsg= "\
 | |
| fusionner les modifications de la branche comme un seul commit.
 | |
| cette option ne devrait pas être utilisée avec --no-delete"
 | |
|     -n,--no-push Push= "\
 | |
| ne pas pousser les branches vers leur origine après la fusion"
 | |
|     --push Push=1 "++\
 | |
| pousser les branches vers leur origine après la fusion.
 | |
| c'est l'option par défaut"
 | |
|     -k,--no-delete Delete= "\
 | |
| ne pas supprimer la branche après la fusion dans la destination"
 | |
|     --delete Delete=1 "++\
 | |
| supprimer la branche après la fusion dans la destination.
 | |
| c'est l'option par défaut"
 | |
|     -f,--force-merge ForceMerge=1 "++\
 | |
| forcer la fusion pour une branche qui devrait être traitée par prel"
 | |
|     -a:,--after-merge AfterMerge= "\
 | |
| évaluer le script spécifié après une fusion *réussie*"
 | |
| )
 | |
| parse_args "$@"; set -- "${args[@]}"
 | |
| 
 | |
| # charger la configuration
 | |
| ensure_gitdir "$chdir"
 | |
| load_branches all
 | |
| load_config "$MYNAME"
 | |
| load_branches current "$1"
 | |
| 
 | |
| resolve_should_push quiet
 | |
| 
 | |
| # puis faire l'action que l'on nous demande
 | |
| case "$action" in
 | |
| show)
 | |
|     git_check_cleancheckout || ewarn "$git_cleancheckout_DIRTY"
 | |
|     ensure_branches
 | |
|     show_action "$@"
 | |
|     ;;
 | |
| merge)
 | |
|     ShouldDelete=1
 | |
|     no_merge_msg="$SrcBranch: cette branche doit être fusionnée dans $DestBranch avec prel"
 | |
|     if [ "$SrcType" == develop ]; then
 | |
|         [ -z "$ForceMerge" ] && die "$no_merge_msg"
 | |
|         [ -n "$AfterMerge" ] || setx AfterMerge=qvals git checkout -q "$SrcBranch"
 | |
|     elif [ "$SrcType" == release -o "$SrcType" == hotfix ]; then
 | |
|         die "$no_merge_msg"
 | |
|     fi
 | |
|     # n'autoriser la suppression que pour feature
 | |
|     [ "$SrcType" == feature ] || ShouldDelete=
 | |
|     [ -z "$ShouldDelete" ] && Delete=
 | |
|     [ -z "$_Fake" ] && git_ensure_cleancheckout
 | |
|     if array_contains LocalBranches "$SrcBranch"; then
 | |
|         ensure_branches
 | |
|         merge_action "$@"
 | |
|     elif array_contains AllBranches "$SrcBranch"; then
 | |
|         enote "$SrcBranch: une branche du même nom existe dans l'origine"
 | |
|         die "$SrcBranch: branche locale introuvable"
 | |
|     else
 | |
|         die "$SrcBranch: branche introuvable"
 | |
|     fi
 | |
|     ;;
 | |
| *)
 | |
|     die "$action: action non implémentée"
 | |
|     ;;
 | |
| esac
 |