Co zrobić z dużą historią svn, przechodząc do git?


23

Edycja: w przeciwieństwie do niektórych podobnych pytań, takich jak Przenoszenie repozytorium SVN z wieloma GB do Git lub /programming/540535/managing-large-binary-files-with-git Mój scenariusz nie obejmuje kilku podprojektów, które można łatwo przekonwertować na submoduły git, a także kilka bardzo dużych plików binarnych, które dobrze nadają się do załącznika git. Jest to pojedyncze repozytorium, w którym pliki binarne są zestawem testowym ściśle powiązanym z głównym kodem źródłowym tej samej wersji, podobnie jak gdyby były to zasoby czasu kompilacji, takie jak grafika.

Badam zmianę starego repozytorium kodu z svn na średnie / duże rozmiary (50 użytkowników, 60 000 wersji, historia 80 Gb, kopia robocza 2 Gb). Wraz ze wzrostem liczby użytkowników występuje duże opóźnienie w przesyłaniu danych, a funkcje są często rozkładane na wiele zatwierdzeń, co utrudnia przegląd kodu. Również bez rozgałęzienia nie ma możliwości „zejścia” złego kodu, przeglądy można wykonać dopiero po jego przypisaniu do pnia. Badam alternatywy. Miałem nadzieję, że możemy przejść do git, ale mam pewne problemy.

Problem z obecnym repo w zakresie git dotyczy rozmiaru. Jest tam wiele starych cruftów, a czyszczenie go za pomocą --filter-branch podczas konwersji na git może zmniejszyć jego rozmiar o rząd wielkości, do około 5-10 GB. To wciąż jest za duże. Największym powodem dużego rozmiaru repozytorium jest to, że do testów wchodzi wiele dokumentów binarnych. Pliki te różnią się między .5mb a 30mb, a są ich setki. Mają też sporo zmian. Patrzyłem na podmoduły, git-aneks itp., Ale posiadanie testów w podmodule wydaje się błędne, podobnie jak posiadanie załącznika do wielu plików, dla których chcesz mieć pełną historię.

Tak więc rozproszony charakter git jest naprawdę tym, co powstrzymuje mnie przed przyjęciem go. Tak naprawdę nie dbam o dystrybucję, chcę tylko tanie rozgałęzienia i potężne funkcje łączenia. Tak jak zakładam, że robi to 99,9% użytkowników git, użyjemy błogosławionego, czystego centralnego repozytorium.

Nie jestem pewien, czy rozumiem, dlaczego każdy użytkownik musi mieć pełną historię lokalną podczas korzystania z git? Jeśli przepływ pracy nie jest zdecentralizowany, co te dane robią na dyskach użytkowników? Wiem, że w najnowszych wersjach git możesz używać płytkiego klona z najnowszą historią. Moje pytanie brzmi: czy jest to wykonalne jako standardowy tryb działania dla całego zespołu? Czy git może być skonfigurowany tak, aby zawsze był płytki, abyś mógł mieć pełną historię tylko centralnie, ale użytkownicy domyślnie mają tylko 1000 obrotów historii? Opcją jest oczywiście konwersja 1000 obrotów na git i zachowanie repozytorium svn dla archeologii. W tym scenariuszu ponownie napotkalibyśmy ten sam problem po kolejnych kilku tysiącach poprawek dokumentów testowych.

  • Co to jest dobry najlepszych praktyk za korzystanie z dużymi repo git zawierających wiele plików binarnych, które nie chcą historię? Większość najlepszych praktyk i samouczków wydaje się unikać tego przypadku. Rozwiązują problem kilku ogromnych plików binarnych lub proponują całkowite ich usunięcie.
  • Czy płytkie klonowanie jest użyteczne jako normalny tryb działania, czy też jest to „hack”?
  • Czy można zastosować podmoduły w kodzie, w którym istnieje ścisła zależność między główną wersją źródłową a wersją podmodułu (na przykład w zależnościach binarnych w czasie kompilacji lub pakiecie testów jednostkowych)?
  • Jak duży jest „zbyt duży” dla repozytorium git (lokalnie)? Czy powinniśmy unikać zmiany, jeśli uda nam się obniżyć ją do 4 GB? 2 GB?


Dużo szukałem informacji na ten temat i nie znalazłem niczego, co odpowiadałoby na moje pytanie. W powiązanym pytaniu pracodawcy (podmoduły, aneks itp.) Działałyby znacznie lepiej niż w moim scenariuszu.
Anders Forsgren,


Perforce może być lepszą opcją niż git, ponieważ jest przeznaczony do radzenia sobie z dużą ilością dużych plików binarnych, dlatego jest używany przez wielu twórców gier. Warto również spojrzeć na Plasticscm.
Ian

Na marginesie: unikaj podmodułów git, jeśli możesz, ponieważ nadmiernie komplikują system kompilacji (co w twoim przypadku jest już skomplikowane).
IgorGanapolsky

