Jak migrować repozytorium SVN z historią do nowego repozytorium Git?


1509

Przeczytałem instrukcję Git, FAQ, kurs awaryjny Git - SVN itp. I wszystkie one wyjaśniają to i tamto, ale nigdzie nie można znaleźć prostej instrukcji, takiej jak:

Repozytorium SVN w: svn://myserver/path/to/svn/repos

Repozytorium Git w: git://myserver/path/to/git/repos

git-do-the-magic-svn-import-with-history \
svn://myserver/path/to/svn/repos \
git://myserver/path/to/git/repos

Nie oczekuję, że będzie to takie proste i nie oczekuję, że będzie to jedno polecenie. Ale spodziewam się, że nie będzie próbować niczego wyjaśniać - tylko powiedzieć, jakie kroki należy podjąć, biorąc pod uwagę ten przykład.


6
Jest coraz łatwiej, właśnie go ukończyłem i udokumentowałem swoje ustalenia przy pomocy SO jmoses.co/2014/03/21/moving-from-svn-to-git.html
John Moses

Skorzystaj z odpowiedzi Casey poniżej, ale zanim uruchomisz polecenie „klon svn ...”, zobacz, jak dodać dodatkową linię „Visual SVN Server” do pliku user.txt ... tutaj: stackoverflow.com/questions/8971208/ …
MacGyver,

1
Ponadto, jeśli w profilu GitHub zaznaczono opcję „ustaw prywatną pocztę e-mail, użyj jej jako adresu e-mail w users.txt w celu dopasowania. Yourgituser@users.noreply.github.com, aby Twój prawdziwy adres e-mail nie był wyświetlany w sprawie zobowiązań
MacGyver

Odpowiedzi:


529

Magia:

$ git svn clone http://svn/repo/here/trunk

Git i SVN działają zupełnie inaczej. Musisz nauczyć się Git, a jeśli chcesz śledzić zmiany od SVN w górę, musisz się nauczyć git-svn. Na git-svn stronie głównej znajduje się sekcja dobrych przykładów :

$ git svn --help

139
Odpowiedź @Casey znacznie lepiej odpowiada na pierwotne pytanie.
Doug Wilson

3
Czy to pozwoli utrzymać gałęzie i wszystko? lub po prostu sklonować bagażnik?
Eildosa

7
@Eildosa: To po prostu sklonuje bagażnik. Zobacz odpowiedź Casey na alternatywę.
śleske,

3
@DougWilson, ale nie widzę tutaj żadnej odpowiedzi Casey. Czy to jest odpowiedź poniżej z 13 autorami, która zaczyna się od „Utwórz plik użytkowników”?
Andrey Regentov,

67
Dla każdego, kto zastanawia się, która „odpowiedź Caseya” jest wymieniona w wielu komentarzach tutaj, jest to ta (Casey zmienił swój nick na cmcginty).
Stefan Monov

1559

Utwórz plik użytkowników (tj. users.txt) Do mapowania użytkowników SVN na Git:

user1 = First Last Name <email@address.com>
user2 = First Last Name <email@address.com>
...

Możesz użyć tego jednowierszowego do zbudowania szablonu z istniejącego repozytorium SVN:

svn log -q | awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2" = "$2" <"$2">"}' | sort -u > users.txt

SVN zatrzyma się, jeśli znajdzie brakującego użytkownika SVN spoza pliku. Ale potem możesz zaktualizować plik i odebrać od miejsca, w którym przerwałeś.

Teraz wyciągnij dane SVN z repozytorium:

git svn clone --stdlayout --no-metadata --authors-file=users.txt svn://hostname/path dest_dir-tmp

To polecenie utworzy nowe repozytorium Git dest_dir-tmpi rozpocznie pobieranie repozytorium SVN. Zauważ, że flaga „--stdlayout” oznacza, że ​​masz wspólny układ „trunk /, branch /, tags /” SVN. Jeśli twoje różni się układ, zapoznać się z --tags, --branches, --trunkopcje (w ogóle git svn help).

Wszystkie wspólne protokoły są dozwolone: svn://, http://, https://. Adres URL powinien być kierowany do podstawowego repozytorium, na przykład http://svn.mycompany.com/myrepo/repository . Ciąg URL musi nie należą /trunk, /tagalbo /branches.

Zauważ, że po wykonaniu tej komendy bardzo często wygląda na to, że operacja jest „zawieszona / zamrożona” i całkiem normalne jest, że może utknąć na długi czas po zainicjowaniu nowego repozytorium. W końcu zobaczysz komunikaty dziennika wskazujące, że migruje.

