2012-10-17 11 views
14

Próbuję użyć svn2git do migracji projektu SVN do git. Mam jednak problemy z zachowaniem całej historii. Przyczyny wydają się być takie, że bagażnik został przeniesiony w przeszłości. Polecenie używam jest:Jak zachować historię SVN w Git, gdy trunk został przeniesiony?

$ svn2git http://mysvnserver.com/myproject/iPhone/ --no-minimize-url --authors ../authors.txt 

Ale to tylko daje mi historię wracając do roku 2011. Projekt faktycznie rozpoczął w 2010 roku prognozowany zaczął patrząc tak:

myproject 
    trunk 
    branches 
    tags 

Ale w 2011 roku zostało zmienione na:

myproject 
    iPhone 
    trunk 
    branches 
    tags 
    Android 
     trunk 
     branches 
     tags 

Stary pień i gałęzie przechodzą pod katalogiem iPhone'a. Historia, którą otrzymuję, zaczyna się od tego, kiedy ten ruch został wykonany. Jeśli wykonam svn log w katalogu iPhone'a, otrzymam skróconą historię. Ale jeśli I cd trunk; svn log to otrzymam pełną historię.

Nie mam pojęcia, jak uzyskać tę historię. Mój pomysł polegał na stworzeniu w jakiś sposób repozytorium git z samą historią bagażnika, które ma być kontynuowane do 2010 roku. Później wciągnę to jako gałąź w moim głównym repozytorium i wykonam rebase, aby uzyskać poprawną historię. Ale nie miałem szczęścia tworzenia tego repozytorium tylko dla bagażnika. Próbowałem:

$ svn2git http://mysvnserver.com/myproject/ --rootistrunk --authors ../authors.txt 

i

$ svn2git http://mysvnserver.com/myproject/ --rootistrunk -no-minimize-url --authors ../authors.txt 

bez powodzenia.

Odpowiedz

10

Ja sam miałem ten sam problem. Oto jak to rozwiązałem.

Klonuj oba reposy oddzielnie.

git svn clone -s [original-svn-location] [original-clone-directory] 
git svn clone -s [new-svn-location] [new-clone-directory] 

Dodaj stare sklonowane dane do nowego repo.

cd [new-clone-directory] 
git remote add oldstuff ../[original-clone-directory] 
git fetch oldstuff 

Teraz najtrudniejsza część ... Czy git log z master i oldstuff/master (albo trunk i olstuff/trunk - jednak go skonfigurować) i zapisz sha pierwszy popełniania od nowego klonu i ostatni commit sha ze starego klonu (tuż przed przeprowadzką).

git replace [first-commit-sha-from-new-clone] [last-commit-sha-from-old-clone] 

I przepisać SHA skróty, więc wszystko jest koszerne i nie trzeba już ref zastąpić ...

git filter-branch 

A teraz oczyścić no-longer-potrzebne referencje.

git remote rm oldstuff 
rm -rf .git/refs/replace 

Stracisz pierwszy popełnić z historii, ale od tego, który powinien być początkowy ruch (tzn nie rzeczywiste zawartość pliku uległy zmianie) to prawdopodobnie nie będzie miało znaczenia dla Ciebie.

Teraz cała historia powinna być nadal przechowywana, a raporty git blame pamiętają historię starej repozytorium, zapewniając dokładniejsze informacje.

Powtórz tę czynność tak często, jak to konieczne (w zależności od tego, ile razy projekt zmienił lokalizację root i/lub ile oddziałów zaangażowało się po obu stronach ruchu).

PS - To rozwiązanie zaadaptowałem do moich potrzeb z jednego znalezionego here (nie mogłem dostać jego graftowego podejścia do pracy dla moich repozytoriów - ale używanie zamiany wydaje się działać pięknie).

+0

Nie mogę już dobrze zapamiętać problemu, ale ustawiłem to jako odpowiedź, ponieważ wydaje mi się to najbardziej zbliżone do tego, jak faktycznie rozwiązałem problem. Sądzę, że stworzyłem całą masę oddzielnych gałęzi, a następnie zszyłem je razem, patrząc na historię, jak opisujesz. –

2

Możesz użyć SubGit, aby skonwertować swoje repozytorium SVN.

Niestety, wersja 1.0 nie obsługuje złożonego układu takiego, jaki masz. Ale jest 1.1 EAP version, który dobrze to obsługuje. Obie wersje 1.0 i 1.1 działają z lokalnym repozytorium SVN, więc musisz mieć dostęp administracyjny do repozytorium SVN.

proszę wykonać następujące czynności w celu konwersji do repozytorium SVN Git:

  1. wygenerować początkową konfigurację.

    $ subgit configure SVN_REPO 
    
  2. Najprawdopodobniej SubGit wykryje dwa projekty wewnątrz tego repozytorium. AFAIU, potrzebujesz tylko jednego repozytorium Git. Tak więc, musisz zachować tylko jedną sekcję "git" w pliku konfiguracyjnym. Określ wszystkie gałęzie, których potrzebujesz do konwersji.

    $ EDITOR SVN_REPO/conf/subgit.conf 
    [core] 
        ... 
    [git "default"] 
        repository = .git 
        ... 
        trunk = trunk:refs/heads/master 
        branches = branches/*:refs/heads/* 
        tags = tags/*:refs/tags/* 
        shelves = shelves/*:refs/shelves/* 
        branches = iPhone/trunk:refs/heads/iPhone/master 
        branches = iPhone/branches/*:refs/heads/iPhone/* 
        tags = iPhone/tags/*:refs/tags/iPhone/* 
        branches = Android/trunk:refs/heads/Android/master 
        branches = Android/branches/*:refs/heads/Android/* 
        tags = Android/tags/*:refs/tags/Android/* 
        ... 
    [daemon] 
        ... 
    
  3. Konwersja SVN na Git.

    $ subgit install SVN_REPO 
    
  4. W tym momencie SubGit konwertuje wszystkie wersje z SVN na Git. Możesz znaleźć przekonwertowane repozytorium Git na SVN_REPO/.git. Dodatkowo SubGit synchronizuje repozytoria SVN i Git, instaluje specjalne haki, aby to osiągnąć. W razie potrzeby pozbyć się tych haczyków.

    $ subgit uninstall --purge SVN_REPO 
    

To wszystko. Teraz przekonwertowałeś repozytorium Git z zachowaną całą historią.

Należy pamiętać, że SubGit jest produktem komercyjnym, ale ten rodzaj jednorazowej konwersji jest bezpłatny. Mam nadzieję, że działa dobrze dla ciebie.

+0

To wygląda na dobre rozwiązanie, ale ponieważ już dawno to zrobiłem, nie mogę zweryfikować rozwiązania i ustawić go jako odpowiedź. Ale jeśli ktoś inny może potwierdzić, że to działa, cieszę się, że jest to poprawna odpowiedź. –

Powiązane problemy