migrar - subgit
git-svn: ¿cuál es el equivalente a `svn switch--relocate`? (8)
git filter-branch
Esta secuencia de comandos , tomada de una entrada de blog , me ha funcionado. Proporcione el URL repo antiguo y nuevo como parámetro, al igual que para el svn switch --relocate
.
El script llama a git filter-branch
para reemplazar las URL de Subversion en git-svn-id
en los mensajes de confirmación, actualizaciones .git/config
y también actualiza git-svn
metadatos de git-svn
recreándolo usando git svn rebase
. Si bien git svn clone
podría ser la solución más robusta, el enfoque de filter-branch
funciona mucho más rápido para grandes repositorios (horas vs. 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
Un repositorio svn que estoy duplicando a través de git-svn ha cambiado la URL.
En svn vainilla simplemente harías svn switch --relocate old_url_base new_url_base
.
¿Cómo puedo hacer esto usando git-svn?
Simplemente se cambia el url de svn en el archivo de configuración.
git_fast_filter
Sin embargo, más rápido que git-filter-branch
(es decir, minutos en lugar de horas), pero similar en espíritu, es usar git_fast_filter
. Sin embargo, esto requiere un poco más de codificación, y no existe una solución limpia y lista para empaquetarse. A diferencia de git-filter-branch
, esto creará un nuevo repositorio de uno anterior. Se supone que el master
apunta al último compromiso SVN.
-
git_fast_filter
del repositorio Gitorious. - Cree un script de Python en el mismo directorio donde clonó
git_fast_filter
basado en este Gist , establezca el bit ejecutable usandochmod +x
. Adapte rutas de repositorio antiguas y nuevas. (El contenido del script también se pega debajo). - Inicialice un nuevo repositorio de destino usando
git init
, cambie el directorio de trabajo a este nuevo repositorio. Ejecute el siguiente conducto:
(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
, y quizás otros archivos relevantes en.git/info
desde el repositorio anterior al nuevo repositorio.- Eliminar
.git/svn
. Haga que
git-svn
tenga en cuenta el nuevo mapeo de números de revisiónEjecute
git branch refs/remotes/git-svn master
- Sus controles remotos git-svn pueden llamarse diferentes que
refs/remotes/git-svn
, consultar.git/config
,svn-remote
sections
- Sus controles remotos git-svn pueden llamarse diferentes que
Ejecute
git svn info
. Si este comando se congela, algo está mal. Debería reconstruir la asignación del número de revisión.Quite la rama falsa
refs/remotes/git-svn
, será recreada porgit-svn
- Sincronice llamando a
git svn rebase
.
A continuación se muestran los contenidos de commit_filter.py
, reemplace los valores de IN_REPO
y OUT_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()
Basado en algunas de las otras respuestas a esta pregunta, he creado un script de 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 sin pulsar en una o más ramas (ya que eso rompe la lógica normal). Utiliza elementos de la respuesta git filter-branch (para la lógica principal) y la respuesta sobre la copia de ramas desde una instancia del repositorio a otra (para copiar ramas con cambios sin pulsar).
He estado usando esto para reubicar un montón de repositorios git-svn que tengo para el trabajo, y esta versión del guión (he pasado por innumerables iteraciones) parece funcionar para mí. No es súper rápido, pero parece que maneja 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, de modo que puede usar esta opción para crear una copia de seguridad. Se necesita crear una copia si tiene cambios sin presionar en cualquier rama.
La secuencia de comandos no utiliza gemas u otras bibliotecas no incluidas en la instalación normal de Ruby de MRI. Utiliza las bibliotecas readline y fileutils incluidas en MRI.
Espero que mi script resulte útil para otra persona. Siéntase libre de hacer 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 también espero que funcione en otros entornos. Sin embargo, no hay garantías sobre Windows.
Esto maneja mi situación bastante bien:
https://git.wiki.kernel.org/index.php/GitSvnSwitch
Me cloné usando el protocolo file://
y quería cambiar al protocolo http://
.
Es tentador editar la configuración de url
en la sección [svn-remote "svn"]
de .git/config
, pero por sí solo esto no funciona. En general, debe seguir el siguiente procedimiento:
- Cambia la configuración de
url
svn-remote al nuevo nombre. - Ejecute
git svn fetch
. ¡Esto necesita buscar al menos una nueva revisión desde svn! - Cambia la configuración de la
url
svn-remote a la URL original. - Ejecute
git svn rebase -l
para hacer una rebase local (con los cambios que vinieron con la última operación de recuperación). - Cambie la configuración de
url
svn-remote a la nueva URL. - Ahora,
git svn rebase
debería funcionar de nuevo.
Las almas aventureras pueden querer probar --rewrite-root
.
Git svn depende en gran medida de la URL svn. Cada confirmación que se importa desde svn tiene un git-svn-id
que incluye la URL svn.
Una estrategia de reubicación válida es llamar git-svn clone
en el nuevo repositorio y fusionar los cambios en ese nuevo cierre. Para un procedimiento más detallado, vea este artículo:
http://www.sanityinc.com/articles/relocating-git-svn-repositories
La solución anterior git svn rebase -l
no funcionó para mí. Decidí hacerlo de otra manera:
- Clona el antiguo repositorio SVN en git repo
old
y nuevo SVN en git reponew
- Trae lo
old
a lonew
-
cd new
-
git fetch ../old
-
git tag old FETCH_HEAD
-
- Rebase
new
encima deold
(debería tener éxito porque los árboles en la raíz denew
y la punta deold
son idénticos)-
git checkout master
(se supone que la ramamaster
está apuntando al encabezado SVN. Este será el caso con un clon limpio; de lo contrario, se comprometerá antes de comenzar). -
git rebase --root --onto old
-
- Reconstruye los metadatos git-svn de
new
para tener en cuenta la rebase-
git update-ref --no-deref refs/remotes/git-svn master
(ajuste la referencia remota dependiendo de cómo haya clonado, por ejemplo, podría serrefs/remotes/svn/trunk
) -
rm -r .git/svn
-
git svn info
-
Lamentablemente, la mayoría de los enlaces en estas respuestas no funcionan, así que voy a duplicar un poco de información de la wiki de git para futuras referencias.
Esta solución funcionó para mí:
Edite la
url
svn-remote
(ofetch
path) en.git/config
para apuntar al nuevo dominio / url / pathEjecute git
git svn fetch
. ¡Esto necesita buscar al menos una nueva revisión desde svn!Si intentas
git svn rebase
ahora, obtendrás un mensaje de error como este:Unable to determine upstream SVN information from working tree history
Creo que esto se debe a que
git svn
está confundido por el hecho de que tu última confirmación antes de la búsqueda tendrá ungit-svn-id
apunta a la ruta anterior, que no coincide con la que se encuentra en.git/config
.Como solución alternativa, cambie
svn-remote
url
(ofetch
path) de vuelta al dominio / url / path originalAhora ejecute
git svn rebase -l
nuevamente para hacer una rebase local con los cambios que vinieron con la última operación de recuperación. Esta vez funcionará, aparentemente porquegit svn
no se confundirá por el hecho de quegit-svn-id
del nuevo cabezal no coincide con el que se encuentra en.git/config
.Finalmente, cambie
svn-remote
url
(ofetch
path) al nuevo dominio / url / path¡En este punto,
git svn rebase
debería funcionar de nuevo!
La información original fue encontrada here .
Puedes ver si lo siguiente funciona bien:
Si
svn-remote.svn.rewriteRoot
no existe en el archivo de configuración (.git/config
):git config svn-remote.svn.rewriteRoot <currentRepositoryURL>
Si
svn-remote.svn.rewriteUUID
no existe en el archivo de configuración:git config svn-remote.svn.rewriteUUID <currentRepositoryUUID>
El
currentRepositoryUUID
se puede obtener de.git/svn/.metadata
.git config svn-remote.svn.url <newRepositoryURL>