Zauważ też, że jeśli pominiesz --no-metadataflagę, Git dołączy informację o odpowiedniej rewizji SVN do komunikatu zatwierdzenia (tj. git-svn-id: svn://svn.mycompany.com/myrepo/<branchname/trunk>@<RevisionNumber> <Repository UUID>)

Jeśli nazwa użytkownika nie zostanie znaleziona, zaktualizuj users.txtplik, a następnie:

cd dest_dir-tmp
git svn fetch

Być może będziesz musiał powtórzyć to ostatnie polecenie kilka razy, jeśli masz duży projekt, aż wszystkie zatwierdzenia Subversion zostaną pobrane:

git svn fetch

Po zakończeniu Git wyśle ​​SVN trunkdo nowego oddziału. Wszelkie inne oddziały są konfigurowane jako piloty. Możesz wyświetlić inne gałęzie SVN za pomocą:

git branch -r

Jeśli chcesz zachować inne zdalne gałęzie w repozytorium, chcesz ręcznie utworzyć lokalną gałąź dla każdego z nich. (Pomiń trunk / master.) Jeśli tego nie zrobisz, gałęzie nie zostaną sklonowane w ostatnim kroku.

git checkout -b local_branch remote_branch
# It's OK if local_branch and remote_branch are the same name

Tagi są importowane jako oddziały. Musisz utworzyć lokalną gałąź, utworzyć tag i usunąć gałąź, aby mieć je jako tagi w Git. Aby to zrobić za pomocą tagu „v1”:

git checkout -b tag_v1 remotes/tags/v1
git checkout master
git tag v1 tag_v1
git branch -D tag_v1

Sklonuj swoje repozytorium GIT-SVN do czystego repozytorium Git:

git clone dest_dir-tmp dest_dir
rm -rf dest_dir-tmp
cd dest_dir

Lokalne gałęzie utworzone wcześniej ze zdalnych gałęzi zostaną skopiowane tylko jako zdalne gałęzie do nowego sklonowanego repozytorium. (Pomiń trunk / master.) Dla każdej gałęzi, którą chcesz zachować:

git checkout -b local_branch origin/remote_branch

Na koniec usuń pilota z czystego repozytorium Git, który wskazuje na teraz usunięte tymczasowe repozytorium:

git remote rm origin

36
Ten post na blogu autorstwa Eelke stanowi świetne odniesienie do powyższej odpowiedzi. blokspeed.net/blog/2010/09/converting-from-subversion-to-git
kgriffs

4
To jest 99% niesamowite, po tych krokach mam wszystko w porządku oprócz gałęzi: po ostatnim kroku były one tylko zdalne (i jako takie zniknęły, gdy wykonałem polecenie: git remote rm origin)
Dirty Henry

4
GitHub ma bardzo wygodny krok po kroku: github.com/nirvdrum/svn2git#readme
Dan Nissenbaum,

8
Dla osób korzystających z systemu Windows utworzyłem skrypt PowerShell oparty na tej metodzie: gist.github.com/Gimly/90df046dc38181bb18de
Gimly

5
Ostrzeżenie dla dużych transakcji repo z dużą historią, jest powolne i sprytne . Zrezygnowałem z migracji wszystkich starych gałęzi i po prostu zmigrowałem pień.
Jess,

195

Czysta migracja repozytorium Subversion do repozytorium Git . Najpierw musisz utworzyć plik, który mapuje nazwiska autorów zatwierdzeń Subversion na podmioty zatwierdzające Git, powiedz ~/authors.txt:

jmaddox = Jon Maddox <jon@gmail.com>
bigpappa = Brian Biggs <bigpappa@gmail.com>

Następnie możesz pobrać dane Subversion do repozytorium Git:

mkdir repo && cd repo
git svn init http://subversion/repo --no-metadata
git config svn.authorsfile ~/authors.txt
git svn fetch

Jeśli korzystasz z komputera Mac, możesz uzyskać git-svnz MacPorts, instalując git-core +svn.

Jeśli twoje repozytorium subversion znajduje się na tym samym komputerze co żądane repozytorium git, możesz użyć tej składni dla kroku inicjalizacji, w przeciwnym razie wszystko to samo:

git svn init file:///home/user/repoName --no-metadata

1
Jak skomentował drugiej odpowiedzi, musiałem usunąć przestrzenie wokół =w users.txt, ponieważ import był przerywanie i byłem coraz pusty repozytorium.
Sebastián Grignoli

8
Ach! Proste i skuteczne wyjaśnienie. W moim przypadku file:///odmówiłem, po prostu użyłem, svnserve.exe --daemona potem użyłem svn://localhost/home/user/repozamiast tego.
Daniel Reis

Na moim komputerze Mac z systemem Mountain Lion git svn nie działałby, dopóki nie przejdę do Xcode i nie zainstaluję Narzędzi wiersza poleceń znajdujących się na karcie Pobrane w panelu Preferencje. Alternatywnie mogłem zainstalować tylko narzędzia wiersza polecenia dla systemu OS X Mountain Lion, które można znaleźć na stronie programistów Apple.
Drew

3
Na moim przypadku musiałem przekonwertować plik authors.txtdo utf-8 without BOM.
Silvan,

To zadziałało dla mnie świetnie! Kiedy już miałem lokalne repozytorium, użyłem postu cmcginty zaczynającego się od „Sklonuj swoje repozytorium GIT-SVN do czystego repozytorium Git:” Myślę, że głównym powodem, dla którego podobała mi się odpowiedź @zoul, było użycie git svn init, git svn configa następnie, git svn fetchponieważ było łatwiej aby zrobić to w ten sposób, musiałem pobrać kilka razy, aby zrobić to dobrze. Jednowierszowa linia cmcginty git svn clone, która wykonuje wszystkie trzy, była dla mnie zbyt zagmatwana.
Mike

70

Użyłem skryptu svn2git i działa jak czar.


4
P: Czy to naprawia spacje w nazwach znaczników i gałęzi (dozwolone w svn i niedozwolone w git)?
spazm



Lepiej wyjaśnić odpowiedzi, w przeciwnym razie produkujemy dzieciaki skryptowe.
Josh Habdas

Co jeśli twoje gałęzie znajdują się w katalogu głównym SVN i nie masz pnia ani tagów?
Kal

58

Sugeruję zapoznanie się z Git przed ciągłym używaniem git-svn, tj. Utrzymywanie SVN jako scentralizowanego repozytorium i używanie Git lokalnie.

Jednak w przypadku prostej migracji z całą historią, oto kilka prostych kroków:

Zainicjuj lokalne repozytorium:

mkdir project
cd project
git svn init http://svn.url

Zaznacz, jak daleko chcesz rozpocząć importowanie wersji:

git svn fetch -r42

(lub po prostu „git svn fetch” dla wszystkich obrotów)

Właściwie pobierz wszystko od tego czasu:

git svn rebase

Możesz sprawdzić wynik importu za pomocą Gitk. Nie jestem pewien, czy to działa w systemie Windows, działa w systemach OSX i Linux:

gitk

Po lokalnym klonowaniu repozytorium SVN możesz zepchnąć go do scentralizowanego repozytorium Git, aby ułatwić współpracę.

Najpierw utwórz puste zdalne repozytorium (może na GitHub ?):

git remote add origin git@github.com:user/project-name.git

Następnie opcjonalnie zsynchronizuj główną gałąź, aby operacja ściągania automatycznie połączyła zdalny master z lokalnym masterem, gdy oba zawierają nowe rzeczy:

git config branch.master.remote origin
git config branch.master.merge refs/heads/master

Następnie możesz być zainteresowany wypróbowaniem mojego własnego git_remote_branchnarzędzia, które pomaga radzić sobie ze zdalnymi gałęziami:

Pierwszy post wyjaśniający: „ Git odległe gałęzie

Kontynuacja najnowszej wersji: „ Czas rozpocząć współpracę z git_remote_branch


Niezwykle pomocny, działał idealnie. Dodam, że należy wykonać ostatni krok, jeśli synchronizujesz się ze zdalnym repozytorium. Po krokach konfiguracji gita, musiałemgit push origin master
mag382

31

Istnieje nowe rozwiązanie do płynnej migracji z Subversion do Git (lub do jednoczesnego korzystania z obu): SubGit .

Sam pracuję nad tym projektem. Używamy SubGit w naszych repozytoriach - niektórzy z moich kolegów z drużyny używają Git i niektórych Subversion i jak dotąd działa bardzo dobrze.

Aby przeprowadzić migrację z Subversion do Git za pomocą SubGit, musisz uruchomić:

$ subgit install svn_repos
...
TRANSLATION SUCCESSFUL 

Następnie otrzymasz repozytorium Git w svn_repos / .git i możesz go sklonować lub po prostu nadal używać Subversion i tego nowego repozytorium Git razem: SubGit upewni się, że oba są zawsze zsynchronizowane.

Jeśli Twoje repozytorium Subversion zawiera wiele projektów, wówczas w katalogu svn_repos / git zostanie utworzonych wiele repozytoriów Git. Aby dostosować tłumaczenie przed jego uruchomieniem, wykonaj następujące czynności:

$ subgit configure svn_repos
$ edit svn_repos/conf/subgit.conf (change mapping, add authors mapping, etc)
$ subgit install svn_repos

Z SubGit możesz migrować do czystego Gita (nie git-svn) i zacząć go używać, zachowując Subversion tak długo, jak potrzebujesz (na przykład dla już skonfigurowanych narzędzi do budowania).

Mam nadzieję że to pomoże!


4
Pamiętaj, że jednorazowy import (za pomocą subgit importpolecenia) nawet nie wymaga licencji. Uwzględniono również dokładne tłumaczenie svn:ignorewłaściwości na .gitignorepliki.
krlmlr

1
SubGit nie rozpozna mojego klucza prywatnego ani żadnych flag ustawionych w wierszu poleceń. Dokumentacja jest bardzo słaba. To nie jest realna alternatywa dla git svn.
pfnuesel

1
błąd: „svn_repos” nie jest prawidłową skonfigurowaną lokalizacją; Brak pliku konfiguracyjnego SubGit.
Jon Davis,

19

Zobacz oficjalną stronę git-svn . W szczególności zajrzyj do „Podstawowych przykładów”:

Śledzenie i udział w całym projekcie zarządzanym przez Subversion (wraz z pniem, tagami i gałęziami):

# Clone a repo (like git clone):
    git svn clone http://svn.foo.org/project -T trunk -b branches -t tags

Twoje polecenie klonowania zadziałało, powyższe nie dały mi nic poza pustymi repozytoriami git. Jedyną różnicą wydaje się być wyraźny „-T trunk”.
user1984717,


14

SubGit (vs Blue Screen of Death)

subgit import --svn-url url://svn.serv/Bla/Bla  directory/path/Local.git.Repo

To wszystko.

+ Aby zaktualizować z SVN, repozytorium Git utworzone przez pierwsze polecenie.

subgit import  directory/path/Local.git.Repo

Skorzystałem ze sposobu natychmiastowej migracji do Git, aby uzyskać ogromne repozytorium.
Oczywiście potrzebujesz przygotowania.
Ale wcale nie możesz zatrzymać procesu rozwoju.

Oto moja droga.

Moje rozwiązanie wygląda następująco:

  • Przeprowadź migrację SVN do repozytorium Git
  • Zaktualizuj repozytorium Git tuż przed zmianą zespołu .

Migracja zajmuje dużo czasu w przypadku dużego repozytorium SVN.
Ale aktualizacja ukończonej migracji zajmuje zaledwie kilka sekund.

Oczywiście, że używam SubGit , mamo. git-svn sprawia, że ​​jestem niebieskim ekranem śmierci . Po prostu ciągle. A git-svn nudzi mnie fatalnym błędem „ zbyt długiej nazwy pliku ” Gita .

KROKI

1. Pobierz SubGit

2. Przygotuj polecenia migracji i aktualizacji.

Powiedzmy, że robimy to dla systemu Windows (portowanie w systemie Linux jest banalne).
W katalogu bin instalacji SubGit (subgit-2.XX \ bin) utwórz dwa pliki .bat.

Treść pliku / polecenia do migracji:

start    subgit import --svn-url url://svn.serv/Bla/Bla  directory/path/Local.git.Repo

Polecenie „start” jest tutaj opcjonalne (Windows). Pozwoli to zobaczyć błędy przy starcie i pozostawić otwartą powłokę po zakończeniu SubGit.

Możesz dodać tutaj dodatkowe parametry podobne do git-svn . Korzystam tylko z --default-domain myCompanyDomain.com, aby naprawić domenę adresu e-mail autorów SVN.
Mam standardową strukturę repozytorium SVN (trunk / branch / tags) i nie mieliśmy problemów z „mapowaniem autorów”. Więc nic więcej nie robię.

(Jeśli chcesz migrować tagi, takie jak oddziały lub Twoja SVN ma wiele folderów oddziałów / tagów, możesz rozważyć użycie bardziej szczegółowego podejścia SubGit )

Wskazówka 1 : Użyj opcji --minimal-rewizja YourSvnRevNumber, aby zobaczyć, jak szybko wszystko się ułoży (jakiś rodzaj debugowania). Szczególnie przydatne jest wyświetlanie nazwisk autorów lub e-maili.
Lub ograniczyć głębokość historii migracji.

Wskazówka 2 : Migrację można przerwać ( Ctrl+ C) i przywrócić, uruchamiając następne polecenie / plik aktualizujący.
Nie radzę tego robić dla dużych repozytoriów. Otrzymałem „Wyjątek braku pamięci Java + Windows”.

Wskazówka 3 : Lepiej jest utworzyć kopię swojego pustego repozytorium wyników.

Treść pliku / polecenia do aktualizacji:

start    subgit import  directory/path/Local.git.Repo

Możesz uruchomić go dowolną ilość razy, gdy chcesz uzyskać zatwierdzenia ostatniego zespołu do repozytorium Git.

Ostrzeżenie! Nie dotykaj nagiego repozytorium (na przykład tworzenie oddziałów).
Weźmiesz kolejny błąd krytyczny:

Błąd nieodwracalny: nie są zsynchronizowane i nie można ich zsynchronizować ... Tłumaczenie wersji Subversion na Git zatwierdza ...

3. Uruchom pierwsze polecenie / plik. Duże repozytorium zajmie dużo czasu. 30 godzin na moje skromne repozytorium.

To wszystko.
Możesz zaktualizować swoje repozytorium Git z SVN w dowolnym momencie i dowolnym czasie, uruchamiając drugi plik / polecenie. A przed zmianą zespołu programistów na Git.
To zajmie tylko sekundy.



Jest jeszcze jedno przydatne zadanie.

Wciśnij lokalne repozytorium Git do zdalnego repozytorium Git

Czy to twoja sprawa? Kontynuujmy.

  1. Skonfiguruj swoje piloty

Biegać:

$ git remote add origin url://your/repo.git
  1. Przygotuj się do początkowego wysłania dużego lokalnego repozytorium Git do zdalnego repozytorium

Domyślnie Twój Git nie może wysyłać dużych fragmentów. fatal: Odległy koniec odłożył słuchawkę nieoczekiwanie

Biegnijmy po to:

git config --global http.postBuffer 1073741824

524288000 - 500 MB 1073741824 - 1 GB itp.

Napraw problemy z certyfikatem lokalnym . Jeśli twój serwer git używa uszkodzonego certyfikatu.

Mam wyłączone certyfikaty .

Również twój serwer Git może mieć ograniczenia ilości żądań wymagające korekty .

  1. Prześlij całą migrację do zdalnego repozytorium Git zespołu.

Uruchom z lokalnym Gitem:

git push origin --mirror

( git push origin „*: *” dla starszych wersji Git)

Jeśli pojawi się następujący błąd : błąd: nie można spawnować git: Brak takiego pliku lub katalogu ... Dla mnie pełne odtworzenie mojego repozytorium rozwiązuje ten błąd (30 godzin). Możesz wypróbować kolejne polecenia

git push origin --all
git push origin --tags

Lub spróbuj ponownie zainstalować Git ( bezużyteczne dla mnie ). Lub możesz tworzyć gałęzie ze wszystkich tagów i przesuwać je. Lub, lub, lub ...


10

reposurgeon

W przypadku skomplikowanych przypadków reposurgeon Erica S. Raymonda jest narzędziem z wyboru. Oprócz SVN obsługuje wiele innych systemów kontroli wersji za pomocą fast-exportformatu, a także CVS . Autor informuje o udanej konwersji starożytnych repozytoriów, takich jak Emacs i FreeBSD .

Narzędzie najwyraźniej ma na celu prawie idealną konwersję (taką jak konwersja svn:ignorewłaściwości SVN do .gitignoreplików), nawet w przypadku trudnych układów repozytoriów z długą historią. W wielu przypadkach inne narzędzia mogą być łatwiejsze w użyciu.

Przed zagłębieniem się w dokumentację reposurgeonwiersza poleceń należy przeczytać doskonały przewodnik migracji DVCS, który krok po kroku omawia proces konwersji.



8

Musisz zainstalować

git
git-svn

Skopiowano z tego linku http://john.albin.net/git/convert-subversion-to-git .

1. Pobierz listę wszystkich osób zatwierdzających Subversion

Subversion po prostu wyświetla nazwę użytkownika dla każdego zatwierdzenia. Zatwierdzenia Gita zawierają znacznie bogatsze dane, ale w najprostszym przypadku autor zatwierdzenia musi mieć na liście imię i nazwisko oraz adres e-mail. Domyślnie narzędzie git-svn wyświetla tylko nazwę użytkownika SVN w polach autora i e-mail. Ale przy odrobinie pracy możesz utworzyć listę wszystkich użytkowników SVN oraz ich nazwy Git i wiadomości e-mail. Ta lista może być używana przez git-svn do przekształcania zwykłych nazw użytkowników svn w odpowiednie komendy Git.

Z katalogu głównego lokalnej kasy Subversion uruchom następujące polecenie:

svn log -q | awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2" = "$2" <"$2">"}' | sort -u > authors-transform.txt