Odpowiedzi:


10

Wow, to długie pytanie (i złożony problem). Spróbuję spróbować.

Nie jestem pewien, czy rozumiem, dlaczego każdy użytkownik musi mieć pełną historię lokalną podczas korzystania z git?

Jest to centralna decyzja projektowa z git. Dokładnie z powodów, dla których musisz zapytać autora (Linus Torvalds), ale o ile mi wiadomo, głównym powodem jest szybkość: Posiadanie wszystkiego lokalnego (na szybkim dysku lub nawet w pamięci podręcznej w pamięci RAM) znacznie przyspiesza operacje na historii unikając dostępu do sieci.

Największym powodem dużego rozmiaru repozytorium jest to, że do testów wchodzi wiele dokumentów binarnych. Pliki te różnią się między .5mb a 30mb, a są ich setki. Mają też sporo zmian.

O tym pomyślałbym pierwszy. Problemem wydaje mi się posiadanie tak wielu ciągle zmieniających się plików binarnych w kontroli źródła (nawet SVN). Nie możesz zastosować innego podejścia? Pomysły:

  • W przeciwieństwie do kodu źródłowego plik binarny o wielkości 3 MB prawdopodobnie nie jest zapisywany ręcznie. Jeśli jakieś narzędzie / proces je generuje, rozważ zintegrowanie go z kompilacją zamiast przechowywania danych.

  • Jeśli nie jest to praktyczne, zwykle lepiej jest przechowywać pliki binarne w repozytorium artefaktów (takim jak Artifactory for Maven & co.). Może to jest dla ciebie opcja.

Patrzyłem na podmoduły, git-aneks itp., Ale testowanie w podmodule wydaje się błędne, podobnie jak posiadanie załącznika do wielu plików, dla których chcesz mieć pełną historię.

W rzeczywistości wygląda to tak, jakby idealnie pasował do git-annex. git-Annex zasadniczo pozwala przechowywać zawartość pliku poza repozytorium git (repozytorium zawiera zamiast niego symbol zastępczy). Możesz przechowywać zawartość pliku na różne sposoby (centralne repozytorium git, dysk udostępniony, pamięć w chmurze ...) i możesz kontrolować, która zawartość ma być lokalnie.

Czy może źle zrozumiałeś, jak działa git-annex? git-annex przechowuje pełną historię wszystkich zarządzanych plików - pozwala tylko wybrać zawartość pliku, którą chcesz mieć lokalnie.

Wreszcie o twoich pytaniach:

Jaka jest dobra najlepsza praktyka używania git z dużymi repozytoriami zawierającymi wiele plików binarnych, dla których chcesz historii?

Z mojego doświadczenia wynika, że ​​zazwyczaj są to:

  • unikaj potrzeby plików binarnych w repozytorium (generuj je na żądanie, przechowuj w innym miejscu)
  • użyj git-annex (lub podobnego rozwiązania, takiego jak Git LFS)
  • na żywo z dużym repozytorium (duże pliki nie wpływają na wszystkie operacje git, a jeśli masz szybki komputer i dysk, może to być całkiem wykonalne)

Czy płytkie klonowanie jest użyteczne jako normalny tryb działania, czy też jest to „hack”?

To może być wykonalne; nie sądzę jednak, aby to rozwiązało problem:

  • straciłbyś korzyści git wynikające z posiadania pełnej historii, takie jak szybkie przeszukiwanie historii
  • scalanie może być trudne, ponieważ AKAIK musi mieć przynajmniej historię z powrotem do punktu oddziału, aby połączyć
  • użytkownicy będą musieli okresowo klonować ponownie, aby zachować niewielki rozmiar swojego klonu
  • jest to po prostu niezwykły sposób korzystania z git, więc prawdopodobnie będziesz mieć problemy z wieloma narzędziami

Jak duży jest „zbyt duży” dla repozytorium git (lokalnie)? Czy powinniśmy unikać zmiany, jeśli uda nam się obniżyć ją do 4 GB? 2 GB?

To zależy od struktury repozytorium (kilka / wiele plików itp.), Od tego, co chcesz zrobić, od tego, jak potężne są twoje komputery i od twojej cierpliwości :-).

Aby dać ci szybki pomysł: na moim (nowym, ale mało wymagającym) laptopie zatwierdzenie pliku 500 MB zajmuje 30-60 sekund. Duże pliki nie mają wpływu tylko na wyświetlanie historii (git log itp.); rzeczy takie jak „git log -S”, które muszą skanować zawartość pliku, są bardzo wolne - jednak szybkość jest głównie zdominowana przez operacje we / wy, więc tak naprawdę nie jest to wina gita.

W repozytorium 3 GB z kilkoma poprawkami „git log -S” zajmuje około minuty.

