Visualizzazione post con etichetta svn. Mostra tutti i post
Visualizzazione post con etichetta svn. Mostra tutti i post

venerdì 10 dicembre 2010

How to mirror a remote subversion repository

When dealing with a remote repository the svnadmin command doesn't work, because it can only be used on the machine that holds the repository. But Subversion meets our need with the svnsycn command.

Svnsync works by essentially asking the Subversion server to “replay” revisions, one at a time. Neither the source nor the target repository needs to be locally accessible to machine on which svnsync is running, all the requirements are read access to the source repository and read/write access to the target/mirror repository.

Svnsync stores its bookkeeping information in special revision properties on revision 0 of the destination repository, but in order to make changes to revision properties you'll need to explicitly implement the pre-revprop-change hook, and your script must allow svnsync to set and change its special properties.

Let's see a script for local mirroring a remote svn repository:

TARGET_REPO_PATH=/tmp/svn/mirror_repo
SOURCE_REPO_PATH=https://xyz.svn.sourceforge.net/svnroot/xyz
SOURCE_REPO_USER=anonymous

svnadmin create $TARGET_REPO_PATH
echo '#!/bin/sh' > $TARGET_REPO_PATH/hooks/pre-revprop-change
chmod +x $TARGET_REPO_PATH/hooks/pre-revprop-change
svnsync init file://$TARGET_REPO_PATH $SOURCE_REPO_PATH --source-username $SOURCE_REPO_USER
svnsync sync file://$TARGET_REPO_PATH --source-username $SOURCE_REPO_USER


In line 5 we create the local target repository

In lines 6 and 7 we create the pre-revprop-change hook and make it executable

In line 8  we register in our target repository the fact that it will be a mirror of the source repository. We do this using the svnsync initialize subcommand. Our target repository will now remember that it is a mirror of the public Subversion source code repository (in Subversion 1.5, you can use svnsync to mirror only some subtree of the repository)

In line 9  with a single subcommand, we can tell svnsync to copy all the as-yet-unmirrored revisions from the source repository to the target. Svnsync performs careful bookkeeping that allows it to be safely interrupted and restarted without ruining the integrity of the mirrored data.
Do not modify a mirror repository in such a way as to cause its version history to deviate from that of the repository it mirrors. The only commits and revision property modifications that ever occur on that mirror repository should be those performed by the svnsync tool.

Whenever we want to update the mirror applying the changes from the remote source repository we just have to call the svnsync sync command as in line 9 of the example script.


Copyright note: most of this post comes from Version Control with Subversion.

See also:

Version Control with Subversion - Repository Administration - Repository Replication
Version Control with Subversion - Repository Administration - Implementing Repository Hooks
Version Control with Subversion - Repository Hooks - pre-revprop-change

giovedì 18 novembre 2010

Merge tracking con Subversion 1.5

Una delle novità introdotte nella versione 1.5 di Subversion è la capacità di tenere traccia dei merge, ovvero include quelle funzionalità che prima venivano garantite da tool esterni come lo script python svnmerge.py.

La storia dei merge effettuati viene mantenuta tramite la proprietà svn:mergeinfo.

Supponiamo di avere nel trunk il ramo di sviluppo principale e di avere su un branch chiamato feature_dev gli sviluppi relativi ad una nuova funzionalità. Alla fine dello sviluppo il branch feature_dev dovrà essere riportato sul trunk.

I percorsi svn coinvolti sono:
  • https://svn.sinossi.it/svn/myproject/trunk
  • https://svn.sinossi.it/svn/myproject/branches/feature_dev
I comandi messi a disposizione da SVN per gestire il merge sono:
  • svn merge
  • svn mergeinfo

Il primo serve per effettuare il merge vero e proprio, il secondo mostra delle informazioni relative ai merge.

Poichè la destinazione del merge è il trunk usiamo questo come working copy. Vediamo lo stato attuale del merge
> svn co https://svn.sinossi.it/svn/myproject/trunk
> cd trunk
trunk> svn mergeinfo https://svn.sinossi.it/svn/myproject/branches/feature_dev
[nessun output]
trunk> svn mergeinfo --show-revs eligible https://svn.sinossi.it/svn/myproject/branches/feature_dev
r195
r196
r197
r198
r220
r221