Spowoduje to przechwycenie wszystkich komunikatów dziennika, wykasowanie nazw użytkowników, wyeliminowanie wszelkich zduplikowanych nazw użytkowników, posortowanie nazw użytkowników i umieszczenie ich w pliku „author-transform.txt”. Teraz edytuj każdą linię w pliku. Na przykład przekonwertuj:

jwilkins = jwilkins <jwilkins>

zaangażowany w to:

jwilkins = John Albin Wilkins <johnalbin@example.com>

2. Sklonuj repozytorium Subversion za pomocą git-svn

git svn clone [SVN repo URL] --no-metadata -A authors-transform.txt --stdlayout ~/temp

Spowoduje to wykonanie standardowej transformacji git-svn (przy użyciu pliku autorskiego-transform.txt utworzonego w kroku 1) i umieszczenie repozytorium git w folderze „~ / temp” w katalogu domowym.

3. Konwertuj svn: ignore właściwości na .gitignore

Jeśli twoje repozytorium svn używało właściwości svn: ignore, możesz łatwo przekonwertować to na plik .gitignore, używając:

cd ~/temp
git svn show-ignore > .gitignore
git add .gitignore
git commit -m 'Convert svn:ignore properties to .gitignore.'

4. Prześlij repozytorium do samego repozytorium git

