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_filterdel repositorio Gitorious. - Cree un script de Python en el mismo directorio donde clonó
git_fast_filterbasado 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-importCopie
.git/config, y quizás otros archivos relevantes en.git/infodesde el repositorio anterior al nuevo repositorio.- Eliminar
.git/svn. Haga que
git-svntenga 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-remotesections
- 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
urlsvn-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
urlsvn-remote a la URL original. - Ejecute
git svn rebase -lpara hacer una rebase local (con los cambios que vinieron con la última operación de recuperación). - Cambie la configuración de
urlsvn-remote a la nueva URL. - Ahora,
git svn rebasedeberí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
oldy nuevo SVN en git reponew - Trae lo
olda lonew-
cd new -
git fetch ../old -
git tag old FETCH_HEAD
-
- Rebase
newencima deold(debería tener éxito porque los árboles en la raíz denewy la punta deoldson idénticos)-
git checkout master(se supone que la ramamasterestá 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
newpara 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
urlsvn-remote(ofetchpath) en.git/configpara 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 rebaseahora, obtendrás un mensaje de error como este:Unable to determine upstream SVN information from working tree historyCreo que esto se debe a que
git svnestá confundido por el hecho de que tu última confirmación antes de la búsqueda tendrá ungit-svn-idapunta a la ruta anterior, que no coincide con la que se encuentra en.git/config.Como solución alternativa, cambie
svn-remoteurl(ofetchpath) de vuelta al dominio / url / path originalAhora ejecute
git svn rebase -lnuevamente para hacer una rebase local con los cambios que vinieron con la última operación de recuperación. Esta vez funcionará, aparentemente porquegit svnno se confundirá por el hecho de quegit-svn-iddel nuevo cabezal no coincide con el que se encuentra en.git/config.Finalmente, cambie
svn-remoteurl(ofetchpath) al nuevo dominio / url / path¡En este punto,
git svn rebasedebería funcionar de nuevo!
La información original fue encontrada here .
Puedes ver si lo siguiente funciona bien:
Si
svn-remote.svn.rewriteRootno existe en el archivo de configuración (.git/config):git config svn-remote.svn.rewriteRoot <currentRepositoryURL>Si
svn-remote.svn.rewriteUUIDno existe en el archivo de configuración:git config svn-remote.svn.rewriteUUID <currentRepositoryUUID>El
currentRepositoryUUIDse puede obtener de.git/svn/.metadata.git config svn-remote.svn.url <newRepositoryURL>