Powiedziałbym więc, że kilka GB jest w porządku, choć nie jest idealne. Prawdopodobnie przekracza 10-20 GB, ale może to być wykonalne - musisz spróbować.


Dziękuję za szczegółową odpowiedź. Z pewnością przyjrzę się użyciu załącznika do dokumentów testowych. Pasek „rozsądnej wydajności” jest prawdopodobnie „zbliżony do svn”, tj. Jeśli jest znacznie wolniejszy dla jakiejkolwiek operacji, to byłoby zbyt duże tarcie do przełączenia.
Anders Forsgren,

Myślę, że Git LFS może być również używany do przechowywania dużych plików binarnych.
IgorGanapolsky

@IgorG .: Tak, Git LFS jest alternatywą, są też inne. Dziękuję za zwrócenie uwagi, zredagowałem swój post.
sleske,

4

Wraz ze wzrostem liczby użytkowników występuje duże opóźnienie w przesyłaniu danych, a funkcje są często rozkładane na wiele zatwierdzeń, co utrudnia przegląd kodu. Również bez rozgałęzienia nie ma możliwości „zejścia” złego kodu, przeglądy można wykonać dopiero po jego przypisaniu do pnia

Przejście do git nie rozwiąże tych problemów, są one problemami w sposobie korzystania z narzędzia, a jeśli używasz git w ten sam sposób, problemy pozostaną.

Możesz rozgałęziać się w svn równie łatwo w git, a łączenie jest zasadniczo tak samo łatwe i ma takie same pułapki. Git został zaprojektowany do pracy z kodem źródłowym jądra, więc przyjął pewne założenia, które mogą nie mieć zastosowania we wszystkich przypadkach, takie jak twoje z dużymi plikami binarnymi i ogromnymi historiami. Zamiarem DVCS jest to, aby każdy użytkownik efektywnie działał sam, a potem współpracował dopiero później - tj. Ma swoje własne repozytorium (kopię), działa tak, jak mu się podoba, a następnie przekazuje zmiany każdemu, kto tego chce. System stowarzyszony używany w rozwoju jądra Linuksa jest do tego idealny - przesuwasz swoje zmiany do następnego faceta w łańcuchu, który łączy go ze swoją bazą kodów, a następnie przekazujesz do następnego faceta, dopóki nie dotrze do Linusa, który umieści go w wydaniu. Większość drużyn korzysta z git podobnie, ale tylko z jednym facetem, który często jest „złotym” repozytorium po stronie serwera,

Chciałbym więc najpierw zmienić przepływ pracy, migrując do git dopiero wtedy, gdy masz lepszy sposób pracy. Zaimplementuj rozgałęzianie i scalanie w SVN, jeśli nie zmienisz nazwy plików lub katalogów scalanie przebiega całkiem dobrze.


4
„Możesz rozgałęziać się w svn równie łatwo w git, a łączenie jest na ogół tak samo łatwe i ma takie same pułapki”, wow, to jest naprawdę kontrowersyjne twierdzenie. Łączenie się w git jest moim zdaniem zwykle proste, aw svn zwykle koszmar, nawet w wersjach po wprowadzeniu na wpół wypalonej próby śledzenia scalania (tak, pracuję z git, nie tylko w tym repozytorium). Przepływ pracy, który chcemy mieć, to taki, w którym tworzysz gałąź funkcji, przegląd kodu / kompilację CI na tej gałęzi. Po prostu nie ma takiej możliwości w SVN bez ogromnej frustracji.
Anders Forsgren,

2
nie, robimy to cały czas tutaj. Właśnie przeglądam 157 gałęzi w moim repozytorium SVN, aby zobaczyć, które można usunąć. Rozgałęziamy, opracowujemy, przeglądamy, a następnie łączymy tutaj prawie codziennie, czasami wpadamy w kłopoty, ale zawsze jest to naprawiane przez usunięcie nowej gałęzi z pnia i połączenie zmian w tym (aby można było później łatwo z powrotem połączyć z pniem) . Dotyczy to jednak tylko starożytnych gałęzi. Jeśli masz ogromną frustrację, nie rozumiesz jej wystarczająco dobrze. Git spowoduje również ogromne frustracje.
gbjbaanb

2
Po prostu tego nie doświadczam. Podczas pracy z git (tak jak mówiłem, ale w mniejszych repozytoriach) uważam, że tworzenie gałęzi, przekształcanie, zgniatanie i scalanie jest dość łatwe i naturalne. „Konflikty drzew po nazwach” itp. Są znacznie rzadsze, a fakt, że możesz naśladować prostą i prostą historię (poprzez rebase + squash itp.) Jest bardzo ważny. Więc: dla zachowania pytania na ten temat (git z dużymi repozytoriami): Załóżmy, że svn nie obsługuje przepływu pracy, którego potrzebuję, a git robi to.
Anders Forsgren,