Najpierw utwórz puste repozytorium i dopasuj jego domyślną gałąź do nazwy gałęzi „trunk” svn.

git init --bare ~/new-bare.git
cd ~/new-bare.git
git symbolic-ref HEAD refs/heads/trunk

Następnie przenieś repozytorium temp do nowego repozytorium.

cd ~/temp
git remote add bare ~/new-bare.git
git config remote.bare.push 'refs/remotes/*:refs/heads/*'
git push bare

Możesz teraz bezpiecznie usunąć repozytorium ~ / temp.

5. Zmień nazwę gałęzi „trunk” na „master”

Twoja główna gałąź programistyczna będzie nosiła nazwę „trunk”, co odpowiada nazwie w Subversion. Będziesz chciał zmienić nazwę na standardowy „główny” oddział Gita, używając:

cd ~/new-bare.git
git branch -m trunk master

6. Oczyść gałęzie i tagi

git-svn zamienia wszystkie znaczniki Subversions w bardzo krótkie gałęzie w Git w postaci „znaczniki / nazwa”. Będziesz chciał przekonwertować wszystkie te gałęzie na rzeczywiste tagi Git, używając:

cd ~/new-bare.git
git for-each-ref --format='%(refname)' refs/heads/tags |
cut -d / -f 4 |
while read ref
do
  git tag "$ref" "refs/heads/tags/$ref";
  git branch -D "tags/$ref";
