Si je supprime un fichier dans Subversion, comment puis-je consulter son historique et son contenu? Si j'essaie de faire svn cat
ou svn log
sur un fichier inexistant, il se plaint que le fichier n'existe pas.
De plus, si je voulais ressusciter le fichier, devrais-je simplement svn add
le retour?
(J'ai spécifiquement posé des questions sur Subversion, mais j'aimerais également savoir comment Bazaar, Mercurial et Git gèrent cette affaire également.)
Pour obtenir le journal d’un fichier supprimé, utilisez
svn log -r lastrevisionthefileexisted
Si vous souhaitez ressusciter le fichier et conserver l'historique de ses versions, utilisez
svn copy url/of/file@lastrevisionthefileexisted -r lastrevisionthefileexisted path/to/workingcopy/file
Si vous voulez seulement le contenu du fichier mais sans version (par exemple, pour une inspection rapide), utilisez
svn cat url/of/file@lastrevisionthefileexisted -r latrevisionthefileexisted > file
Dans tous les cas, NE PAS utiliser 'svn up' pour récupérer un fichier supprimé!
Lorsque vous souhaitez consulter d'anciens fichiers, vous devez vraiment connaître la différence entre:
svn cat http://server/svn/project/file -r 1234
et
svn cat http://server/svn/project/file@1234
La première version regarde le chemin qui est maintenant disponible en tant que http: // serveur/svn/projet/fichier et récupère ce fichier tel qu'il était dans la révision 1234. (Donc, cette syntaxe ne ( ne fonctionne pas ne fonctionne après une suppression de fichier)).
La deuxième syntaxe récupère le fichier disponible sous la forme http: // serveur/svn/projet/fichier dans la révision 1234. Cette syntaxe [~ # ~] [~ # ~] fonctionne sur les fichiers supprimés.
Vous pouvez même combiner ces méthodes pour récupérer un fichier disponible dans la révision 2345 en tant que http: // serveur/svn/project/fichier mais avec le contenu tel qu’il était en 1234 avec:
svn cat http://server/svn/project/file@2345 -r 1234
Premièrement, trouvez le numéro de révision où le fichier a été supprimé:
svn log -v > log.txt
Puis cherchez dans log.txt (pas un gourou SVN, donc je ne connais pas de meilleur moyen) pour une ligne avec
D <deleted file>
et voir quelle révision c'était. Ensuite, comme dans les autres réponses, ressuscitez le fichier en utilisant la révision précédente.
Il n'y a rien de particulièrement spécial dans git. Si vous connaissez le nom du fichier, vous pouvez trouver la modification qui l'a supprimé avec log:
git log -n 1 -- filename
Vous pouvez ensuite utiliser ce commit pour obtenir le fichier tel qu’il existait avant la suppression.
git checkout [last_revision]^ filename
dhcp-120:/tmp/slosh 587% ls -l slosh.tac
ls: slosh.tac: No such file or directory
dhcp-120:/tmp/slosh 588% git log -n 1 -- slosh.tac
commit 8d4a1f1a94e4aa37c1cb9d329a140d08eec1b587
Author: Dustin Sallings <[email protected]>
Date: Mon Dec 15 11:25:00 2008 -0800
Get rid of a .conf and replace it with .tac.
dhcp-120:/tmp/slosh 589% git checkout 8d4a1f^ slosh.tac
dhcp-120:/tmp/slosh 590% ll slosh.tac
-rw------- 1 dustin wheel 822 Dec 30 12:52 slosh.tac
Notez que cela ne remet pas le fichier dans le contrôle de révision. Il laisse simplement le fichier tel qu'il existait dans son état final à l'emplacement actuel. Vous pouvez ensuite l'ajouter ou simplement l'inspecter ou autre chose à partir de là.
Une solution utilisant uniquement l'interface graphique:
Si vous connaissez le nom du fichier mais ne connaît pas son dernier numéro de révision ou même son chemin:
Ceci affichera alors uniquement les révisions où le fichier a été ajouté/modifié/supprimé. Ceci est votre historique du fichier.
Notez que si le fichier a été supprimé en supprimant l'un de ses dossiers parents, il n'aura pas d'entrée "supprimé" dans le journal (et la solution de mjy ne fonctionnera donc pas). Dans ce cas, son entrée la plus récente dans le journal filtré correspondra à son contenu lors de la suppression.
svn log -v | grep -B50 YourDeletedFileName
Vous obtiendrez le chemin et la révision. Dans git (vérifie également les renames):
git log --diff-filter=DR --name-only | grep -B50 YourDeletedFileName
En plus de la réponse de Dustin, si vous voulez simplement examiner le contenu, et non le vérifier, dans son exemple, vous pouvez faire:
$ git show 8d4a1f^:slosh.tac
the: sépare une révision et un chemin dans cette révision, demandant effectivement un chemin spécifique à une révision spécifique.
Utilisez cette commande:
svn log -v | awk '/^r[0-9]+/ { rev = $1; }; / D .*filename_escaped_for_regex/ { print rev" "$2; };'
Ceci listera toutes les révisions qui ont déjà effacé tous les fichiers correspondant au motif. Autrement dit, si vous recherchez le fichier LISEZMOI, tous les /src/README
, /src/README.first
, et /some/deeply/hidden/directory/READMENOT
sera trouvé et répertorié.
Si votre nom du fichier contient des barres obliques (chemin d'accès), des points ou d'autres caractères de regex spéciaux, n'oubliez pas de les échapper pour éviter les erreurs de correspondance et les erreurs.
Si vous ne connaissez pas le chemin du fichier supprimé, vous pouvez rechercher le dans le trop lourd svn log
commande:
svn log --search <deleted_file_or_pattern> -v
La commande martèle probablement le serveur autant qu'elle le ferait sans l'option de recherche, mais au moins le reste des ressources impliquées (y compris vos yeux) serait un peu soulagé, car cela vous dira dans quelle révision ce fichier a été supprimé. Ensuite, vous pouvez suivre les autres conseils (principalement en utilisant le même svn log
commande, mais déjà sur un chemin défini).
L'affiche a effectivement posé 3 questions ici:
Toutes les réponses que je vois ici sont pour les questions 2 et 3.
La réponse à la question 1 est:
svn log http://server/svn/project/file@1234
Vous devez toujours obtenir le numéro de révision pour la dernière fois que le fichier a existé, ce à quoi d'autres personnes répondent clairement.
Ah, depuis que j'apprends à utiliser Bazaar, c'est quelque chose que j'ai essayé. Sans succès, il semble que vous ne puissiez pas enregistrer et annoter les fichiers supprimés actuellement ... :-(
A tenté:
> bzr log -r 3 Stuff/ErrorParser.hta
bzr: ERROR: Path does not have any revision history: Stuff/ErrorParser.hta
mais curieusement (et heureusement) je peux faire:
> bzr cat -r 3 Stuff/ErrorParser.hta
et:
> bzr diff -r 2..3 Stuff/ErrorParser.hta
et comme suggéré dans le bug ci-dessus:
> bzr log -v | grep -B 1 ErrorParser
(régler -B
(--before-context
) paramètre si nécessaire).
Je voulais une réponse, moi-même. Essayez ce qui suit pour sortir uniquement les suppressions de svn log
.
svn log --stop-on-copy --verbose [--limit <limit>] <repo Url> | \
awk '{ if ($0 ~ /^r[0-9]+/) rev = $0 }
{ if ($0 ~ /^ D /) { if (rev != "") { print rev; rev = "" }; print $0 } }'
Ceci filtre la sortie du journal à travers awk. awk met en mémoire tampon chaque ligne de révision trouvée, en ne la sortant que lorsqu'un enregistrement de suppression est trouvé. Chaque révision n'est sortie qu'une seule fois. Par conséquent, les suppressions multiples d'une révision sont regroupées (comme dans la norme svn log
sortie).
Vous pouvez spécifier un --limit
pour réduire le nombre d'enregistrements renvoyés. Vous pouvez aussi enlever le --stop-on-copy
, comme requis.
Je sais qu'il y a des plaintes concernant l'efficacité de l'analyse de tout le journal. Je pense que c'est une meilleure solution que grep et son "jetez un large filet" -B
option. Je ne sais pas si c'est plus efficace, mais je ne peux pas penser à une alternative à svn log
. Cela ressemble à la réponse de @Alexander Amelkin, mais n'a pas besoin d'un nom spécifique. C'est aussi mon premier awk script, il est donc peut-être peu conventionnel.
Si vous souhaitez consulter l'historique d'un fichier avant qu'il ne soit renommé, alors comme mentionné dans n commentaire ici vous pouvez utiliser
git log --follow -- current_file_name
Vous devrez spécifier une révision.
svn log -r <revision> <deleted file>
Vous pouvez trouver la dernière révision qui fournit le fichier en utilisant la recherche binaire. J'ai créé un simple /bin/bash
script pour cela:
function svnFindLast(){
# The URL of the file to be found
local URL="$1"
# The SVN revision number which the file appears in (any rev where the file DOES exist)
local r="$2"
local R
for i in $(seq 1 "${#URL}")
do
echo "checkingURL:'${URL:0:$i}'" >&2
R="$(svn info --show-item revision "${URL:0:$i}" 2>/dev/null)"
echo "R=$R" >&2
[ -z "$R" ] || break
done
[ "$R" ] || {
echo "It seems '$URL' is not in a valid SVN repository!" >&2
return -1
}
while [ "$r" -ne "$R" -a "$(($r + 1))" -ne "$R" ]
do
T="$(($(($R + $r)) / 2))"
if svn log "${URL}@${T}" >/dev/null 2>&1
then
r="$T"
echo "r=$r" >&2
else
R="$T"
echo "R=$R" >&2
fi
done
echo "$r"
}
J'ai écrit un script php qui copie le journal svn de tous mes référentiels dans une base de données mysql. Je peux maintenant effectuer des recherches en texte intégral sur mes commentaires ou les noms de fichiers.
Supposons que votre fichier porte le nom ~/src/a/b/c/delete.file.
cd ~/src/a/b/c # to the directory where you do the svn rm or svn mv command
#cd ~/src # if you forget the correct directory, just to the root of repository
svn log -v | grep -w -B 9 deleted.file | head # head show first 10 lines
exemple de sortie, trouvé à r90440
...
r90440 | user | 2017-02-03 11:55:09 +0800 (Fri, 03 Feb 2017) | 4 lines
Changed paths:
M /src/a/b/c/foo
M /src/a/b/c/bar
D /src/a/b/c/deleted.file
recopiez-le dans la version précédente (90439 = 90440-1)
svn cp URL_of_deleted.file@90439 .