Poichè ci interessa modificare il trunk usiamo quello come working copy, e come indirizzo di confronto quello del branch feature_dev, che è quello di rispetto a cui vogliamo conoscere lo stato dei merge fatti e/o da fare.
Il primo comando mostra l'elenco dei commit che sono stati riportati da feature_dev verso trunk (non essendo stato ancora effettuato nessun merge non è indicata nessuna revisione); il comando mergeinfo con l'opzione --show-revs eligible mostra i commit che sono stati effettuati su feature_dev e non sono ancora stati portati sul trunk.

Tramite il comando
> svn log https://svn.sinossi.it/svn/myproject/branches/feature_dev
siamo in grado di capire quali commit debbano essere riportati sul trunk e quali no.

Supponiamo di voler riportare il commit 198, il comando sarà
trunk> svn merge -c 198 https://svn.sinossi.it/svn/myproject/branches/feature_dev
trunk> svn commit -m "rientro del branch feature_dev"

Questo applicherà sul trunk le mofiche relative al commit 198 effettuato sul branch feature_dev.
Le modifiche effettuate da svn merge sono locali, quindi per renderle effettive sarà necessario committare.

Se prima di committare si lancia il comando svn status si noterà che molte cartelle sono state modificate, più di quelle coinvolte nel commit 198, questo perchè è stata aggiunta la proprietà svn:mergeinfo che tiene appunto memeoria dei merge effettuati.

Se ora riproviamo ad esaminare lo stato dei merge avremo
trunk> svn mergeinfo https://svn.sinossi.it/svn/myproject/branches/feature_dev
r198
trunk> svn mergeinfo --show-revs eligible https://svn.sinossi.it/svn/myproject/branches/feature_dev
r195
r196
r197
r220
r221
Quindi il commit 198 risulta riportato sul trunk, gli altri sono ancora disponibili.
Supponiamo di sapere che i commit 195,196,197 non debbano essere portati, svn merge permette di considerare i commit come integrati anche senza riportare realmente sul trunk le modifiche, questo può essere fatto tramite l'opzione --record-only
trunk> svn merge --record-only -c 195,196,197 https://svn.sinossi.it/svn/myproject/branches/feature_dev
trunk> svn commit -m "rientro del branch feature_dev"
Il commit è necessario per aggiornare nel repository lo stato della proprietà svn:mergeinfo, ma con l'opzione --read-only non viene apportata nessuna modifica ai nostri file.
A questo punto lo stato è:
trunk> svn mergeinfo https://svn.sinossi.it/svn/myproject/branches/feature_dev
r195
r196
r197
r198
trunk> svn mergeinfo --show-revs eligible https://svn.sinossi.it/svn/myproject/branches/feature_dev
r220
r221
Ora le commit 195, 196 e 197 risultano integrate.


Come ulteriore esempio vediamo il caso in cui si voglia aggiornare un tag riportando un commit effettuato sul trunk.
I rami coinvolti sono
  • https://svn.sinossi.it/svn/myproject/trunk
  • https://svn.sinossi.it/svn/myproject/tags/1.0.3

Poichè la destinazione del merge è il tag usiamo questo come working copy un checkout del tag 1.0.3.
> svn co https://svn.sinossi.it/svn/myproject/tags/1.0.3
> cd 1.0.3
1.0.3> svn mergeinfo https://svn.sinossi.it/svn/myproject/trunk
[nessun output]
1.0.3> svn mergeinfo --show-revs eligible https://svn.sinossi.it/svn/myproject/trunk
r234
r237
r238
Il commit che si vuole riportare è il 238:
trunk> svn merge -c 238 https://svn.sinossi.it/svn/myproject/trunk
trunk> svn commit -m "aggiornamento del tag 1.0.3"
Lo stato del merge ora sarà:
1.0.3> svn mergeinfo https://svn.sinossi.it/svn/myproject/trunk
r238
1.0.3> svn mergeinfo --show-revs eligible https://svn.sinossi.it/svn/myproject/trunk
r234
r237


Per sfruttare al meglio le funzionalità introdotte con il tracking dei merge è stata aggiunta l'opzione -g (oppure --use-merge-history) ai comandi svn log e svn blame, ciò permette di utilizzare le informazioni relative ai merge nell'output di questi comandi.
Come ultima indicazione, per chi ha utilizzato lo script svnmerge.py per tracciare i merge, è disponibile lo script svnmerge-migrate-history.py che consente di migrare alla modalità di merge di Subversion 1.5 senza perdere lo storico delle informazioni di merge accumulate.


Per maggiorni informazioni vedere anche:

Subversion 1.5 release notes
svn merge
svn mergeinfo
svnmerge.py