<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Artisan Numérique</title>
  <link rel="alternate" type="text/html" href="http://artisan.karma-lab.net/node/1071"/>
  <link rel="self" type="application/atom+xml" href="http://artisan.karma-lab.net/node/1071/atom/feed"/>
  <id>http://artisan.karma-lab.net/node/1071/atom/feed</id>
  <updated>2008-10-26T20:06:22+01:00</updated>
  <entry>
    <title>Bloc-note &#039;Subversion&#039;</title>
    <link rel="alternate" type="text/html" href="http://artisan.karma-lab.net/node/1071" />
    <id>http://artisan.karma-lab.net/node/1071</id>
    <published>2006-10-28T19:29:49+02:00</published>
    <updated>2008-10-26T20:06:22+01:00</updated>
    <author>
      <name>Ulhume</name>
    </author>
    <category term="Bases de données" />
    <category term="Aucun" />
    <category term="Note" />
    <category term="OK" />
    <summary type="html"><![CDATA[<p>Bloc-Notes sur Subversion</p>
    ]]></summary>
    <content type="html"><![CDATA[<p>Bloc-Notes sur Subversion</p>
<!--break-->

	<a name='chapter_1'></a>
  <h2>Organisation \"typique\" d'un dépôt</h2>
	
<p>
  'organisation d'un dépôt est affaire de besoin et doit être bien pensée dés le début même si tout peut être changé, ou presque, par la suite.
</p>

<h3>Dépôt unique ou dépots multiples</h3>
<p>
La première question à se poser est "un ou plusieurs dépôts". En effet, si nous avons deux projets à versionné, il n'est pas idiot de se dire que l'on va créer deux dépôts avec chacun leur URL. Mais il est aussi possible de créer deux dossiers dans le même dépôt et de gérer ces deux dossiers de manière indépendante. Ce qu'il faut prendre en compte dans son choix à ce stade, c'est :
<ul>
<li>Un compteur de révision par dépôt. Cela veut dire que si deux projets sont sur le même dépôt, chaque <kbd>commit</kbd> d'un côté fera augmenter le compteur de révision de l'autre côté. Pour moi la révision est comme un numéro de série, pas une version, donc je ne trouve pas cela gênant. Mais pour les anciens de CVS cela peut être perturbant de commiter il y a 6 mois une révision 10, et lors d'un nouveau commit, six mois plus tard, de se retrouver à la révision 4512 parce qu'entre temps, les autres projets ont vécu. Donc chacun ses goûts à ce stade. 
</p>
<li>Un dépôt = plus de fluidité. En effet, lorsqu'une sous branche d'un projet devient bien dense et que l'on veut la transformer en projet indépendant, il suffit de faire un simple MOVE dans un nouveau dossier pour lui-donner son nouveau statut en conservant en prime tout l'historique. 
</li>
<li>
  Plusieurs dépots = moins d'espace. Un argument pour le multi-dépôts est qu'il sépare les espaces disques. En effets, si le projet A meurt une fois pour toute, supprimer son dépot libère de l'espace disque. Car il ne faut pas oublier que pour subversion, le mot supprimer n'existe pas. 
</li>
</ul>
</p>

<p>
En conclusion, au delà du numéro de révision, le critère de choix est "est-ce que mes projets vont se mélanger les uns les autres". Si je suis une SSII, c'est rarement le cas, je vais créer un dépôt par client/projet car il est rare que le sous-projet du client A se retrouve un jour projet du client B (et encore <img src="http://artisan.karma-lab.net/sites/all/modules/contrib/smileys/packs/crystal/wink2.gif" title="Wink" alt="Wink" class="smiley-content"/>. Si je suis une organisation type "Apache" ou "KDE", mes projets sont tous plus où moins liés, j'ai donc tout interêt à ne faire qu'un seul dépôt. 
</p>
<h3>Organisation des dossiers par projet</h3>
<p>
Un dépôt peut contenir autant de sous-dossier que désiré jusqu'à arriver à celui d'un projet. Subversion permettant de gérer les droits de manière fine sur chacun des dossiers. Nous pouvons donc avoir une structure adapté à nos besoins du type :

  <div class='code-block code-block-fragment'>
  <div class='container'>
  https://mondepot/<br />
&nbsp; java<br />
&nbsp; &nbsp; toolkits<br />
&nbsp; &nbsp; &nbsp; network<br />
&nbsp; &nbsp; &nbsp; ...<br />
&nbsp; &nbsp; webapps<br />
&nbsp; &nbsp; &nbsp; monApplication<br />
&nbsp; &nbsp; &nbsp; ...
  </div>
  
  </div>
</p>
<p>
  En revanche, arrivé au niveau du projet lui-même il convient de normaliser le premier niveau de dossiers comme suit :

  <div class='code-block code-block-fragment'>
  <div class='container'>
  monApplication<br />
&nbsp; trunk<br />
&nbsp; &nbsp; monApplication<br />
&nbsp; branches<br />
&nbsp; &nbsp; maBrancheExperimentale<br />
&nbsp; &nbsp; &nbsp; monApplication<br />
&nbsp; tags<br />
&nbsp; &nbsp; Version 1.1<br />
&nbsp; &nbsp; &nbsp; monApplication
  </div>
  
  </div>
</p>
<p>
  Les sous-dossiers <kbd>trunk, branches et tags</kbd> vont permettre de s'y retrouver quant à l'étiquetage des versions. Le premier niveau <kbd>mon application</kbd> n'est donc en réalité jamais <kbd>chekouté</kbd>. Seuls les dossiers fineaux <kbd>monApplication</kbd> le seront. Le <kbd>trunk</kbd> correspond à la version courrant de développement (head en CVS), <kbd>branches</kbd> contient des sous dossiers correspondant aux branches (expérimentales ou pas) et <kbd>tags</kbd> aux versions release. Dans les deux derniers cas le niveau en dessous est un dossier nommé pour s'y retrouver (ex. Version 1.1) et en dessous nous retrouvons le dossier de l'application elle-même. 
</p>


	<a name='chapter_2'></a>
  <h2>Commandes de base</h2>
	
<h3>Import initial d'un dossier (et de son contenu) dans SubVersion</h3>
<p>

  <div class='code-block code-block-fragment'>
  <div class='container'>
  <span class="co0"># On importe le projet dans le dépôt</span><br />
svn import monProjet http:<span class="sy0">//</span>monSite.org<span class="sy0">/</span>subversion<span class="sy0">/</span>monProjet<span class="sy0">/</span>trunk<span class="sy0">/</span>monProjet<br />
<br />
<span class="co0"># Suppression du projet maintenant qu'il est dans le dépôt</span><br />
<a target="blank" href="http://pwet.fr/man/linux/commandes/rm"><span class="kw2">rm</span></a> -rf monProjet<br />
<br />
<span class="co0"># pour le récupérer à nouveau, mais cette fois, géré par subversion</span><br />
svn <a target="blank" href="http://pwet.fr/man/linux/commandes/co"><span class="kw2">co</span></a> http:<span class="sy0">//</span>monSite.org<span class="sy0">/</span>subversion<span class="sy0">/</span>monProjet<span class="sy0">/</span>trunk<span class="sy0">/</span>monProjet
  </div>
  
  </div>
</p>
<p>
Ensuite tout marche comme un système de fichier classique

  <div class='code-block code-block-fragment'>
  <div class='container'>
  <span class="co0"># Si l'on désire déplacer un fichier/dossier, grande nouveauté par rapport à CVS</span><br />
svn <a target="blank" href="http://pwet.fr/man/linux/commandes/mv"><span class="kw2">mv</span></a> mauvaisEmplacement sousDossier<span class="sy0">/</span>bonEmplacement<br />
<br />
<span class="co0"># Supprimer</span><br />
svn <a target="blank" href="http://pwet.fr/man/linux/commandes/rm"><span class="kw2">rm</span></a> fichieraDetruire<br />
<br />
<span class="co0"># Commiter ses modifications dans le dépot</span><br />
svn commit -m <span class="st0">&quot;Un commentaire est toujours le bienvenu !&quot;</span>
  </div>
  
  </div>
</p>

<h3>Etat de la copie locale</h3>
<p>
Pour s'assurer que tout est en ordre, ou pour avoir la liste des fichiers ajoutés et modifiés, la commande suivante est bien utile :


  <div class='code-block code-block-fragment'>
  <div class='container'>
  svn status
  </div>
  
  </div>
</p>


<h3>Liste des commentaires de révision</h3>

  <div class='code-block code-block-fragment'>
  <div class='container'>
  svn log
  </div>
  
  </div>


	<a name='chapter_3'></a>
  <h2>Modification des méta-données</h2>
	
<p>
Une des nouveauté de subversion est la possibilité de stocker des méta données au niveau des répertoires. Cela peut servir à renseigner la liste des dossiers/fichiers invisibles, à définir la liste des références externes, etc...
</p>
<h3>éditeur externe</h3>
<p>
Pour éditer les propriétés, nous allons avoir besoin d'un éditeur externe. Cela peut-être n'importe quelle application capable d'éditer du texte de la manière qui vous convient :

  <div class='code-block code-block-fragment'>
  <div class='container'>
  <span class="kw3">export</span> <span class="re2">VISUAL=</span>vi
  </div>
  
  </div>
</p>
<h3>Les commandes de gestion des propriétés</h3>

  <div class='code-block code-block-fragment'>
  <div class='container'>
  <span class="co0"># donne la liste des propriétés dans le dossier courrant</span><br />
svn proplist .<br />
<br />
<span class="co0"># Affiche le contenu d'une propriété du dossier courrant</span><br />
svn propget ma:propriete .<br />
<br />
<span class="co0"># Edition du contenu d'une propriété du dossier courrant</span><br />
svn propedit ma:propriete .<br />
<br />
<span class="co0"># Changer la valeur sans passer par l'éditeur (moins pratique)</span><br />
svn propset ma:propriete <span class="st0">&quot;Sa valeur&quot;</span> .
  </div>
  
  </div>

<h3>Déclarer un dossier comme ignoré</h3>
<p>
  La propriété responsable du fait d'ignorer un fichier, un dossier, un ensemble, etc, est <kbd>svn:ignore</kbd>. Il suffit donc d'éditer cette propriété pour ajouter une régle par ligne contenant le nom d'un fichier, d'un dossier, ou un "pattern" du type <kbd>*.bak</kbd>. 
</p>

<h3>Charger des sous-projets externes</h3>
<p>
Une des possibilités très utile de SubVersion est de pouvoir "monter" dans l'arborescence d'un projet des branches (au sens système de fichier du terme) provenant d'autre dépôts. Cela se fait très simplement par la commande d'édition de propriétés. Par exemple, imaginons que dans un dossier <kbd>monProjet</kbd>, nous cherchions à grêffer le projet <kbd>moduleAmi</kbd>. 
</p>
<p>
  Pour ajouter une référence, il faut éditeur la propriété <kbd>svn:externals</kbd> du dossier où lm'on désire établir la greffe. Ensuite nous ajoutons la référence comme suit :

  <div class='code-block code-block-fragment'>
  <div class='container'>
  moduleAmi https:<span class="sy0">//</span>siteAmi.org<span class="sy0">/</span>subversion<span class="sy0">/</span>moduleAmi<span class="sy0">/</span>trunk<span class="sy0">/</span>moduleAmi
  </div>
  
  </div>
</p>
<p>
 Il prut y avoir autant de ligne de référence que désiré. Une la propriété fois sauvé, il suffit de faire une mise à jour du dossier <kbd>monProjet</kbd> (svn co) pour mettre à jour ou, si le dossier externe n'existe pas encore, checkouter le dossier greffé automatiquement.
</p>
<p>
 De manière général, une mise à jour (svn up) à la racine, entraîne une mise à jour des dossiers externes. En revanche, les commits (svn co), eux, ne franchissent pas les "barrières" des externals. Pour commiter une version d'un sous-dossier externe, il font explicitement commiter celui si. 
</p>


	<a name='chapter_4'></a>
  <h2>Astuces diverses</h2>
	
<h3>Revenir en arrière sur une action (avant commit)</h3>

  <div class='code-block code-block-fragment'>
  <div class='container'>
  svn revert fichier<span class="sy0">/</span>chemin
  </div>
  
  </div>

<h3>Commiter un dossier complet</h3>

  <div class='code-block code-block-fragment'>
  <div class='container'>
  <a target="blank" href="http://pwet.fr/man/linux/commandes/find"><span class="kw2">find</span></a> . -name <span class="st0">&quot;*~&quot;</span> -exec <a target="blank" href="http://pwet.fr/man/linux/commandes/rm"><span class="kw2">rm</span></a> -rf <span class="br0">&#123;</span><span class="br0">&#125;</span> \;<br />
svn add <span class="sy0">`</span>svn status <span class="sy0">|</span> <a target="blank" href="http://pwet.fr/man/linux/commandes/grep"><span class="kw2">grep</span></a> ? <span class="sy0">|</span> <a target="blank" href="http://pwet.fr/man/linux/commandes/cut"><span class="kw2">cut</span></a> -d<span class="st0">&quot; &quot;</span> -f7<span class="sy0">`</span><br />
svn <a target="blank" href="http://pwet.fr/man/linux/commandes/rm"><span class="kw2">rm</span></a> <span class="sy0">`</span>svn status <span class="sy0">|</span> <a target="blank" href="http://pwet.fr/man/linux/commandes/grep"><span class="kw2">grep</span></a> <span class="sy0">!</span> <span class="sy0">|</span> <a target="blank" href="http://pwet.fr/man/linux/commandes/cut"><span class="kw2">cut</span></a> -d<span class="st0">&quot; &quot;</span> -f7<span class="sy0">`</span><br />
svn commit -m <span class="st0">&quot;$1&quot;</span>
  </div>
  
  </div>

<h3>Obtenir l'url d'une copie de travail</h3>
<p>

  <div class='code-block code-block-fragment'>
  <div class='container'>
  svn info <span class="sy0">|</span> <a target="blank" href="http://pwet.fr/man/linux/commandes/grep"><span class="kw2">grep</span></a> URL
  </div>
  
  </div>
</p>

<h3>Changer l'url d'un espace de travail</h3>
<p>
Il arrive parfois que l'URL de base d'un dépôt doive être changé.
</p>
<p>
Par exemple impaginons que votre copie locale de <kbd>monProjet</kbd> ait été obtenue par :

  <div class='code-block code-block-fragment'>
  <div class='container'>
  svn <a target="blank" href="http://pwet.fr/man/linux/commandes/co"><span class="kw2">co</span></a> http:<span class="sy0">//</span>svn.masociete.com<span class="sy0">/</span>depots<span class="sy0">/</span>monProjet
  </div>
  
  </div>
</p>
<p>
Or, l'url de base a changé entre temps, et n'est aujourd'hui plus <kbd>http://svn.masociete.com/depots</kbd> mais <kbd>http://intranet.masociete.com/subversion</kbd>. Vous avez alors deux solutions, la plus "simple" consiste à détruire votre copie locale et à refaire un checkout. C'est jouable si vous n'avez aucune modification en cours sinon vous perdez tous vos ajouts...
</p>
<p>
La "vraie" solution consiste quant à elle à relocaliser votre copie locale vers le nouveau dépôt. Pour cela, allez dans le dossier racine de votre projet et tapez la commande suivante :

  <div class='code-block code-block-fragment'>
  <div class='container'>
  svn switch --relocate http:<span class="sy0">//</span>svn.masociete.com<span class="sy0">/</span>depots http:<span class="sy0">//</span>intranet.masociete.com<span class="sy0">/</span>subversion
  </div>
  
  </div>
</p>
<p>
Notez bien que seule l'url de base est utilisée, par le nom du projet. Ceci fait, vous pouvez à nouveau commiter vos modifications. 
</p>

<h3>Annuler le dernier commit</h3>
<p>Grosse cata, vous avez commité des horreurs et pour votre malheur, la règle absolue de subversion est de ne rien effacer. Pas de panique, voici la marche à suivre.</p
<p>Imaginons que vous ayez commité des erreurs dans la revision 666 et que vous vouliez revenir à la révision 665. L'astuce est de fusionner la revision 665 sur la 666 et de commiter l'ensemble en 667 qui sera donc un nouveau 666. Pour cela, placez-vous dans votre dossier à restaurer :

  <div class='code-block code-block-fragment'>
  <div class='container'>
  <span class="kw3">cd</span> mon_projet<br />
<br />
<span class="co0"># au cas où. Personnellement je fait un même un rm -rf * dans ce dossier, puis un svn up </span><br />
<span class="co0"># être certain d'avoir le dernière revision.</span><br />
svn up<br />
<br />
<span class="co0"># On merge avec les deux révisions</span><br />
svn merge -r <span class="nu0">666</span>:<span class="nu0">667</span> .<br />
<br />
<span class="co0"># On commit la revision &quot;patch&quot;</span><br />
svn commit -m <span class="st0">&quot;annulation des horreurs de la révision 666&quot;</span>
  </div>
  
  </div>
</p>


	<a name='chapter_5'></a>
  <h2>Changer les propriétés de révisions</h2>
	
<p>
 mettre en place le hook pre-revprop-change
</p>    ]]></content>
  </entry>
</feed>
