\documentclass[a4paper,11pt]{article}
\usepackage[latin1]{inputenc}
\usepackage[french]{babel}
\usepackage[T1]{fontenc}
\usepackage[hypertex]{hyperref}
\usepackage{fancyhdr}
%\usepackage{graphicx}
\usepackage{indentfirst}
\usepackage{vmargin}
\usepackage{lmodern}
\usepackage{verbatim}


%BEGIN LATEX
\FrenchFootnotes
\AddThinSpaceBeforeFootnotes
\setmarginsrb{2.5cm}{1.5cm}{2.5cm}{2cm}{1cm}{1cm}{1cm}{1cm}
%END LATEX

\newenvironment{code}{\small \verbatim}{\endverbatim \normalsize}

%$Id: formation_svn.tex 135 2005-08-02 09:47:51Z julien $

%HEVEA \newstyle{body}{width:800px;padding:1em;font-family:sans-serif;background:\#F9F9FF;}
%HEVEA \newstyle{.section}{margin-top: 8ex; border-bottom:1px solid navy; color:navy;}
%HEVEA \newstyle{.subsection}{margin-top: 5ex; color:navy;}
%HEVEA \newstyle{.subsubsection}{margin-top: 3ex; color:navy;}
%HEVEA \newstyle{.verbatim}{margin:3ex 0 3ex 0;padding:1ex;border:1px dotted black;background:\#E8E6FF;}
%HEVEA \newstyle{a}{text-decoration:none;color:blue;}
%HEVEA \newstyle{a:visited}{text-decoration:none;color:purple;}
%HEVEA \newstyle{a:hover}{text-decoration:none;color:red;}

\title{Introduction à Subversion}
\author{Julien Barnier}
\date{2 août 2005}

\begin{document}

\sloppy

\maketitle
\thispagestyle{empty}

\newpage

\pagestyle{fancy}
\lhead[\textit{\thepage}]{\textit{Introduction à} \textsf{Subversion}}
\rhead[\textit{\textit{Introduction à \texttt{Subversion}}}]{\textit{\thepage}}
\cfoot{\textbf{}}

\setcounter{tocdepth}{3}
\tableofcontents


\section{Introduction}


\subsection{Objectifs de ce document}

Ce document a pour objectif de servir d'aide-mémoire et de support de
formation succinct au logiciel de contrôle de versions
\texttt{Subversion}\footnote{\url{http://subversion.tigris.org/}}.


\subsection{Qu'est-ce que \texttt{Subversion}~?}

\texttt{Subversion} est un logiciel de gestion de sources et de contrôle
de versions. Ce type de programmes a plusieurs fonctions, notamment~:

\begin{itemize}
 \item garder un historique des différentes versions des fichiers d'un
	projet~;
 \item permettre le retour à une version antérieure quelconque~;
 \item garder un historique des modifications avec leur nature, leur
	date, leur auteur...~;
 \item permettre un accès souple à ces fichiers, en local ou via un
	réseau~;
 \item permettre à des utilisateurs distincts et souvent distants de
	travailler ensemble sur les mêmes fichiers.
\end{itemize}


\subsection{Pourquoi \texttt{Subversion} ~?}

Il existe un grand nombre de logiciels du même type. Le plus connu
d'entre eux et le plus répandu actuellement est sans doute
\texttt{CVS}\footnote{\url{http://www.cvshome.org/}. \texttt{Subversion} est souvent cité comme le successeur «~officiel~» de \texttt{CVS}.}, mais on peut aussi citer \texttt{GNU Arch}, \texttt{Bitkeeper},
\texttt{Git}, \texttt{Superversion}, etc.

Des comparatifs point à point peuvent être trouvés aux adresses
suivantes~:

\url{http://zooko.com/revision_control_quick_ref.html}

\url{http://better-scm.berlios.de/comparison/comparison.html}\\

On pourra justifier rapidement le choix de \texttt{Subversion} par les
arguments suivants~:
\begin{itemize}
 \item il est multiplateforme~;
 \item il s'agit d'un logiciel libre~;
 \item il fonctionne de manière centralisée~;
 \item son utilisation et son administration sont plus faciles que
	\texttt{CVS}~;
 \item il supporte plusieurs modes d'accès distants, dont \texttt{SSH} et
	\texttt{WebDAV} via \texttt{Apache}.
\end{itemize}



\subsection{Configuration requise}

Aucune configuration particulière n'est nécessaire pour utiliser
\texttt{Subversion}, il suffit juste de se procurer un client qui permette
de se connecter et de communiquer avec le dépôt. A noter qu'il est
très facile d'installer soi-même un serveur \texttt{Subversion} en local
sur sa machine si l'on souhaite l'utiliser de manière «~privée~».\\

Parmi les clients, on peut citer~:
\begin{itemize}
 \item la ligne de commande, un peu rustique mais qui permet de tout
	faire\footnote{Pour utiliser la ligne de commande, il faut télécharger et installer \texttt{Subversion} depuis le site officiel.}~;
 \item TortoiseSVN (\url{http://tortoisesvn.tigris.org/}) (Windows)
 \item RapidSVN (\url{http://rapidsvn.tigris.org/}), eSvn (\url{http://esvn.umputun.com/}) (multiplateforme)
 \item JSVN (\url{http://jsvn.alternatecomputing.com/}) (java,
	multiplateforme)
 \item Subclipse (\url{http://subclipse.tigris.org/}) (\emph{plugin} pour
	\texttt{Eclipse})
 \item AnkhSVN (\url{http://ankhsvn.tigris.org/}) (\emph{plugin} pour \texttt{Visual
	Studio .Net})
 \item psvn.el (\url{http://xsteve.nit.at/prg/vc_svn/}) (mode pour
	\texttt{Emacs})
 \item etc, etc.
\end{itemize}

Une liste complète de clients est disponible à l'adresse~:

\url{http://subversion.tigris.org/links.html#clients}\\

Dans ce qui suit, nous illustrerons les points abordés à l'aide de la
ligne de commande, mais les concepts sont les mêmes pour les
différents clients.


\section{Définitions}

\subsection{Notions générales}

\subsubsection{dépôt (\emph{repository})}

Un dépôt \texttt{Subversion} est l'emplacement central où sont stockées
toutes les données relatives aux projets gérés. Le dépôt est accédé
\emph{via} une URL locale ou distante.

Le dépôt contient l'historique des versions des fichiers stockés, les
logs enregistrés lors des modifications, les dates et auteurs de ces
modifications, etc.

Un dépôt apparaît de l'extérieur comme un système de fichiers composé
de répertoires au sein desquels on peut naviguer, lire et écrire selon
les permissions accordées.


\subsubsection{projets}

Au sein d'un dépôt se trouvent un ou plusieurs projets. À chaque
projet correspond en général un répertoire situé à la racine du dépôt
et qui contient lui-même les fichiers et dossiers du projet proprement
dit.\\

Exemple d'arborescence~:

\begin{code}
(dépôt)--+--/batchxsl--+--/trunk
         |             |
         |             +--/branches
         |             |
         |             +--/tags
         |
         +--/css-------+--/trunk
         |             |
         |             +--/branches
         |             |
         |             +--/tags
         |
         +--/test------+--/rep1
                       |
                       +--/rep2
\end{code}

\subsubsection{copie de travail (\emph{working copy})}

La copie de travail est un répertoire situé en local sur le poste de
l'utilisateur et qui contient une copie d'une révision donnée des
fichiers du dépôt. C'est cette copie qui sert de base de travail et
qui est modifiée en local avant d'être importée (sauvegardée) vers le
dépôt.


\subsubsection{révisions}

Chaque modification faite au dépôt constitue une révision. Le numéro
de révision commence à 1 et augmente de 1 à chaque opération. Sa
valeur n'a aucune importance, mais c'est un indicateur qui permet de
revenir à une version donnée d'un ou plusieurs fichiers.


\subsection{Opérations}


\subsubsection{\emph{checkout}}

Le \emph{checkout} est l'opération qui consiste à récupérer pour la
première fois les fichiers déjà existant au sein d'un projet du
dépôt. Cette opération ne se fait en général qu'une fois par projet.

Le résultat est une copie de travail.

\subsubsection{\emph{import}}

L'\emph{import} est l'opération inverse du \emph{checkout}. Elle consiste à
placer dans le dépôt des fichiers locaux déjà existants pour y créer
un nouveau projet. Cette opération ne se fait en général qu'une fois
par projet.

\subsubsection{\emph{update}}

L'\emph{update} consiste à synchroniser la copie de travail locale avec le
dépôt en récupérant la dernière version des fichiers du dépôt.

C'est à cette occasion que des conflits de version peuvent apparaître.

\subsubsection{\emph{commit}}

Un \emph{commit} est l'opération inverse d'un \emph{update}. Elle consiste à
mettre à jour le dépôt à partir de la copie de travail locale. Une
nouvelle révision est alors créée. Un log (simple message texte
contenant une description des modifications effectuées) doit être
saisi à cette occasion.\\

À noter que pour qu'un \emph{commit} soit possible, il faut que la copie de
travail corresponde à la dernière version du dépôt (modifications
locales exceptées). Si ce n'est pas le cas, il est nécessaire
d'effectuer d'abord un \emph{update} et de résoudre les conflits éventuels
avant de réessayer le \emph{commit}.


\section{Utilisation}

L'utilisation de \texttt{Subversion} suit en général un cycle assez
répétitif.

\subsection{Création d'un nouveau projet}

La première chose à faire lors de la première utilisation est de créer
un nouveau projet. Deux cas de figure peuvent se présenter~: ou bien le
projet existe déjà au sein d'un dépôt et il s'agit de récupérer ce
projet en local pour en faire une copie de travail, ou bien ce projet
existe en local et doit être importé au sein du dépôt.


\subsubsection{Projet déjà existant au sein d'un dépôt}

Si le projet existe déjà au sein du dépôt, une seule commande suffit
pour effectuer un \emph{checkout} et récupérer la dernière version des
fichiers~: il s'agit de la commande \texttt{svn co}.

\begin{code}
$ svn co https://cens-srv-dev1.ens-lsh.fr/svnrep/formationsvn .
A  credits.htm
A  index.htm
Checked out revision 36.
\end{code}
La commande précédente a effectué un \emph{checkout} du projet
\texttt{formationsvn} (situé dans un répertoire racine du même nom) dans
le répertoire courant.

Le résultat de la commande indique que deux fichiers ont été récupérés
et que la dernière révision est la révision numéro 36.


\subsubsection{Import d'un projet déjà existant en local}

Si le projet n'existe pas dans le dépôt et qu'il faut le créer à
partir de fichiers locaux, la commande à utiliser est \texttt{svn
import}. Cette opération n'est en théorie effectuée que par la
personne chargée de l'administration du dépôt. Voir la documentation
officielle pour plus d'informations.


\subsection{Récupération de la dernière version du projet}

Avant de travailler sur les fichiers du projet, il faut s'assurer que
l'on est bien synchronisé avec le dépôt, c'est à dire que la copie de
travail correspond bien à la dernière révision en cours. Pour cela, il
faut effectuer un \emph{update} à l'aide de la commande \texttt{svn update}~:

\begin{code}
$ svn update
U  index.htm
Updated to revision 37.
\end{code}
La commande indique qu'un fichier du répertoire, vraisemblablement
modifié par quelqu'un d'autre depuis notre dernier \emph{update}, a été mis
à jour dans notre copie de travail.


\subsection{Mise à jour des modifications dans le dépôt}

Une fois qu'on a modifié des fichiers, il faut basculer ces
modifications au sein du dépôt pour qu'elles soient accessibles aux
autres utilisateurs. Cette opération s'effectue à l'aide de la
commande \texttt{svn commit}~:

\begin{code}
$ svn commit -m "Ajout d'une personne dans les credits"
Sending        credits.htm
Transmitting file data .
Committed revision 38.
\end{code}
Toute opération de \emph{commit} s'effectue en indiquant un message
décrivant les modifications effectuées (ici directement dans la ligne
de commande). Il est possible d'effectuer cette opération sur un
répertoire entier, ou sur seulement un ou plusieurs fichiers.

Si des modifications ont eu lieu par un autre utilisateur du dépôt
depuis le dernier \emph{update}, un message d'erreur le signale. Il faut
alors effectuer un nouvel \emph{update} et résoudre d'éventuels conflits
avant de relancer le \emph{commit}.


\subsection{Récupération d'une version antérieure d'un fichier}


\subsubsection{Récupération de la dernière version}

Lorsqu'on travaille sur un fichier, il peut arriver que les
modifications effectuées ne soient pas bonnes et qu'on souhaite
retourner au fichier tel qu'il était lors du dernier \emph{update}. La
commande \texttt{svn revert} est faite pour ça~:

\begin{code}
$ svn revert credits.htm 
Reverted 'credits.htm'
\end{code}
Cette commande annule les modifications effectuées depuis le dernier
\emph{update}. À noter que tout est effectué en local, et qu'un accès au
dépôt n'est pas nécessaire.

\subsubsection{Récupération d'une version antérieure du dépôt}

On peut aussi souhaiter revenir à une version antérieure d'un fichier
situé dans le dépôt. Il faut alors utiliser \texttt{svn update} en
précisant le numéro de la révision et le ou les fichiers~:

\begin{code}
$ svn update -r 36 credits.htm 
U  credits.htm
Updated to revision 36.
\end{code}

\subsection{Gestion des fichiers du dépôt}

\texttt{Subversion} propose un ensemble de commandes pour ajouter,
supprimer ou renommer des fichiers du dépôt.

\subsubsection{Ajout d'un fichier}

Il faut utiliser \texttt{svn add}. A noter que l'ajout n'est effectif qu'au
prochain \emph{commit}~:

\begin{code}
$ svn add liens.htm 
A         liens.htm

$ svn commit -m "Ajout du fichier de liens"
Adding         liens.htm
Transmitting file data .
Committed revision 39.
\end{code}
\subsubsection{Suppression d'un fichier}

Il faut utiliser \texttt{svn delete}~:

\begin{code}
$ svn delete liens.htm
D         liens.htm

$ svn commit -m "Suppression d'un fichier"
Deleting       liens.htm
Committed revision 40.
\end{code}
Là aussi, la suppression n'est effective qu'au \emph{commit} suivant.

\subsubsection{Renommer un fichier}

Il faut utiliser \texttt{svn move}~:

\begin{code}
$ svn move credits.htm merci.htm
A         merci.htm
D         credits.htm

$ svn commit -m "Renommage d'un fichier"
Deleting       credits.htm
Adding         merci.htm
Committed revision 41.
\end{code}

\subsection{Résolution des conflits}

Les conflits peuvent intervenir au moment d'un \emph{update}, lorsque des
modifications ont été faites à la fois dans la copie de travail et
dans le dépôt. Par exemple, si vous éditez en local un fichier pour
lui rajouter une ligne, et qu'un autre utilisateur du dépôt a
«~commité~» entre temps une modification différente sur le même fichier,
votre \emph{commit} va générer l'erreur suivante~:

\begin{code}
$ svn commit
Sending        merci.htm
svn: Commit failed (details follow):
svn: Your file or directory 'merci.htm' is probably out-of-date
svn: 
The version resource does not correspond to the resource within the
transaction.  Either the requested version resource is out of date
(needs to be updated), or the requested version resource is newer than
the transaction root (restart the commit).
\end{code}
Il vous faut alors effectuer un \emph{update}, ce qui va mettre en
concurrence les deux versions du ou des fichiers concernés. Deux cas
de figure peuvent alors se présenter.

Dans le premier cas, le conflit peut être résolu automatiquement par
\texttt{Subversion} car les modifications ne concernent pas les mêmes
parties du fichier. Dans ce cas vous obtiendrez le message suivant~:

\begin{code}
$ svn update
G  merci.htm
Updated to revision 42.
\end{code}
Il est quand même conseillé de vérifier manuellement le résultat de
cette résolution «~automatique~».

Dans le deuxième cas, les modifications ne peuvent être fusionnées
automatiquement car elles concernent les mêmes parties d'un
fichier. Dans ce cas un conflit est signalé lors de l'\emph{update}~:

\begin{code}
$ svn update
C  merci.htm
Updated to revision 43.
\end{code}
Dans ce cas, deux nouveaux fichiers font leur apparition dans votre
copie de travail. Dans l'exemple précédent, on se retrouve avec~:

\begin{itemize}
 \item \texttt{merci.htm.mine}~: copie du fichier tel qu'il se
	trouvait dans votre copie de travail, en local, avant de faire
	l'\emph{update}. C'est la version que vous souhaitiez «~commiter~» avant
	de détecter un conflit~;
 \item \texttt{merci.htm.r42}~: version du fichier pour la révision 42, c'est
	à dire lors de votre dernier \emph{update}. C'est la version qui a servi
	de base pour les deux utilisateurs du dépôt qui ont travaillé en
	parallèle~;
 \item \texttt{merci.htm.r43}~: version du fichier pour la revision 43, c'est
	à dire la version actuellement dans le dépôt. Il s'agit de la
	version modifiée par un autre utilisateur, «~commitée~» avant votre
	\emph{update}, et dont le contenu est à l'origine du conflit.
 \item \texttt{merci.htm}~: il s'agit d'une version qui, en quelque sorte
	«~résume~» les trois autres en faisant apparaître les différences
	entre versions au sein d'un seul fichier.\\
\end{itemize}

Dès lors, le travail consiste à éditer le fichier \texttt{merci.htm}
jusqu'à ce que le conflit soit résolu\footnote{Les clients graphiques proposent parfois des outils plus conviviaux pour résoudre «~visuellement~» les conflits de version. \texttt{TortoiseSVN} utilise le programme associé \texttt{TortoiseMerge}.}. Une fois ce travail terminé, on
signale que le conflit est résolu à l'aide de la commande \texttt{svn
resolved}~:

\begin{code}
$ svn resolved merci.htm
Resolved conflicted state of 'merci.htm'
\end{code}
On peut alors effectuer le \emph{commit} final.


\subsection{Tronc, branches, tags...}

Les notions de tronc, de branches et de \emph{tags} sont assez spécifiques
aux logiciels de contrôle de versions. C'est ce qui explique que les
arborescences des répertoires de projet contiennent souvent comme
premier niveau de sous-répertoires les dossiers \texttt{trunk},
\texttt{branches} et \texttt{tags}.\\

En général, on définit par «~tronc~» la version centrale du programme,
le développement principal «~officiel~».\\

Une «~branche~» est en général créée lorsqu'un développement
«~secondaire~» est mis en route, que ce soit pour ajouter une nouvelle
fonctionnalité ou parce que certains développeurs souhaitent essayer
de prendre une autre direction pour certains aspects du
développement. Une branche peut, au bout d'un certain temps, soit être
à nouveau fusionnée dans le «~tronc~», soit disparaître, soit donner
lieu à un nouveau programme.\\

La notion de \emph{tags} correspond en partie à celle de \emph{release}, c'est à
dire de marquage d'une certaine révision du projet comme composant une
version du projet. Une fois que le développement a atteint une
certaine stabilité, on pourra par exemple créer un \emph{tag} pour marquer
la sortie de la version 1.0. Ceci permettra de revenir facilement à
cette version, indépendamment du numéro de révision sous-jacent
correspondant.\\

Nous n'entrerons pas dans le détail de ces concepts et commandes ici,
mais on peut juste citer que la création de branches ou de \emph{tags} ne
sont en fait que des copies créées par la commande \texttt{svn copy}. La
commande \texttt{svn switch}, elle, permet de faire passer la copie de
travail d'une branche à une autre.


\section{Outils}

\subsection{Aide intégrée}

Une aide est intégrée à l'interface en ligne de commande. Pour obtenir
de l'aide générale, et notamment la liste des commandes possibles, il
suffit de faire~:

\begin{code}
svn help
\end{code}
Pour obtenir de l'aide sur une commande particulière, utiliser~:

\begin{code}
svn help <nom de la commande>
\end{code}
\subsection{Informations sur la copie de travail}

Pour obtenir des informations sur la copie de travail en cours, on peut
utiliser \texttt{svn info}~:

\begin{code}
$ svn info
Path: .
URL: https://cens-srv-dev1.ens-lsh.fr/svnrep/formationsvn
Repository UUID: 090fa6ab-88f7-0310-b83e-cd111ae4905a
Revision: 40
Node Kind: directory
Schedule: normal
Last Changed Author: jbarnier
Last Changed Rev: 40
Last Changed Date: 2005-05-30 14:58:11 +0200 (lun, 30 mai 2005)
\end{code}
\subsection{Voir l'historique des modifications d'un fichier ou projet}

La commande \texttt{svn log} permet d'afficher l'historique de toutes les
modifications d'un fichier donné en paramètre ou d'un projet entier~:

\begin{code}
$ svn log index.htm   
 ------------------------------------------------------------------------
 r37 | jbarnier | 2005-05-30 14:42:26 +0200 (lun, 30 mai 2005) | 2 lines

 Modification du titre de la page

 ------------------------------------------------------------------------
 r36 | jbarnier | 2005-05-30 14:34:05 +0200 (lun, 30 mai 2005) | 2 lines

 Ajout de deux fichiers de test.

 ------------------------------------------------------------------------
\end{code}

La commande \texttt{svn blame} permet d'obtenir des informations sur un
fichier ligne par ligne, avec la révision et l'auteur correspondants~:

\begin{code}
$ svn blame index.htm 
    36   jbarnier <html>
    36   jbarnier <head></head>
    36   jbarnier <body>
    37   jbarnier <h1>Un bien beau titre, vraiment</h1>
    36   jbarnier </body>
    36   jbarnier </html>
\end{code}



\subsection{Voir le statut de la copie de travail}

La commande \texttt{svn status} permet d'avoir des informations sur l'état
de la copie de travail depuis le dernier \emph{update}~:

\begin{code}
$ svn status -v
?                                       credits.htm
               40       40 jbarnier     .
               41       41 jbarnier     merci.htm
               40       37 jbarnier     index.htm
\end{code}
\subsection{Parcourir le dépôt}

La commande \texttt{svn list} permet d'afficher le contenu du dépôt à
distance~:

\begin{code}
$ svn list https://cens-srv-dev1.ens-lsh.fr/svnrep/formationsvn
index.htm
merci.htm
\end{code}

\subsection{Utiliser les propriétés}

Les propriétés sont des attributs attachés à un ou plusieurs fichiers
du dépôt et qui permettent des comportements particuliers.\\

Sans entrer dans le détail, on ne citera que deux types de
propriétés. Tout d'abord, la propriété \texttt{svn:ignore} permet de
retirer explicitement certains fichiers du contrôle de version. Par
exemple, si votre éditeur de texte enregistre systématiquement une
copie de sauvegarde de vos fichiers avec l'extension \texttt{.bak}, il peut
être intéressant de systématiquement mettre de côté ces fichiers en
positionnant la propriété correspondante~:

\begin{code}
$ svn propset svn:ignore *.bak .
property 'svn:ignore' set on '.'
\end{code}
Une autre utilisation intéressante concerne l'utilisation de
mots-clés. Ceux-ci sont des identifiants insérés dans les fichiers du
projet et qui seront remplacés au moment du \emph{commit} par des
informations propres à \texttt{Subversion}, comme le nom du fichier, le
numéro de révision, l'auteur et la date de la dernière modification,
etc.\\

Par exemple, si vous insérez la chaîne \texttt{\$Id\$} dans votre fichier,
celle-ci sera automatiquement remplacée par un résumé de ces
informations. Voici la valeur correspondant au fichier source de ce
document~:

\begin{code}
$Id: formation_svn.tex 135 2005-08-02 09:47:51Z julien $
\end{code}
Pour que ces mots-clés fonctionnent, il faut positionner la propriété
\texttt{svn:keywords} de manière adéquate pour les fichiers concernés~:

\begin{code}
$ svn propset svn:keywords "Id" index.htm 
property 'svn:keywords' set on 'index.htm'
\end{code}

\section{Clients graphiques}

\subsection{Intérêt d'un client graphique}

Les clients graphiques ne permettent pas de faire plus, mais proposent
des interfaces plus élaborées que la ligne de commande. Ils permettent
notamment de naviguer dans le dépôt comme dans un explorateur de
fichiers, d'afficher les informations de manière plus structurée, de
garder un historique des logs saisis, etc.\\

\texttt{TortoiseSVN}, par exemple, est un client particulièrement bien
intégré à Windows, puisqu'il s'ajoute directement au menu contextuel
de l'explorateur de fichiers. Les commandes sont les mêmes que celles
décrites dans ce document, mais elles sont lancées par un menu et
bénéficient d'interfaces graphiques plus conviviales.



\section{Ressources}

\begin{itemize}
\item Site officiel de Subversion~:\\
\url{http://subversion.tigris.org/}
\item FAQ de Subversion~:\\
\url{http://subversion.tigris.org/faq.html}
\item Documentation complète (en anglais)~:\\
\url{http://svnbook.red-bean.com/}
\item Un tutoriel en français~:\\
\url{http://toutprogrammer.com/print_19.html}
\item Documentation de TortoiseSVN (en anglais)~:\\
\url{http://tortoisesvn.tigris.org/docs.html}
\end{itemize}


\section{À propos de ce document}

Ce document est publié sous licence \textit{Creative Commons
  Attribution}. Vous pouvez voir une copie de cette licence à
l'adresse \url{http://creativecommons.org/licenses/by/2.5/}.\\

Copyright \copyright{} 2005 Julien Barnier.\\

Pour tout commentaire ou suggestion, n'hésitez pas à m'écrire à
l'adresse \url{julien (at) nozav.org}.



\end{document}