1
W poprzedniej firmie korzystaliśmy z git i znam kogoś, kto regularnie tracił pracę, używając go, więc to nie jest idealny system pod żadnym względem! SVN też nie jest, ale SVN jest znacznie lepiej przystosowany do twoich okoliczności niż git IMHO i działa. Na temat, jak sprawić, by git działał tak, jak chcesz ... Naprawdę nie jestem pewien, czy tak będzie, przepraszam.
gbjbaanb

7
@gbjbaanb, jeśli ktoś traci pracę z Gitem, robi coś strasznie złego.
RubberDuck,

2

Przejrzyj listę mailingową GCC. Migracja drzewa źródłowego kompilatora GCC z SVN do GIT jest obecnie omawiana (sierpień i wrzesień 2015), przy jednoczesnym zachowaniu historii GCC. Zobacz np. Repozytorium dla maszyn do konwersji i kryteriów akceptacji dla wątków poczty konwersji git ; znajdziesz odniesienia do narzędzi i procedur związanych z konwersją (co nie jest tak proste, jak się wydaje; konwersja tak dużej historii kodu wymaga 36 godzin i około 64 GB pamięci RAM, IIRC)


Miałeś na myśli migrację z SVN do Git? Migracja z systemu kontroli wersji do pakietu kompilatorów wydaje się nieco ... dziwna. Ponadto brzmi to bardziej jak komentarz niż odpowiedź.
8bittree

Tak. Przepraszam za literówkę.
Basile Starynkevitch,

Dzięki. 36 godzin brzmi jak wiatr, nasz może się przekształcić w ciągu kilku tygodni ...
Anders Forsgren

2

Jeśli przekonwertowanie całego repozytorium SVN na Git spowoduje powstanie ogromnego repozytorium, którego klonowanie jest niemożliwe, możesz spróbować użyć SubGit do utworzenia mniejszych kopii lustrzanych Git dla niektórych części repozytorium Subversion.

Na przykład możesz zaimportować i zsynchronizować niektóre podkatalogi z repozytorium SVN http://domain/repos/trunk/project/src:

subgit configure --layout auto --trunk trunk/project/src http://domain/repos project.git
edit project.git/subgit/config
edit project.git/subgit/authors.txt
subgit install project.git

Więcej informacji na temat korzystania z SubGit znajduje się w jego dokumentacji .

Gdy tylko będziesz mieć kopię lustrzaną Git tego katalogu, możesz użyć repozytorium Git do przesłania nowych zmian, które natychmiast zostaną odzwierciedlone w repozytorium SVN. Ponieważ synchronizujesz tylko określoną część repozytorium SVN, która znacznie zmniejsza rozmiar przekonwertowanego repozytorium Git i nadal możesz tworzyć gałęzie, scalać je, stosować dowolny przepływ pracy od strony Git.

Alternatywnie możesz zaimportować całe repozytorium SVN, ale wykluczyć duże pliki z synchronizacji:

subgit configure --layout auto --trunk trunk http://domain/repos project.git
edit project.git/subgit/config
...
[svn]
    excludePath = *.bin
    excludePath = *.iso
...
edit project.git/subgit/authors.txt
subgit install project.git

Wynikowe repozytorium Git powinno mieć rozsądny rozmiar, a programiści mogą nadal używać Git do przesyłania swoich zmian do repozytorium Subversion.

Pamiętaj, że to rozwiązanie powinno działać dobrze, jeśli jesteś gotowy, aby utrzymać serwer Subversion działający i używać Git razem z repozytorium SVN.

Oświadczenie: Jestem jednym z programistów SubGit; SubGit to komercyjne oprogramowanie z wieloma dostępnymi bezpłatnymi opcjami.


1

Podejdę do twojej sytuacji w następujący sposób:

1) Zainicjuj repozytorium git w tym samym katalogu, co repozytorium SVN. Zrób git initi git remote add originaby rozpocząć to repozytorium git. W ten sposób możesz kontynuować zatwierdzanie SVN i git osobno, bez zajmowania się pełną konwersją z jednego do drugiego, dopóki nie będziesz gotowy.

2) Aktywnie używaj narzędzi bfg i filter-branch , aby spróbować zmniejszyć git repo, jak omówiono tutaj: https://confluence.atlassian.com/bitbucket/reduce-repository-size-321848262.html

3) Użyj git-annex, Git LFS lub po prostu zewnętrznego serwera pamięci dla dużych plików binarnych (transport plików przy użyciu skryptów powłoki w czasie kompilacji).

4) Gdy poczujesz się dobrze ze strategią łączenia / rozgałęziania w swoim repozytorium git i nie masz nic przeciwko wielkości repozytorium git, możesz następnie przeprowadzić pełną migrację z svn do git.

Mam nadzieję że to pomoże.

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.