done

Ten krok wymaga trochę pisania. :-) Ale nie martw się; twoja powłoka uniksowa wyświetli> dodatkowy monit o wyjątkowo długie polecenie, które zaczyna się od git for-each-ref.



7

Nieco rozszerzona odpowiedź przy użyciu tylko git, SVN i bash. Zawiera kroki dla repozytoriów SVN, które nie używają konwencjonalnego układu z układem katalogu trunk / branch / tags (SVN absolutnie nic nie wymusza tego rodzaju układu).

Najpierw użyj tego skryptu bash, aby zeskanować repozytorium SVN w poszukiwaniu różnych osób, które się do niego przyczyniły, i wygenerować szablon pliku mapowania:

#!/usr/bin/env bash
authors=$(svn log -q | grep -e '^r' | awk 'BEGIN { FS = "|" } ; { print $2 }' | sort | uniq)
for author in ${authors}; do
  echo "${author} = NAME <USER@DOMAIN>";
done

Użyj tego, aby utworzyć authorsplik, w którym zamapujesz nazwy użytkowników svn na nazwy użytkowników i wiadomości e-mail ustawione przez programistów za pomocą git configwłaściwości user.namei user.email(zwróć uwagę, że w przypadku usługi takiej jak GitHub wystarczy tylko pasujący adres e-mail).

Następnie git svnsklonuj repozytorium svn do repozytorium git, mówiąc mu o mapowaniu:

git svn clone --authors-file=authors --stdlayout svn://example.org/Folder/projectroot

Może to zająć niewiarygodnie długo, ponieważ git svn osobno sprawdzi każdą wersję dla każdego istniejącego tagu lub gałęzi. (zauważ, że tagi w SVN są tak naprawdę gałęziami, więc kończą jako takie w Git). Możesz to przyspieszyć, usuwając niepotrzebne stare znaczniki i gałęzie w SVN.

Uruchomienie tego na serwerze w tej samej sieci lub na tym samym serwerze może to naprawdę przyspieszyć. Ponadto, jeśli z jakiegoś powodu proces ten zostanie przerwany, możesz go wznowić

git svn rebase --continue

W wielu przypadkach skończysz tutaj. Ale jeśli twoje repozytorium SVN ma niekonwencjonalny układ, w którym po prostu masz katalog w SVN, który chcesz umieścić w gałęzi git, możesz wykonać dodatkowe kroki.

Najprościej jest po prostu utworzyć na serwerze nowe repozytorium SVN, zgodne z konwencją i użyć svn copydo umieszczenia katalogu w bagażniku lub oddziale. To może być jedyny sposób, jeśli katalog jest cały w katalogu głównym repozytorium, kiedy ostatnio próbowałem, git svnpo prostu odmówiłem wykonania transakcji.

Możesz to również zrobić za pomocą git. Po git svn cloneprostu skorzystaj z katalogu, który chcesz umieścić w gałęzi git.

Po biegu

git branch --set-upstream master git-svn
git svn rebase

Pamiętaj, że wymagało to Git 1.7 lub nowszej wersji.


Proponuję połączyć te informacje z tym linkiem: sailmaker.co.uk/blog/2013/05/05/…
Joan PS

7

Opublikowałem przewodnik krok po kroku ( tutaj ), aby przekonwertować svn na git, w tym konwersję tagów svn na tagi git i gałęzie svn na gałęzie git.

Krótka wersja:

1) klon svn z określonego numeru wersji. (numer wersji musi być najstarszy, który chcesz migrować)

git svn clone --username=yourSvnUsername -T trunk_subdir -t tags_subdir -b branches_subdir -r aRevisionNumber svn_url gitreponame

2) pobierz dane SVN. Ten krok zajmuje najwięcej czasu.

cd gitreponame
git svn fetch

powtarzaj pobieranie git svn, aż zakończy się bez błędu

3) zaktualizuj gałąź master

git svn rebase

4) Utwórz oddziały lokalne z oddziałów svn, kopiując odniesienia

