Repozytorium svn, które dubluję przez git-svn, zmieniło adres URL.
W Vanilla SVN po prostu byś to zrobił svn switch --relocate old_url_base new_url_base
.
Jak mogę to zrobić za pomocą git-svn?
Po prostu zmiana adresu URL svn w pliku konfiguracyjnym kończy się niepowodzeniem.
Odpowiedzi:
To całkiem dobrze rozwiązuje moją sytuację:
https://git.wiki.kernel.org/index.php/GitSvnSwitch
Sklonowałem za pomocą
file://
protokołu i chciałem przełączyć się nahttp://
protokół.Kuszące jest edytowanie
url
ustawienia w[svn-remote "svn"]
sekcji.git/config
, ale samo to nie działa. Ogólnie musisz postępować zgodnie z następującą procedurą:url
na nową nazwę.git svn fetch
. To musi pobrać co najmniej jedną nową wersję z svn!url
powrotem na oryginalny adres URL.git svn rebase -l
aby wykonać lokalną rebase (ze zmianami wprowadzonymi podczas ostatniej operacji pobierania).url
powrotem na nowy adres URL.git svn rebase
powinno znowu działać.Dusze żądne przygód mogą chcieć spróbować
--rewrite-root
.źródło
Możesz sprawdzić, czy poniższe elementy działają poprawnie:
Jeśli
svn-remote.svn.rewriteRoot
nie istnieje w pliku konfiguracyjnym (.git/config
):Jeśli
svn-remote.svn.rewriteUUID
nie istnieje w pliku konfiguracyjnym:currentRepositoryUUID
Można otrzymać z.git/svn/.metadata
.git config svn-remote.svn.url <newRepositoryURL>
źródło
file://
, przełącz nasvn+ssh
); wystarczy zauważyć, że: ta procedura nie musi "pobierać co najmniej jednej nowej wersji z svn"; również./.git/svn/.metadata
po pierwszymsvn rebase
zawiera<newRepository>
asreposRoot
- ale to nie wystarczy, aby usunąćrewrite*
klucze.git/config
; dlatego te klucze powinny być tam na stałe, o ile rozumiem.svn+ssh://
a nasz serwer svn właśnie zmienił domenę z.se
na,.com
aby oczyścić nasze wewnętrzne nazewnictwo.Niestety większość linków w tych odpowiedziach nie działa, więc zamierzam zduplikować część informacji z git wiki na przyszłość.
To rozwiązanie zadziałało dla mnie:
Edytuj
svn-remote
url
(lubfetch
ścieżkę) w,.git/config
aby wskazać nową domenę / adres URL / ścieżkęUruchom git
git svn fetch
. To musi pobrać co najmniej jedną nową wersję z svn!Jeśli spróbujesz
git svn rebase
teraz, zostanie wyświetlony następujący komunikat o błędzie:Myślę, że dzieje się tak, ponieważ
git svn
jest zdezorientowany faktem, że ostatnie zatwierdzenie przed pobraniem będzie miałogit-svn-id
wskazanie na starą ścieżkę, która nie pasuje do tej znalezionej w.git/config
.Aby obejść ten problem, zmień
svn-remote
url
(lubfetch
ścieżkę) z powrotem do oryginalnej domeny / adresu URL / ścieżkiTeraz uruchom
git svn rebase -l
ponownie, aby wykonać lokalną rebase ze zmianami wprowadzonymi podczas ostatniej operacji pobierania. Tym razem to będzie działać, bo widoczniegit svn
nie należy mylić z faktu, żegit-svn-id
od nowego szefa nie zgadza się z tym znaleźć w.git/config
.Na koniec zmień
svn-remote
url
(lubfetch
ścieżkę) z powrotem do nowej domeny / adresu URL / ścieżkiW tym momencie
git svn rebase
powinno działać ponownie!Oryginalne informacje zostały znalezione tutaj .
źródło
Git svn w dużym stopniu opiera się na adresie URL svn. Każde zatwierdzenie, które jest importowane z svn
git-svn-id
, zawiera adres URL svn.Prawidłową strategią relokacji jest zadzwonienie
git-svn clone
nowego repozytorium i połączenie zmian z tym nowym zamknięciem. Aby uzyskać bardziej szczegółową procedurę, zobacz ten artykuł:http://www.sanityinc.com/articles/relocating-git-svn-repositories
źródło
git filter-branch
Ten skrypt , zaczerpnięty z wpisu na blogu , zadziałał dla mnie. Podaj stary i nowy adres URL repozytorium jako parametr, tak jak w przypadku
svn switch --relocate
.Skrypt wywołuje
git filter-branch
zastąpienie adresów URL Subversion wgit-svn-id
komunikatach o zmianach.git/config
, aktualizuje , a także aktualizujegit-svn
metadane, odtwarzając je za pomocągit svn rebase
. Chociażgit svn clone
może być bardziej niezawodnym rozwiązaniem,filter-branch
podejście to działa znacznie szybciej w przypadku dużych repozytoriów (godziny w porównaniu z dniami).#!/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
źródło
git_fast_filter
Jednak szybciej niż
git-filter-branch
(tj. Minuty zamiast godzin), ale podobnie w duchu, jest użyciegit_fast_filter
. Wymaga to jednak nieco więcej kodowania i nie istnieje żadne schludne, gotowe rozwiązanie. W przeciwieństwie dogit-filter-branch
tego spowoduje to utworzenie nowego repozytorium ze starego . Zakłada się, żemaster
wskazuje na ostatnie zatwierdzenie SVN.git_fast_filter
z repo Gitorious.git_fast_filter
na podstawie tego Gist , ustaw wykonywalny bit za pomocąchmod +x
. Dostosuj stare i nowe ścieżki repozytorium. (Treść skryptu jest również wklejona poniżej).git init
, zmień katalog roboczy na to nowe repozytorium.Wykonaj następującą potokę:
Skopiuj
.git/config
i być może inne odpowiednie pliki w formacie.git/info
ze starego repozytorium do nowego repozytorium..git/svn
.Zwróć uwagę
git-svn
na nowe mapowanie numerów wersjiWykonać
git branch refs/remotes/git-svn master
refs/remotes/git-svn
skonsultować.git/config
,svn-remote
sekcjeWykonaj
git svn info
. Jeśli to polecenie zawiesza się, coś jest nie tak. Powinien odbudować mapowanie numerów wersji.Usuń fałszywą gałąź
refs/remotes/git-svn
, zostanie odtworzona przezgit-svn
git svn rebase
.Poniżej znajduje się treść
commit_filter.py
, zamień wartościIN_REPO
iOUT_REPO
odpowiednio:#!/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()
źródło
Powyższe
git svn rebase -l
rozwiązanie u mnie nie działa. Postanowiłem zająć się tym inaczej:old
a nowe repozytorium SVN do repozytorium gitnew
old
donew
cd new
git fetch ../old
git tag old FETCH_HEAD
new
na szczycieold
(powinno się powieść, ponieważ drzewa w korzeniunew
i na końcuold
są identyczne)git checkout master
(Zakłada się, żemaster
gałąź wskazuje na główkę SVN. Tak będzie w przypadku czystego klonu; w przeciwnym razie dcommit przed rozpoczęciem).git rebase --root --onto old
new
aby uwzględnić rebasegit update-ref --no-deref refs/remotes/git-svn master
(dostosuj zdalny numer referencyjny w zależności od tego, jak sklonowałeś, np. może to byćrefs/remotes/svn/trunk
)rm -r .git/svn
git svn info
źródło
Opierając się na niektórych innych odpowiedziach na to pytanie, wymyśliłem skrypt Ruby, który obsługuje relokację git-svn. Możesz go znaleźć na https://gist.github.com/henderea/6e779b66be3580c9a584 .
Obsługuje relokację bez sprawdzania innej kopii, a nawet obsługuje przypadek, w którym występują niewysłane zmiany w jednej lub kilku gałęziach (ponieważ łamie to zwykłą logikę). Używa rzeczy z odpowiedzi git filter-branch (dla głównej logiki) i odpowiedzi o kopiowaniu gałęzi z jednej instancji repozytorium do drugiej (do kopiowania gałęzi z niezapchniętymi zmianami).
Używałem tego do przenoszenia kilku repozytoriów git-svn, które mam do pracy, a ta wersja skryptu (przeszedłem przez niezliczone iteracje) wydaje się działać dla mnie. Nie jest superszybki, ale wydaje się obsługiwać wszystkie napotkane przypadki i skutkować w pełni przeniesionym repozytorium.
Skrypt daje możliwość utworzenia kopii repozytorium przed wprowadzeniem jakichkolwiek zmian, więc można użyć tej opcji do utworzenia kopii zapasowej. Utworzenie kopii jest wymagane, jeśli masz cofnięte zmiany w jakichkolwiek gałęziach.
Skrypt nie używa żadnych klejnotów ani innych bibliotek, które nie są zawarte w normalnej instalacji MRI Ruby. Używa bibliotek readline i fileutils zawartych w MRI.
Mam nadzieję, że mój skrypt przyda się komuś innemu. Zapraszam do wprowadzania zmian w skrypcie.
UWAGA: Testowałem ten skrypt tylko z git 2.3.0 / 2.3.1 i Ruby 2.2.0 na OS X 10.10 Yosemite (ponieważ jest to środowisko, którego używam), ale spodziewałbym się, że będzie działał również w innych środowiskach. Nie ma jednak gwarancji dotyczących systemu Windows.
źródło