Affichage des articles dont le libellé est SGV. Afficher tous les articles
Affichage des articles dont le libellé est SGV. Afficher tous les articles

30 mars 2010

Numéroter automatiquement des branches svn

Créer une nouvelle version sur un projet géré par Subversion, c'est très souvent créer une nouvelle branche. Afin d'harmoniser le nom des branches on peut être tenté de respecter une convention de nommage et de les numéroter.

Exemple de structure attendue

`-----trunk
 |      `-----fichier1
 |      `-----fichier2
`-----branches
        `-----VERSION_1
        |     `-----fichier1
        |     `-----fichier2
        `-----VERSION_1_1
        |     `-----fichier1
        |     `-----fichier2
        `-----VERSION_2
              `-----fichier1
              `-----fichier2

mkbranch

Cette procédure devant être répétée à chaque nouvelle version, il est intéressant d'automatiser cette procédure. Voici donc le script mkbranch qui permet de créer des branches versionnées pour n'importe quel répertoire présent dans le trunk d'un dépôt subversion.

#!/bin/sh
# @author Nicolas Thouvenin 
# @link http://github.com/touv/misc/blob/master/mkbranch
SCRIPT_NAME=`basename $0`
SCRIPT_PATH=`dirname $0`

usage() {
cat <<EOF

    SYNTAXE :
        ${SCRIPT_NAME} [ [-n|--new] |
                         [-u|--update] |
                         [[-v|--version] VERSION ]
                       ] REPERTOIRE

    DETAILS :
        Création d'une branche versionnée sur un répertoire sous le contrôle de svn

        --new     : Bascule majeur, création d'un nouveau numéro de version
        --update  : Bascule minueur, création d'une sous version
        --version : Force le numéro de version (très utile en cas de problème)


    EXEMPLES :
        $SCRIPT_NAME .
        $SCRIPT_NAME -n trunk
        $SCRIPT_NAME -u trunk/module
        $SCRIPT_NAME --update trunk/module 
        $SCRIPT_NAME --version VERSION_4_2 module

EOF
    exit 0;
}

PREFIX="VERSION"          # Préfix du nom de chaque branche
SEPARATOR="_"             # Séparateur entre le préfix et les numéros majeurs et mineurs


VERSION=""
ACTION=""
MODULE=""
NEXT=""
for argument in $*
do
 if [ ! -z "${NEXT}" ]
 then
  CMD="if [ -z \"\${${NEXT}}\" ]; then export ${NEXT}=\"${argument}\"; else export ${NEXT}=\"\${${NEXT}} ${argument}\"; fi;"
  eval ${CMD}
  NEXT=""
 else
  case $argument in
   -h | --help )
   usage
   ;;
   -n | --new )
   ACTION="new"
   ;; 
   -u | --update )
   ACTION="upd"
   ;; 
   -v | --version )
   NEXT="VERSION"
   ;; 
   * )
   MODULE=$argument
   ;;
  esac
 fi
done


VERSION=${VERSION:=}
ACTION=${ACTION:=upd}
SKIPPING=${ACTION:=}

if test ${#} -eq 0
then
 usage
fi
if test "x${MODULE}" = "x"
then
 usage
fi
TRUNK=`svn info --xml ${MODULE} | grep "<url>" | sed -e "s/<url>//" -e "s/<\/url>//"`/
if test "x${TRUNK}" = "x/"
then
 usage
fi
BRANCHES=`echo ${TRUNK} | sed -e "s/\/trunk/\/branches/"`
if test "${TRUNK}" = "${BRANCHES}"
then
 usage
fi
echo "Dépôt trouvé : ${TRUNK}"
if test "x${VERSION}" = "x" 
then
 echo "Calcul du nouveau numéro de version ..."
 AWK=`echo "awk '\$""0 !~ /${SEPARATOR}/ { print \$""0\"${SEPARATOR}0\"} $""0 ~/${SEPARATOR}/ { print $""0}'"`
 MAJEUR=`svn list ${BRANCHES}/ | grep "${PREFIX}${SEPARATOR}"  | sed -e"s/\///" -e"s/${PREFIX}${SEPARATOR}//" | eval ${AWK} | sed -e"s/${SEPARATOR}/ /" | sort -n | cut -f 1 -d " " | tail -1`
 MINEUR=`svn list ${BRANCHES}/ | grep "${PREFIX}${SEPARATOR}"  | sed -e"s/\///" -e"s/${PREFIX}${SEPARATOR}//" | eval ${AWK} | sed -e"s/${SEPARATOR}/ /" | sort -n | cut -f 2 -d " " | tail -1`
 
 if test "x${MAJEUR}" = "x"
 then 
  MAJEUR="0"
 fi
 if test "x${MINEUR}" = "x"
 then
  MINEUR="0"
 fi

 echo "Version trouvée : ${PREFIX}${SEPARATOR}${MAJEUR}${SEPARATOR}${MINEUR}"

 if test "x${ACTION}" = "xupd" 
 then
  MINEUR=`expr $MINEUR + 1 2>/dev/null`
  VERSION="${PREFIX}${SEPARATOR}${MAJEUR}${SEPARATOR}${MINEUR}"
 elif test "x${ACTION}" = "xnew"
 then
  MAJEUR=`expr ${MAJEUR} + 1 2>/dev/null`
  VERSION="${PREFIX}${SEPARATOR}${MAJEUR}"
 fi
fi

echo "Nouveau numéro  : ${VERSION}"
echo "Confirmer le branchage  (O/N)"
read -r CONFIRM
if test "x${CONFIRM}" != "xO" 
then
 echo "Branchage abandonné !"
 exit 1
fi
echo "Branchage de ${MODULE} en ${VERSION} ..."
svn cp ${TRUNK} ${BRANCHES}${VERSION}/ -m "$0 ${VERSION}"
exit $?

Téléchargement et code source

Le code source de ce script est consultable et téléchargeable depuis GitHub à cette adresse http://github.com/touv/misc/blob/master/mkbranch

Remarques

  • Ce script a uniquement été testé sous Ubuntu et Debian sur des dépôts svn distants. Il n'y a pas raison qui ne fonctionne pas sur d'autres distribution et sur des dépôts locaux, mais je ne peux pas l'affirmer.
  • Le nom des branches est paramétrable suivant cette régle : ${PREFIX}${SEPARATEUR}${NUMERO}${SEPARATEUR}${NUMERO}
  • Le script peut être renommé indifféremment.

09 décembre 2009

Pourquoi je préfére git à svn

J'utilise presque quotidiennement svn et git, et au fil de mon usage, ma préférence va son contestation vers git, Pourquoi ?

les répertoires .svn

Manipuler, déplacer ou renommer un répertoire dans une arborescence pose rapidement problème à partir du moment ou l'on ne valide (commit) pas chaque opération ! Copier des répertoires d'un repository à un autre ou isoler un répertoire en dehors de son arborescence de travail se fait naturellement avec git. Avec svn, il faut prendre soin de supprimer les répertoires .svn car en cas d'oubli c'est le bordel assuré...

Déplacer, copier, renommer

Toutes ces opérations à l'intérieur d'une arborescence de fichier nécessite de faire un "commit" dans un répertoire incluant la source et la destination. Dans le cas contraire, si on "commit" uniquement le répertoire source, le repository est certes correct mais le répertoire local de destination sera bancal. Il faudra nécessairement tout supprimer et refaire une mise à jour pour retrouver une version locale correcte. Pour éviter ce type de problème avec svn, l'idéal est de faire des commits à la racine de son projet. Ce qui n'est évidemment pas le cas avec git.

De plus, avant de déplacer, copier ou supprimer un fichier, il faut prendre soin de valider (commit) toutes les modifications locales faites sur ce fichier. Sinon svn bloquera la manipulation et si on passe en force on perdra automatiquement toutes les modifications. Ce type de problème n'existe pas avec git.

Branches et versions

Avec svn, les branches et les versions sont forcement partagés entre tous les utilisateurs du repository. Impossible donc d'avoir une branche personnel de travail, sauf à travailler hors de svn ou à ce mettre d'accord entre développeurs pour que personne ne modifie la branche sur laquelle on travaille.

Inconvénients d'un système centralisé

Bien sur svn a les inconvénients d'un système centralisé par opposition à un système décentralisé. Le principal problème est qu'un "commit" vaut "publication". Faire un commit s'est envoyer des données sur le serveur central et donc potentiellement partager ces modifications. Par conséquent, on valide (commit) uniquement quand on juge les modifications suffisamment avancés pour quelles soient grosso modo cohérentes et donc visibles par les autres développeurs. Avec git, la validation et la publication sont séparées, ce qui donne plus de souplesse au développeur.

Conclusion

D'accord git a d'autres inconvénients (les interfaces graphiques, son intégration difficile dans les explorateurs de fichiers, son utilisation sous windows, etc...). Cependant les problèmes décrits précédement touchent l'usage primaire que l'on peut avoir d'un gestionnaire version. Ce qui m'amène à penser que git foncièrement meilleur que svn.

03 juin 2009

Dépôt Git privé et personnel sur serveur mutualisé OVH

L'architecture et la philosophie de Git n'imposent pas l'usage d'un serveur central. Malgré cela, pour un développeur, il est pratique et confortable d'avoir un dépôt de référence donc d'avoir un dépôt central.
Si l'on travaille sur un projet public seul ou à plusieurs, des plateformes comme github ou gitorious sont parfaitement adaptées. Si par contre, on souhaite utiliser git pour un usage personnel et strictement privé, ces plateformes le sont beaucoup moins (options payantes pour github notamment). D'autant plus que si on loue déjà un serveur autant essayer de le réutiliser.

L'offre de serveur mutualisé chez OVH propose à partir de la gamme 90 Plan un accès ssh. On a donc un accès en ligne de commande dans son espace et on peut utiliser les outils installés sur le système.

Depuis quelques temps (ça n'a pas toujours été le cas), on peut utiliser la commande git. Il devient donc possible de transformer son compte en serveur de dépôt git privé. Démonstration :

Création d'un projet GIT


% mkdir ~/mon_projet
% cd ~/mon_projet 
% touch .gitignore
% git init
% git add .
% git commit -an

Création du dépôt de référence


% cd ~/mon_projet 
% git clone --bare . ~/mon_projet.git
% cd ~/mon_projet.git
% git --bare update-server-info
% cd hooks/
% mv post-update.sample post-update
% chmod a+x post-update

Un dépôt de référence et plus précisément un dépôt nu a par convention l'extension git. Dans notre exemple : mon_projet.git

Copie sur le serveur


% scp -r ~/mon_projet.git moi@ovh:~/
% rm -Rf ~/mon_projet*

Utilisation du dépôt de référence


% git clone ssh://moi@ovh/~/mon_projet.git
% touch readme
% git add readme
% git commit -an
% git push

20 mai 2009

Un fichier .gitignore pour Automake & Autoconf

Quand on utilise automake et autoconf pour un projet, le répertoire de celui-ci contient de très nombreux fichiers et répertoires créés automatiquement par ces 2 outils.
Si on souhaite utiliser git pour gérer le projet, il est fortement conseillé de signaler à Git la liste des fichiers pouvant être régénérés automatiquement.

Voici donc un fichier .gitignore pour ignorer les fichiers générés par Automake et Autoconf.

Makefile
Makefile.in
aclocal.m4
autom4te.cache
build
config.cache
config.guess
config.h
config.h.in
config.log
config.status
config.sub
configure
depcomp
install-sh
libtool
ltmain.sh
missing
mkinstalldirs
releases
stamp-h
stamp-h1
stamp-h.in
*~
*.swp
*.o
.deps
*.exe

12 janvier 2009

Balader un projet versionné de poste en poste sans serveur central ?

J'ai déjà, par le passé, rédigé 2 articles montrant comment balader des fichiers de poste en poste avec une clé USB :

Le temps passe et les techniques avancent. Voici donc une autre méthode, en utilisant cette fois-ci, un gestionnaire de version décentralisé en l'occurrence git.

Énoncé

Soient deux postes nommés A et B. Soit un projet nommé P contenant un fichier F.

Comment modifier F sur A pour aller ensuite le modifier sur B avant de revenir sur A.

Vous me suivez ;-)

Préambule

Pour utiliser git, il faut que le projet P soit gérer par git. Pour cela :


touv@A ~ % cd p
touv@A ~/p % git init
touv@A ~/p % touch f
touv@A ~/p % git add f
touv@A ~/p % git commit

Mettre le projet sur une clé USB

Ici, le but est de cloner le projet dans un répertoire sur la clé USB puis
de récupérer les modifications faites dans le répertoire d'origine.


touv@A ~ % cd /media/usb
touv@A /media/usb % mkdir p
touv@A /media/usb % git clone ~/p

Modifier le projet sur un autre poste

Comme précédemment, il faut cloner le projet sur le nouveau poste.


touv@B ~ % git clone /media/usb/p
touv@B ~ % cd p
touv@B ~/p % cat "Coucou c'est B" >> f
touv@B ~/p % git commit

Ensuite, il nous faut envoyer les modifications locales sur la clé USB :


touv@B ~/p % git repack
touv@B ~/p % git prune-packed
touv@B ~/p % cd /media/usb/p
touv@B /media/usb/p % git pull ~/p
touv@B /media/usb/p % git commit -a --no-verify --message "en balade"

Revenir sur le poste de départ et continuer le travail

Ici, il suffit de "tirer" les sources de la clé USB.


touv@A ~ % cd p
touv@A ~/p % git pull /media/usb/p master
touv@A ~/p % cat f
Coucou c'est B

Et, rejouer ce petit scénario autant de fois que l'on souhaite ...

07 octobre 2005

Utiliser CVS et SSH avec un numéro de port SSH non standard

Cas d'utilisation

  • Vous souhaitez récupérer les sources d'un projet géré par CVS.
  • Le repository CVS se trouve sur machine distante.
  • Le serveur SSH de la mahine distante tourne sur un port non standard (par exemple : le 123456).

Voici comment faire :

Dans le fichier $HOME/.ssh/config ajoutez les lignes suivantes :


HostKeyAlias lamachinedistante
Hostname machine.exemple.com
Port 123456

Fixez les variables d'environnement pour CVS de cette manière :


CVSROOT=:ext:yourlogin@lamachinedistante:/path/to/the/repository
CVS_RSH=ssh

Et voila, la commande «cvs checkout votre/module» devrait fonctionner.