cp .git/refs/remotes/origin/* .git/refs/heads/

5) zamień tagi svn na tagi git

git for-each-ref refs/remotes/origin/tags | sed 's#^.*\([[:xdigit:]]\{40\}\).*refs/remotes/origin/tags/\(.*\)$#\2 \1#g' | while read p; do git tag -m "tag from svn" $p; done

6) Umieść repozytorium w lepszym miejscu, takim jak github

git remotes add newrepo git@github.com:aUser/aProjectName.git
git push newrepo refs/heads/*
git push --tags newrepo

Jeśli chcesz uzyskać więcej informacji, przeczytaj mój post lub zapytaj mnie.


6

Możemy użyć git svn clonepoleceń jak poniżej.

  • svn log -q <SVN_URL> | awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2" = "$2" <"$2">"}' | sort -u > authors.txt

Powyższe polecenie utworzy plik autorów z zatwierdzeń SVN.

  • svn log --stop-on-copy <SVN_URL>

Powyższe polecenie da ci pierwszy numer wersji, kiedy tworzony jest projekt SVN.

  • git svn clone -r<SVN_REV_NO>:HEAD --no-minimize-url --stdlayout --no-metadata --authors-file authors.txt <SVN_URL>

Powyższe polecenie utworzy repozytorium Git w wersji lokalnej.

Problem polega na tym, że nie konwertuje gałęzi i tagów do wypychania. Będziesz musiał zrobić to ręcznie. Na przykład poniżej dla oddziałów:

$ git remote add origin https://github.com/pankaj0323/JDProjects.git
$ git branch -a
* master
  remotes/origin/MyDevBranch
  remotes/origin/tags/MyDevBranch-1.0
  remotes/origin/trunk
$$ git checkout -b MyDevBranch origin/MyDevBranch
Branch MyDevBranch set up to track remote branch MyDevBranch from origin.
Switched to a new branch 'MyDevBranch'
$ git branch -a
* MyDevBranch
  master
  remotes/origin/MyDevBranch
  remotes/origin/tags/MyDevBranch-1.0
  remotes/origin/trunk
$

W przypadku tagów:

$git checkout origin/tags/MyDevBranch-1.0
Note: checking out 'origin/tags/MyDevBranch-1.0'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b new_branch_name

HEAD is now at 3041d81... Creating a tag
$ git branch -a
* (detached from origin/tags/MyDevBranch-1.0)
  MyDevBranch
  master
  remotes/origin/MyDevBranch
  remotes/origin/tags/MyDevBranch-1.0
  remotes/origin/trunk
$ git tag -a MyDevBranch-1.0 -m "creating tag"
$git tag
MyDevBranch-1.0
$

Teraz przenieś master, gałęzie i tagi do zdalnego repozytorium git.

$ git push origin master MyDevBranch MyDevBranch-1.0
Counting objects: 14, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (11/11), done.
Writing objects: 100% (14/14), 2.28 KiB | 0 bytes/s, done.
Total 14 (delta 3), reused 0 (delta 0)
To https://github.com/pankaj0323/JDProjects.git
 * [new branch]      master -> master
 * [new branch]      MyDevBranch -> MyDevBranch
 * [new tag]         MyDevBranch-1.0 -> MyDevBranch-1.0
$

narzędzie svn2git

Narzędzie svn2git usuwa ręczne wysiłki z gałęziami i tagami.

Zainstaluj go za pomocą polecenia sudo gem install svn2git. Następnie uruchom poniżej polecenia.

  • $ svn2git <SVN_URL> --authors authors.txt --revision <SVN_REV_NO>

Teraz możesz łatwo wymienić gałęzie, tagi i pchać je.

$ git remote add origin https://github.com/pankaj0323/JDProjects.git
$ git branch -a
  MyDevBranch
* master
  remotes/svn/MyDevBranch
  remotes/svn/trunk
$ git tag
  MyDevBranch-1.0
$ git push origin master MyDevBranch MyDevBranch-1.0

Wyobraź sobie, że masz 20 gałęzi i tagów, oczywiście svn2git zaoszczędzi ci dużo czasu i dlatego lubię to bardziej niż polecenia natywne. To ładne opakowanie wokół natywnego git svn clonepolecenia.

Aby uzyskać pełny przykład, zapoznaj się z moim wpisem na blogu .




3

Jeśli korzystasz z SourceTree, możesz to zrobić bezpośrednio z aplikacji. Idź do pliku -> Nowy / klon, a następnie wykonaj następujące czynności:

  1. Wprowadź zdalny adres URL SVN jako „Ścieżkę / adres URL źródła”.
  2. Po wyświetleniu monitu wprowadź dane uwierzytelniające.
  3. Wprowadź lokalizację folderu lokalnego jako „Ścieżkę docelową”.
  4. Daj temu imię.
  5. W opcjach zaawansowanych wybierz „Git” z menu rozwijanego w „Utwórz lokalne repozytorium typu”.
  6. Opcjonalnie możesz określić wersję, z której chcesz sklonować.
  7. Hit Clone.

Otwórz repozytorium w SourceTree, a zobaczysz, że Twoje wiadomości z zatwierdzeniami również zostały zmigrowane.

Teraz przejdź do repozytorium -> Ustawienia repozytorium i dodaj nowe szczegóły zdalnego repozytorium. Jeśli chcesz, usuń pilota SVN (zrobiłem to za pomocą opcji „Edytuj plik konfiguracyjny”).

Wciśnij kod do nowego zdalnego repozytorium, gdy będziesz gotowy i swobodnie koduj.


Dziękuję, super i szybko!
Rikard

Dziękuję. To działało dla mnie. Używam SourceTree i Stash.
VK_217,

3

Dla użytkowników GitLab przedstawiłem tutaj informacje na temat migracji z SVN:

https://gist.github.com/leftclickben/322b7a3042cbe97ed2af

Kroki migracji z SVN do GitLab

Ustawiać

  • SVN jest hostowany pod adresem svn.domain.com.au.
  • SVN jest dostępny poprzez http(inne protokoły powinny działać).
  • GitLab jest hostowany w git.domain.com.au:
    • Grupa jest tworzona z przestrzenią nazw dev-team.
    • Co najmniej jedno konto użytkownika jest tworzone, dodawane do grupy i ma klucz SSH dla konta używanego do migracji (użycie testowe ssh git@git.domain.com.au).
    • Projekt favourite-projectjest tworzony w dev-teamprzestrzeni nazw.
  • Plik users.txtzawiera odpowiednie dane użytkownika, po jednym użytkowniku w wierszu, w formularzu username = First Last <address@domain.com.au>, gdzie usernamenazwa użytkownika podana jest w logach SVN. (Zobacz pierwszy link w sekcji Referencje, aby uzyskać szczegółowe informacje, w szczególności odpowiedź użytkownika Casey).

Wersje

  • wersja subversion 1.6.17 (r1128011)
  • wersja git 1.9.1
  • GitLab wersja 7.2.1 ff1633f
  • Serwer Ubuntu 14.04

Polecenia

bash
git svn clone --stdlayout --no-metadata -A users.txt 
http://svn.domain.com.au/svn/repository/favourite-project
cd favourite-project
git remote add gitlab git@git.domain.com.au:dev-team/favourite-project.git
git push --set-upstream gitlab master

Otóż ​​to! Ponownie załaduj stronę projektu w internetowym interfejsie GitLab, a zobaczysz wszystkie zatwierdzenia i pliki na liście.

Notatki

  • Jeśli istnieją nieznane użytkowników, git svn clonekomenda stop, w którym to przypadku aktualizacji users.txt, cd favourite-projecti git svn fetchbędzie nadal skąd zatrzymany.
  • Średnia trunk- tags- brancheswymagany jest układ do repozytorium SVN.
  • Adres URL SVN podany dla git svn clonepolecenia zatrzymuje się na poziomie bezpośrednio powyżej trunk/, tags/a branches/.
  • git svn clonePolecenie produkuje dużo mocy, w tym kilka ostrzeżeń na górze; Zignorowałem ostrzeżenia.

Chociaż ten link może odpowiedzieć na pytanie, lepiej dołączyć tutaj istotne części odpowiedzi i podać link w celach informacyjnych. Odpowiedzi zawierające tylko łącze mogą stać się nieprawidłowe, jeśli połączona strona ulegnie zmianie.
Blackhole

1
Nie zgadzam się. Powiązana treść może się zmienić, a treść tutaj powielona nie zostanie zaktualizowana, a zatem może być nieaktualna (i faktycznie uważam, że zmieniła się od czasu, gdy pierwotnie opublikowałem tę odpowiedź). Wytyczne mówią tylko, że zawierają odpowiedni kontekst dla linku, który zrobiłem - na rzeczywiste pytanie odpowiedź została udzielona hurtowo przez link. Kopiowanie całego połączonego zasobu tutaj nie jest wymagane ani konieczne. Czy byłem za to zlekceważony ?!
leftclickben

2

Na marginesie, polecenie git-stash jest darem niebios przy próbie git z poleceniami git-svn.

Typowy proces:

  1. skonfiguruj git repo
  2. popracuj nad różnymi plikami
  3. zdecyduj się sprawdzić część pracy, używając git
  4. zdecydować się na svn-dcommit
  5. otrzymaj przerażający błąd „nie można zatwierdzić z brudnym indeksem”.

Rozwiązanie (wymaga git 1.5.3+):

git stash; git svn dcommit ; git stash apply

2

Oto prosty skrypt powłoki bez żadnych zależności, który przekonwertuje jedno lub więcej repozytoriów SVN na git i wypchnie je do GitHub.

https://gist.github.com/NathanSweet/7327535

W około 30 wierszach skryptu: klonuje za pomocą git SVN, tworzy plik .gitignore z właściwości SVN :: ignore, wypycha do pustego repozytorium git, zmienia nazwę pnia SVN na master, konwertuje tagi SVN na tagi git i wypycha je do GitHub zachowując tagi.

Zadałem sobie wiele trudu, aby przenieść kilkanaście repozytoriów SVN z Google Code do GitHub. Nie pomogło mi to, że korzystałem z systemu Windows. Ruby był zepsuty na moim starym Debianie, a uruchomienie go w systemie Windows było żartem. Inne rozwiązania nie współpracowały ze ścieżkami Cygwin. Nawet kiedy już coś działało, nie mogłem wymyślić, jak sprawić, by tagi pojawiały się na GitHubie (sekret to --follow-tags).

Na koniec połączyłem dwa krótkie i proste skrypty, połączone powyżej i działa świetnie. Rozwiązanie nie musi być bardziej skomplikowane!


2
Użyłem tego skryptu. Po drobnych próbach i błędach zadziałało to dla mnie. Pamiętaj , że potrzebujesz do tego Git 1.8.3+ , ponieważ --follow-tags jest obsługiwane tylko później.
nrobey

2

Korzystam z komputera z systemem Windows i wykonałem małą partię, aby przenieść repozytorium SVN z historią (ale bez oddziałów) do repozytorium GIT, po prostu wywołując

transfer.bat http://svn.my.address/svn/myrepo/trunk https://git.my.address/orga/myrepo

Być może każdy może go użyć. Tworzy folder TMP sprawdza repozytorium SVN za pomocą git i dodaje nowe pochodzenie i wypycha je ... i ponownie usuwa folder.

@echo off 
SET FROM=%1 
SET TO=%2 
SET TMP=tmp_%random%

echo from:  %FROM% 
echo to:    %TO% 
echo tmp:   %TMP%

pause

git svn clone  --no-metadata --authors-file=users.txt %FROM% %TMP%  
cd %TMP% 
git remote add origin %TO% 
git push --set-upstream origin master


cd .. 
echo delete %TMP% ... 
pause

rmdir /s /q %TMP%

Nadal potrzebujesz users.txt z takimi mapowaniami użytkowników jak

User1 = User One <u.1@xxx.com>

Ta odpowiedź pomogła mi bez problemu przenieść wszystkie moje repozytoria do BitBucket.
Gonzalingui

Dobrze słyszeć. Miałem tylko doświadczenie z Giteą ... ale w ten sposób przesłałem ~ 40 repozytoriów.
cljk

Bardzo dobrze! Thnx
b3wii

ostrzeżenie; Wystąpiły problemy ze złym charsetem. Rozpoznałem to naprawdę za późno, ale naprawienie zajęło mi kilka godzin. Sprawdź, czy wynikowe repozytorium zawiera dokładnie (!) Spodziewane źródła
kliknij

1

Chciałem tylko dodać swój wkład do społeczności Git. Napisałem prosty skrypt bash, który automatyzuje pełny import. W przeciwieństwie do innych narzędzi do migracji, to narzędzie opiera się na natywnym git zamiast jGit. To narzędzie obsługuje również repozytoria z dużą historią zmian i / lub dużymi obiektami blob. Jest dostępny przez github:

https://github.com/onepremise/SGMS

Ten skrypt konwertuje projekty przechowywane w SVN w następującym formacie:

/trunk
  /Project1
  /Project2
/branches
     /Project1
     /Project2
/tags
 /Project1
 /Project2

Ten schemat jest również popularny i obsługiwany:

/Project1
     /trunk
     /branches
     /tags
/Project2
     /trunk
     /branches
     /tags

Każdy projekt zostanie zsynchronizowany według nazwy projektu:

Ex: ./migration https://svnurl.com/basepath project1

Jeśli chcesz przekonwertować pełne repozytorium, użyj następującej składni:

Ex: ./migration https://svnurl.com/basepath .

0

Skuteczne używanie Git z Subversion jest delikatnym wprowadzeniem do git-svn. W przypadku istniejących repozytoriów SVN, git-svn czyni to bardzo łatwym. Jeśli zaczynasz tworzenie nowego repozytorium, znacznie łatwiej jest najpierw utworzyć puste repozytorium SVN, a następnie zaimportować je za pomocą git-svn, niż w przeciwnym kierunku. Utworzenie nowego repozytorium Git, a następnie importowanie do SVN może być wykonane, ale jest to trochę bolesne, szczególnie jeśli jesteś nowy w Git i masz nadzieję zachować historię zatwierdzeń.


0

Pobierz instalator Ruby dla Windows i zainstaluj z nim najnowszą wersję. Dodaj pliki wykonywalne Ruby do swojej ścieżki.

  • Zainstaluj svn2git
  • Menu Start -> Wszystkie programy -> Ruby -> Uruchom wiersz polecenia za pomocą Ruby
  • Następnie wpisz „gem install svn2git” i wpisz

    Migruj repozytorium Subversion

  • Otwórz wiersz poleceń Ruby i przejdź do katalogu, w którym pliki mają być migrowane

    Następnie svn2git http: // [ nazwa domeny ] / svn / [root repozytorium]

  • Migracja projektu do Git może potrwać kilka godzin, w zależności od rozmiaru kodu projektu.

  • Ten ważny krok pomaga w tworzeniu struktury repozytorium Git, jak wspomniano poniżej.

    Pień SVN (/ Project_components) -> Git master Oddziały SVN (/ Project_components) -> Oddziały Git Tagi SVN (/ Project_components) -> Tagi Git

Utwórz zdalne repozytorium i prześlij zmiany.


0

GitHub ma importera. Po utworzeniu repozytorium można importować z istniejącego repozytorium za pośrednictwem jego adresu URL. Poprosi o podanie poświadczeń, jeśli dotyczy, i stamtąd.

W trakcie działania znajdzie autorów i możesz po prostu zamapować ich na użytkowników w GitHub.

Użyłem go już do kilku repozytoriów, i jest dość dokładny i znacznie szybszy! Repozytorium z ~ 4000 zatwierdzeniami zajęło 10 minut, a potem mojemu przyjacielowi cztery dni!



0

Istnieją różne metody osiągnięcia tego celu. Wypróbowałem niektóre z nich i znalazłem naprawdę działający z git i svn zainstalowanymi w systemie operacyjnym Windows.

Wymagania wstępne:

  1. git w systemie Windows (użyłem tego) https://git-scm.com/
  2. svn z zainstalowanymi narzędziami konsoli (użyłem żółwia svn)
  3. Zrzuć plik z repozytorium SVN. svnadmin dump /path/to/repository > repo_name.svn_dump

Kroki prowadzące do osiągnięcia ostatecznego celu (przenieś całe repozytorium z historią do git, najpierw git lokalny, a następnie zdalnie)

  1. Utwórz puste repozytorium (używając narzędzi konsoli lub TortoiseSVN) w katalogu REPO_NAME_FOLDER cd REPO_NAME_PARENT_FOLDER, umieść plik zrzutu pliku w REPO_NAME_PARENT_FOLDER

  2. svnadmin load REPO_NAME_FOLDER < dumpfile.dump Poczekaj na tę operację, może być długa

  3. To polecenie jest ciche, więc otwórz drugie okno cmd: svnserve -d -R --root REPO_NAME_FOLDER Dlaczego po prostu nie użyjesz pliku: /// ......? Ponieważ następne polecenie zakończy się niepowodzeniem Unable to open ... to URL:, dzięki odpowiedzi https://stackoverflow.com/a/6300968/4953065

  4. Utwórz nowy folder SOURCE_GIT_FOLDER

  5. cd SOURCE_GIT_FOLDER
  6. git svn clone svn: // localhost / Poczekaj na tę operację.

Wreszcie, co mamy?

Sprawdźmy nasze lokalne repozytorium:

git log

Widzisz swoje poprzednie zobowiązania? Jeśli tak - w porządku

Masz teraz w pełni funkcjonalne lokalne repozytorium git ze źródłami i starą historią svn. Teraz, jeśli chcesz przenieść go na jakiś serwer, użyj następujących poleceń:

git remote add origin https://fullurlpathtoyourrepo/reponame.git
git push -u origin --all # pushes up the repo and its refs for the first time
git push -u origin --tags # pushes up any tags

W moim przypadku nie potrzebuję polecenia tags, ponieważ moje repo nie ma tagów.

Powodzenia!


0

Konwertowanie podmoduła / folderu svn „MyModule” na git z historią bez znaczników i gałęzi.

Aby zachować listę ignorowania SVN, użyj powyższych komentarzy po kroku 1

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.