Un repositorio svn que estoy duplicando a través de git-svn ha cambiado de URL.
En vainilla svn simplemente harías svn switch --relocate old_url_base new_url_base
.
¿Cómo puedo hacer esto usando git-svn?
El simple cambio de la url svn en el archivo de configuración falla.
Respuestas:
Esto maneja mi situación bastante bien:
https://git.wiki.kernel.org/index.php/GitSvnSwitch
Cloné usando el
file://
protocolo y quería cambiar alhttp://
protocolo.Es tentador editar la
url
configuración en la[svn-remote "svn"]
sección de.git/config
, pero por sí solo no funciona. En general, debe seguir el siguiente procedimiento:url
configuración de svn-remote al nuevo nombre.git svn fetch
. ¡Esto necesita obtener al menos una nueva revisión de svn!url
configuración de svn-remote a la URL original.git svn rebase -l
para hacer un rebase local (con los cambios que se produjeron con la última operación de recuperación).url
configuración de svn-remote de nuevo a la nueva URL.git svn rebase
debería funcionar de nuevo.Las almas aventureras pueden querer intentarlo
--rewrite-root
.fuente
Puede ver si lo siguiente funciona bien:
Si
svn-remote.svn.rewriteRoot
no existe en el archivo de configuración (.git/config
):Si
svn-remote.svn.rewriteUUID
no existe en el archivo de configuración:El
currentRepositoryUUID
se puede obtener de.git/svn/.metadata
.git config svn-remote.svn.url <newRepositoryURL>
fuente
file://
, cambiar asvn+ssh
); solo notando que: este procedimiento no necesita "buscar al menos una nueva revisión de svn"; también./.git/svn/.metadata
after firstsvn rebase
contiene el<newRepository>
asreposRoot
, pero esto no es suficiente para eliminar lasrewrite*
claves de.git/config
; por lo tanto, esas claves deben guardarse permanentemente allí, según tengo entendido.svn+ssh://
y nuestro servidor svn acaba de cambiar el dominio de.se
a.com
para desinfectar nuestro nombre interno.Desafortunadamente, la mayoría de los enlaces en estas respuestas no funcionan, así que duplicaré un poco de información de la wiki de git para referencia futura.
Esta solución funcionó para mí:
Edite la
svn-remote
url
(o lafetch
ruta).git/config
para que apunte al nuevo dominio / url / rutaEjecuta git
git svn fetch
. ¡Esto necesita obtener al menos una nueva revisión de svn!Si lo intenta
git svn rebase
ahora, recibirá un mensaje de error como este:Creo que esto se debe a que
git svn
está confundido por el hecho de que su última confirmación antes de la recuperación tendrá ungit-svn-id
apunte a la ruta anterior, que no coincide con la que se encuentra en.git/config
.Como solución alternativa, cambie
svn-remote
url
(ofetch
ruta) de nuevo al dominio / URL / ruta originalAhora ejecute de
git svn rebase -l
nuevo para hacer una rebase local con los cambios que se produjeron con la última operación de recuperación. En esta ocasión se va a trabajar, al parecer porquegit svn
no será confundido por el hecho de que elgit-svn-id
de la nueva cabeza no coincide con la encontrada en.git/config
.Finalmente, cambie
svn-remote
url
(ofetch
ruta) de nuevo al nuevo dominio / url / ruta¡En este punto
git svn rebase
debería funcionar de nuevo!La información original se encontró aquí .
fuente
Git svn se basa en gran medida en la URL de svn. Cada confirmación que se importa desde svn tiene una
git-svn-id
que incluye la URL de svn.Una estrategia de reubicaciones válida es llamar
git-svn clone
al nuevo repositorio y fusionar los cambios en ese nuevo cierre. Para obtener un procedimiento más detallado, consulte este artículo:http://www.sanityinc.com/articles/relocating-git-svn-repositories
fuente
git filter-branch
Este script , tomado de una entrada de blog , me ha funcionado. Proporcione la URL de repositorio nueva y antigua como parámetro, al igual que para
svn switch --relocate
.La secuencia de comandos llama
git filter-branch
para reemplazar las URL de Subversion en losgit-svn-id
mensajes de confirmación, actualizaciones.git/config
y también actualiza losgit-svn
metadatos al recrearlos usandogit svn rebase
. Si biengit svn clone
podría ser la solución más sólida, elfilter-branch
enfoque funciona mucho más rápido para grandes repositorios (horas frente a días).#!/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
fuente
git_fast_filter
Aún más rápido que
git-filter-branch
(es decir, minutos en lugar de horas), pero similar en espíritu, es usargit_fast_filter
. Sin embargo, esto requiere un poco más de codificación y no existe una solución ordenada y lista para usar. En contraste congit-filter-branch
, esto creará una nueva cesión temporal de un viejo uno. Se supone quemaster
apunta al último compromiso SVN.git_fast_filter
del repositorio de Gitorious.git_fast_filter
basado en este Gist , configure el bit ejecutable usandochmod +x
. Adapte las rutas de repositorio nuevas y antiguas. (El contenido del script también se pega a continuación).git init
, cambie el directorio de trabajo a este nuevo repositorio.Ejecute la siguiente tubería:
Copie
.git/config
, y quizás otros archivos relevantes.git/info
desde el antiguo repositorio al nuevo repositorio..git/svn
.Tenga en
git-svn
cuenta la nueva asignación de números de revisiónEjecutar
git branch refs/remotes/git-svn master
refs/remotes/git-svn
, consultar.git/config
,svn-remote
seccionesEjecutar
git svn info
. Si este comando se congela, algo anda mal. Debería reconstruir la asignación del número de revisión.Retire la rama falsa
refs/remotes/git-svn
, será recreada porgit-svn
git svn rebase
.A continuación se muestra el contenido de
commit_filter.py
, reemplace los valores deIN_REPO
yOUT_REPO
según corresponda:#!/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()
fuente
La
git svn rebase -l
solución anterior no funcionó para mí. Decidí hacerlo de una manera diferente:old
y el nuevo SVN en git reponew
old
ennew
cd new
git fetch ../old
git tag old FETCH_HEAD
new
encima deold
(debería tener éxito porque los árboles en la raíznew
y la punta deold
son idénticos)git checkout master
(Se asume que lamaster
rama apunta a la cabeza SVN. Este será el caso con un clon limpio; de lo contrario, haga dcommit antes de comenzar).git rebase --root --onto old
new
para dar cuenta de la rebasegit update-ref --no-deref refs/remotes/git-svn master
(ajuste la referencia remota dependiendo de cómo clonó, por ejemplo, podría serrefs/remotes/svn/trunk
)rm -r .git/svn
git svn info
fuente
Basándome en algunas de las otras respuestas a esta pregunta, se me ocurrió un script Ruby que maneja la reubicación de git-svn. Puede encontrarlo en https://gist.github.com/henderea/6e779b66be3580c9a584 .
Maneja la reubicación sin verificar otra copia, e incluso maneja el caso donde hay cambios no empujados en una o más ramas (ya que eso rompe la lógica regular). Utiliza cosas de la respuesta de git filter-branch (para la lógica principal) y la respuesta sobre copiar ramas de una instancia del repositorio a otra (para copiar ramas con cambios no empujados).
He estado usando esto para reubicar un montón de repositorios git-svn que tengo para trabajar, y esta versión del script (he pasado por innumerables iteraciones) parece funcionar para mí. No es muy rápido, pero parece manejar todos los casos que he encontrado y resulta en un repositorio completamente reubicado.
El script le da la opción de crear una copia del repositorio antes de realizar cualquier cambio, por lo que puede usar esta opción para crear una copia de seguridad. Es necesario crear una copia si tiene cambios no enviados en alguna rama.
El script no utiliza gemas u otras bibliotecas que no se incluyan en la instalación normal de MRI Ruby. Utiliza las bibliotecas readline y fileutils incluidas en MRI.
Con suerte, mi guión le resultará útil a otra persona. No dude en realizar cambios en el guión.
NOTA: Solo he probado este script con git 2.3.0 / 2.3.1 y Ruby 2.2.0 en OS X 10.10 Yosemite (ya que ese es el entorno que uso), pero espero que funcione también en otros entornos. Sin embargo, no hay garantías sobre Windows.
fuente