Bien que connaissant VCS (utilisateur régulier de svn, git et git-svn), je n'arrive pas à comprendre ce comportement singulier de SVN.
Chaque fois que je dois renommer un répertoire de ma copie de travail SVN à partir d'un état "propre" - c'est-à-dire svn status
ne renvoie rien et toutes les autres modifications ont été validées - comme tel (ce que suggère le document svn):
svn mv foo bar
svn commit
SVN se plaint fort:
Adding bar
Adding bar/toto
Deleting foo
svn: Commit failed (details follow):
svn: Item '/test/foo' is out of date
Comme vous le souhaitez:
svn update
Qui donne:
C foo
At revision 46.
Summary of conflicts:
Tree conflicts: 1
Il y a un conflit d'arbre, alors qu'aucun changement tiers n'a eu lie. De toute évidence, le seul moyen de sortir de ce désordre conflictuel est génériquement (d'après le livre rouge svn):
svn resolve --accept working -R .
svn commit
Renommer à distance sur le référentiel puis mettre à jour ma copie de travail me semble tout à fait inutile:
url=$(svn info | grep -e '^URL:' | sed 's/^URL: //') svn mv $url/foo $url/bar
svn update
Existe-t-il un moyen plus rationalisé et approuvé de renommer un dossier qui me manque? Quelle est la cause fondamentale de cet état de conflit de l’arbre particulièrement surprenant?
svn mv
travaille pour moi:
C:\svn\co>svn mv my_dir new_dir
A new_dir
D my_dir\New Text Document.txt
D my_dir
C:\svn\co>svn commit -m foo
Raderar my_dir
Lägger till new_dir
Arkiverade revision 2.
C:\svn\co>
Désolé pour la sortie suédoise de svn.
Il doit y avoir quelque chose d'autre qui ne va pas dans votre cas.
Edit:
Comme indiqué dans les commentaires de Lloeki
Pour reproduire le problème, vous devez également mettre à jour et valider un fichier contenu dans le dossier, sans mettre à jour le dossier lui-même.
file commit crée une nouvelle révision sur le référentiel, mais les métadonnées locales ne sont pas mises à jour (comme cela a toujours été le cas, reportez-vous à svn log après toute validation), ainsi les métadonnées dir sont à la révision n-1. Il s'ensuit que svn ne s'engagera pas à cause des différences de métadonnées et qu'il ne se mettra pas à jour car il y a effectivement un conflit dans le répertoire dir: metadata update vs delete.
Le comportement est "attendu" et la "solution" consiste à mettre à jour la copie de travail avant d'émettre le svn rename
commande.
OK, je me suis heurté à cela - et je peux enfin reconstruire le problème avec une simple session de terminal: le problème se produit si vous svn mv
(déplacer/renommer) un fichier; alors engagez ce changement; then ( sans faire un svn update
première), svn mv
le répertoire parent du fichier dont le déplacement/changement de nom a déjà été validé - et enfin faire un svn commit
lors de la modification du nom du répertoire - ou comme réponse acceptée le dit: " vous devez également mettre à jour et valider un fichier contenu dans le dossier, mais pas mettre à jour le dossier lui-même "; mais tout cela est exécuté dans un répertoire parent (ou plutôt, ancêtre). Voici le journal de ligne de commande démontrant le problème:
$ cd /tmp
$ svnadmin create myrepo
$ svn co file:///tmp/myrepo myrepo-wc
Checked out revision 0.
$ cd myrepo-wc/
$ mkdir -p dir1/dir2/dir3
$ svn add dir1/
A dir1
A dir1/dir2
A dir1/dir2/dir3
$ svn ci -m 'add dir1/'
Adding dir1
Adding dir1/dir2
Adding dir1/dir2/dir3
Committed revision 1.
$ echo test1 >> dir1/dir2/dir3/test1.txt
$ echo test2 >> dir1/dir2/dir3/test2.txt
$ svn add dir1/
svn: warning: 'dir1' is already under version control
$ svn add dir1/*
svn: warning: 'dir1/dir2' is already under version control
$ svn add dir1/dir2/dir3/*
A dir1/dir2/dir3/test1.txt
A dir1/dir2/dir3/test2.txt
$ svn status
A dir1/dir2/dir3/test2.txt
A dir1/dir2/dir3/test1.txt
$ svn ci -m 'add dir1/dir2/dir3/*'
Adding dir1/dir2/dir3/test1.txt
Adding dir1/dir2/dir3/test2.txt
Transmitting file data ..
Committed revision 2.
$ svn mv dir1/dir2/dir3/test2.txt dir1/dir2/dir3/test2X.txt
A dir1/dir2/dir3/test2X.txt
D dir1/dir2/dir3/test2.txt
$ svn status
D dir1/dir2/dir3/test2.txt
A + dir1/dir2/dir3/test2X.txt
$ svn ci -m 'mv dir1/dir2/dir3/test2.txt dir1/dir2/dir3/test2X.txt'
Deleting dir1/dir2/dir3/test2.txt
Adding dir1/dir2/dir3/test2X.txt
Committed revision 3.
$ svn status
$ svn mv dir1/dir2/dir3 dir1/dir2/dir3X
A dir1/dir2/dir3X
D dir1/dir2/dir3/test2X.txt
D dir1/dir2/dir3/test1.txt
D dir1/dir2/dir3
$ svn status
D dir1/dir2/dir3
D dir1/dir2/dir3/test2X.txt
D dir1/dir2/dir3/test1.txt
A + dir1/dir2/dir3X
D + dir1/dir2/dir3X/test2.txt
$ svn ci -m 'mv dir1/dir2/dir3 dir1/dir2/dir3X'
Deleting dir1/dir2/dir3
svn: Commit failed (details follow):
svn: Directory '/dir1/dir2/dir3' is out of date
$ svn status
D dir1/dir2/dir3
D dir1/dir2/dir3/test2X.txt
D dir1/dir2/dir3/test1.txt
A + dir1/dir2/dir3X
D + dir1/dir2/dir3X/test2.txt
$ svn up
C dir1/dir2/dir3
At revision 3.
Summary of conflicts:
Tree conflicts: 1
Et voici comment il aurait dû être - faire un svn up
après que le fichier soit déplacé/renommé; notez comment les numéros de version rapportés par svn status -v
changement après le svn update
commande:
$ cd /tmp
$ rm -rf myrepo*
$ svnadmin create myrepo
$ svn co file:///tmp/myrepo myrepo-wc
Checked out revision 0.
$ cd myrepo-wc/
$ mkdir -p dir1/dir2/dir3
$ svn add dir1/
A dir1
A dir1/dir2
A dir1/dir2/dir3
$ svn ci -m 'add dir1/'
Adding dir1
Adding dir1/dir2
Adding dir1/dir2/dir3
Committed revision 1.
$ echo test1 >> dir1/dir2/dir3/test1.txt
$ echo test2 >> dir1/dir2/dir3/test2.txt
$ svn add dir1/dir2/dir3/*
A dir1/dir2/dir3/test1.txt
A dir1/dir2/dir3/test2.txt
$ svn status
A dir1/dir2/dir3/test2.txt
A dir1/dir2/dir3/test1.txt
$ svn ci -m 'add dir1/dir2/dir3/*'
Adding dir1/dir2/dir3/test1.txt
Adding dir1/dir2/dir3/test2.txt
Transmitting file data ..
Committed revision 2.
$ svn mv dir1/dir2/dir3/test2.txt dir1/dir2/dir3/test2X.txt
A dir1/dir2/dir3/test2X.txt
D dir1/dir2/dir3/test2.txt
$ svn status
D dir1/dir2/dir3/test2.txt
A + dir1/dir2/dir3/test2X.txt
$ svn ci -m 'mv dir1/dir2/dir3/test2.txt dir1/dir2/dir3/test2X.txt'
Deleting dir1/dir2/dir3/test2.txt
Adding dir1/dir2/dir3/test2X.txt
Committed revision 3.
$ svn status
$ svn status -v
0 0 ? .
1 1 username dir1
1 1 username dir1/dir2
1 1 username dir1/dir2/dir3
3 3 username dir1/dir2/dir3/test2X.txt
2 2 username dir1/dir2/dir3/test1.txt
$ svn up
At revision 3.
$ svn status -v
3 3 username .
3 3 username dir1
3 3 username dir1/dir2
3 3 username dir1/dir2/dir3
3 3 username dir1/dir2/dir3/test2X.txt
3 2 username dir1/dir2/dir3/test1.txt
$ svn mv dir1/dir2/dir3 dir1/dir2/dir3X
A dir1/dir2/dir3X
D dir1/dir2/dir3/test2X.txt
D dir1/dir2/dir3/test1.txt
D dir1/dir2/dir3
$ svn status
D dir1/dir2/dir3
D dir1/dir2/dir3/test2X.txt
D dir1/dir2/dir3/test1.txt
A + dir1/dir2/dir3X
$ svn ci -m 'mv dir1/dir2/dir3 dir1/dir2/dir3X'
Deleting dir1/dir2/dir3
Adding dir1/dir2/dir3X
Committed revision 4.
$ svn status
$ svn status -v
3 3 username .
3 3 username dir1
3 3 username dir1/dir2
4 4 username dir1/dir2/dir3X
4 4 username dir1/dir2/dir3X/test2X.txt
4 4 username dir1/dir2/dir3X/test1.txt
$ svn up
At revision 4.
$ svn status -v
4 4 username .
4 4 username dir1
4 4 username dir1/dir2
4 4 username dir1/dir2/dir3X
4 4 username dir1/dir2/dir3X/test2X.txt
4 4 username dir1/dir2/dir3X/test1.txt
Et comme l’a dit OP - faut-il oublier de faire le svn update
avant un nouveau déplacement/changement de nom + commit, et que le "commit échoué" se soit produit - on peut alors utiliser svn resolve --accept working -R .
pour pouvoir terminer l'action commit.
Cela a fonctionné pour moi:
vi someotherfile
...various changes to the other file
svn mv olddir newdir
svn commit -m"Moved olddir out of the way" olddir
svn commit -m"New location of olddir" newdir
svn update
svn commit -m"Changed someotherfile" someotherfile
Je soupçonne qu'il y avait plusieurs autres moyens possibles et qu'avoir un répertoire de travail propre avant de faire la commande svn mv aurait également fait l'affaire.
On pourrait penser à un scénario dans lequel le répertoire a été modifié dans le référentiel par un autre utilisateur. Renommer le même dossier dans votre copie de travail peut déclencher des conflits d'arborescence lors de la validation.
Résolution des conflits montre comment résoudre les "conflits d'arborescence" dans Subversion.