Un référentiel svn que je mets en miroir via git-svn a changé d'URL.
Dans Vanilla svn, vous feriez simplement svn switch --relocate old_url_base new_url_base
.
Comment puis-je faire cela en utilisant git-svn?
La simple modification de l'URL svn dans le fichier de configuration échoue.
Cela gère assez bien ma situation:
https://git.wiki.kernel.org/index.php/GitSvnSwitch
J'ai cloné en utilisant le file://
et souhaitait passer au http://
protocole.
Il est tentant de modifier le paramètre url
dans le [svn-remote "svn"]
section de .git/config
, mais en soi, cela ne fonctionne pas. En général, vous devez suivre la procédure suivante:
url
vers le nouveau nom.git svn fetch
. Cela doit récupérer au moins une nouvelle révision de svn!url
par l'URL d'origine.git svn rebase -l
pour effectuer un rebase local (avec les modifications apportées lors de la dernière opération d'extraction).url
par la nouvelle URL.git svn rebase
devrait fonctionner à nouveau.Les âmes aventureuses voudront peut-être essayer --rewrite-root
.
Vous pouvez voir si les éléments suivants fonctionnent correctement:
Si svn-remote.svn.rewriteRoot
n'existe pas dans le fichier de configuration (.git/config
):
git config svn-remote.svn.rewriteRoot <currentRepositoryURL>
Si svn-remote.svn.rewriteUUID
n'existe pas dans le fichier de configuration:
git config svn-remote.svn.rewriteUUID <currentRepositoryUUID>
currentRepositoryUUID
peut être obtenu auprès de .git/svn/.metadata
.
git config svn-remote.svn.url <newRepositoryURL>
Malheureusement, la plupart des liens dans ces réponses ne fonctionnent pas, donc je vais dupliquer un peu d'informations du git wiki pour référence future.
Cette solution a fonctionné pour moi:
Modifiez le svn-remote
url
(ou fetch
chemin) dans .git/config
pour pointer vers le nouveau domaine/url/chemin
Exécutez git git svn fetch
. Cela doit récupérer au moins une nouvelle révision de svn!
Si vous essayez git svn rebase
maintenant, vous obtiendrez un message d'erreur comme celui-ci:
Unable to determine upstream SVN information from working tree history
Je pense que c'est parce que git svn
est troublé par le fait que votre dernier commit avant l'extraction aura un git-svn-id
pointant vers l'ancien chemin, qui ne correspond pas à celui trouvé dans .git/config
.
Pour contourner ce problème, modifiez svn-remote
url
(ou fetch
chemin) vers le domaine/url/chemin d'origine
Exécutez maintenant git svn rebase -l
à nouveau pour effectuer un rebasage local avec les modifications apportées lors de la dernière opération d'extraction. Cette fois, cela fonctionnera , apparemment parce que git svn
ne sera pas dérouté par le fait que git-svn-id
de la nouvelle tête ne correspond pas à celle trouvée dans .git/config
.
Enfin, modifiez svn-remote
url
(ou fetch
chemin) vers le nouveau domaine/url/chemin
À ce point git svn rebase
devrait fonctionner à nouveau!
Les informations d'origine ont été trouvées ici .
Git svn s'appuie fortement sur l'URL svn. Chaque commit importé de svn a un git-svn-id
qui inclut l'URL svn.
Une stratégie de relocalisation valide consiste à appeler git-svn clone
sur le nouveau référentiel et fusionner les modifications dans cette nouvelle fermeture. Pour une procédure plus détaillée, consultez cet article:
http://www.sanityinc.com/articles/relocating-git-svn-repositories
git filter-branch
Ce script , tiré de ne entrée de blog , a fonctionné pour moi. Fournissez l'ancien et le nouveau URL de dépôt en tant que paramètre, comme pour svn switch --relocate
.
Le script appelle git filter-branch
pour remplacer les URL Subversion dans le git-svn-id
dans les messages de validation, met à jour .git/config
, et met également à jour git-svn
métadonnées en les recréant à l'aide de git svn rebase
. Tandis que git svn clone
pourrait être la solution la plus robuste, le filter-branch
L'approche fonctionne beaucoup plus rapidement pour les grands référentiels (heures vs jours).
#!/bin/sh
# Must be called with two command-line args.
# Example: git-svn-relocate.sh http://old.server https://new.server
if [ $# -ne 2 ]
then
echo "Please invoke this script with two command-line arguments (old and new SVN URLs)."
exit $E_NO_ARGS
fi
# Prepare URLs for regex search and replace.
oldUrl=`echo $1 | awk '{gsub("[\\\.]", "\\\\\\\&");print}'`
newUrl=`echo $2 | awk '{gsub("[\\\&]", "\\\\\\\&");print}'`
filter="sed \"s|^git-svn-id: $oldUrl|git-svn-id: $newUrl|g\""
git filter-branch --msg-filter "$filter" -- --all
sed -i.backup -e "s|$oldUrl|$newUrl|g" .git/config
rm -rf .git/svn
git svn rebase
git_fast_filter
Pourtant, plus rapide que git-filter-branch
(c.-à-d. minutes au lieu d'heures), mais similaire dans son esprit, consiste à utiliser git_fast_filter
. Cependant, cela nécessite un peu plus de codage, et il n'existe aucune solution soignée prête à l'emploi. Contrairement à git-filter-branch
, cela créera un nouveau dépôt à partir d'un ancien . Il est supposé que master
pointe vers le dernier commit SVN.
git_fast_filter
du repo Gitorious.git_fast_filter
basé sur cet Gist , définissez le bit exécutable en utilisant chmod +x
. Adaptez les anciens et nouveaux chemins de référentiel. (Le contenu du script est également collé ci-dessous.)git init
, changez le répertoire de travail en ce nouveau dépôt.Exécutez le canal suivant:
(cd path/to/old/repo && git-fast-export --branches --tags --progress=100) | \
path/to/git_fast_filter/commit_filter.py | git-fast-import
Copie .git/config
, et peut-être d'autres fichiers pertinents dans .git/info
de l'ancien référentiel au nouveau référentiel.
.git/svn
.Faire git-svn
au courant du nouveau mappage des numéros de révision
Exécutez git branch refs/remotes/git-svn master
refs/remotes/git-svn
, consulter .git/config
, svn-remote
sectionsExécutez git svn info
. Si cette commande se bloque, quelque chose ne va pas. Il devrait reconstruire le mappage du numéro de révision.
Retirez la fausse branche refs/remotes/git-svn
, il sera recréé par git-svn
git svn rebase
.Voici le contenu de commit_filter.py
, remplacez les valeurs de IN_REPO
et OUT_REPO
selon le cas:
#!/usr/bin/python
from git_fast_filter import Commit, FastExportFilter
import re
import sys
IN_REPO = "https://svn.code.sf.net/p/matsim/code"
OUT_REPO = "https://svn.code.sf.net/p/matsim/source"
IN_REPO_RE = re.compile("^git-svn-id: %s" % re.escape(IN_REPO), re.M)
OUT_REPO_RE = "git-svn-id: %s" % OUT_REPO
def my_commit_callback(commit):
commit.message = IN_REPO_RE.sub(OUT_REPO_RE, commit.message)
sys.stderr.write(".")
filter = FastExportFilter(commit_callback = my_commit_callback)
filter.run()
Sur la base de certaines des autres réponses à cette question, j'ai trouvé un script Ruby qui gère la relocalisation de git-svn. Vous pouvez le trouver sur https: // Gist.github.com/henderea/6e779b66be3580c9a584 .
Il gère la relocalisation sans extraire une autre copie, et il gère même le cas où il y a des changements non poussés dans une ou plusieurs branches (car cela rompt la logique régulière). Il utilise des éléments de la réponse git filter-branch (pour la logique principale) et la réponse sur la copie des branches d'une instance du référentiel vers une autre (pour copier des branches avec des modifications non poussées).
Je l'ai utilisé pour déplacer un tas de dépôts git-svn que j'ai pour le travail, et cette version du script (j'ai traversé d'innombrables itérations) semble fonctionner pour moi. Ce n'est pas super rapide, mais il semble gérer tous les cas que j'ai rencontrés et entraîner un repo entièrement relocalisé.
Le script vous donne la possibilité de créer une copie du référentiel avant d'apporter des modifications, vous pouvez donc utiliser cette option pour créer une sauvegarde. La création d'une copie est requise si vous avez des modifications non poussées dans des branches.
Le script n'utilise pas de gemmes ou d'autres bibliothèques non incluses dans l'installation MRI normale Ruby installation. Il utilise les bibliothèques readline et fileutils incluses dans MRI.
J'espère que mon script sera utile à quelqu'un d'autre. N'hésitez pas à apporter des modifications au script.
REMARQUE: Je n'ai testé ce script qu'avec git 2.3.0/2.3.1 et Ruby 2.2.0 sur OS X 10.10 Yosemite (puisque c'est l'environnement que j'utilise), mais je m'attendrais à ce qu'il fonctionne également sur d'autres environnements. Aucune garantie sur Windows, cependant.
Ce qui précède git svn rebase -l
la solution n'a pas fonctionné pour moi. J'ai décidé de procéder différemment:
old
et le nouveau SVN dans git repo new
old
dans new
cd new
git fetch ../old
git tag old FETCH_HEAD
new
au-dessus de old
(devrait réussir, car les arbres à la racine de new
et la pointe de old
sont identiques) git checkout master
(Suppose que la branche master
pointe vers la tête SVN. Ce sera le cas avec un clone propre; sinon, engagez-le avant de commencer.)git rebase --root --onto old
new
pour tenir compte du rebase git update-ref --no-deref refs/remotes/git-svn master
(ajustez la référence de la télécommande en fonction de la façon dont vous avez cloné, par exemple, cela pourrait être refs/remotes/svn/trunk
)rm -r .git/svn
git svn info