Pliki binarne w kontroli źródła

30

Podczas opracowywania dla urządzeń osadzonych i innych dziwnych światów jest bardzo prawdopodobne, że proces kompilacji będzie obejmował wiele zastrzeżonych plików binarnych, z wykorzystaniem ich bardzo specyficznych wersji. Pytanie brzmi, czy są one częścią twojej kontroli źródła? W moich biurach obowiązuje zasada „wyewidencjonowywanie kontroli źródła obejmuje wszystko, czego potrzebujesz do skompilowania kodu”, co doprowadziło do poważnych argumentów.

Główne argumenty, które widzę przeciwko temu, to rozdęcie DB kontroli źródła, brak różnicowania plików binarnych ( patrz wcześniejsze pytania na ten temat) . Jest to sprzeczne ze zdolnością do sprawdzania, budowania, wiedząc, że masz dokładne środowisko, które zamierzał poprzedni programista, i bez szukania odpowiednich plików (z konkretnymi wersjami nie mniej!)

Daniel Goldberg
źródło
3
Alternatywnie możesz napisać skrypt bash / python / perl / bat do kasy źródłowej i pobrać wszystkie inne zależne składniki w jednym kroku. Jednak nadal polecam sprawdzanie plików binarnych w kontroli wersji, tylko ze względu na zachowanie poprawek. Jedynymi plikami, których nie należy sprawdzać w repozytorium, są pliki, które można łatwo odtworzyć z plików kontrolowanych wersjami. Miejsce na dysku jest tanie i nie powinno być głównym czynnikiem.
Lie Ryan,

Odpowiedzi:

28

Ideą KONTROLI WERSJI (myląca nazwa: kontrola źródła) jest umożliwienie ci cofnięcia się do historii, odzyskania efektu zmian, zobaczenia zmian i powodów ich wprowadzenia. Jest to szereg wymagań, z których niektóre wymagają binarnych rzeczy, a niektóre nie.

Przykład: W przypadku wbudowanego oprogramowania układowego zwykle masz kompletny zestaw narzędzi: albo kompilator, który kosztuje dużo pieniędzy, albo jakąś wersję gcc. Aby uzyskać plik wykonywalny wysyłki, potrzebujesz zarówno łańcucha narzędzi, jak i źródła.

Sprawdzanie łańcuchów narzędzi w kontroli wersji jest uciążliwe, narzędzia różnicowania są okropne (jeśli w ogóle), ale nie ma alternatywy. Jeśli chcesz zachować zestaw narzędzi dla faceta, który przyjrzy się Twojemu kodowi za 5 lat, aby dowiedzieć się, co on robi, to nie masz wyboru: MUSISZ mieć również kontrolę łańcucha wersji.

Przez lata odkryłem, że najprostszym sposobem na zrobienie tego jest utworzenie pliku ZIP lub ISO instalacyjnego dysku CD i wpisanie go. Komentarzem do zgłoszenia musi być konkretny numer wersji producenta zestawu narzędzi. Jeśli gcc lub podobny, spakuj wszystko, czego używasz, w duży plik ZIP i zrób to samo.

Najbardziej ekstremalnym przypadkiem, jaki zrobiłem, jest Windows XP Embedded, gdzie „toolchain” to działająca maszyna wirtualna z systemem Windows XP, która zawiera (wtedy) SQL Server i stos plików konfiguracyjnych wraz z setkami plików łatek. Zainstalowanie całej partii i jej aktualizacja zajęło około 2-3 dni. Zachowanie tego dla potomności oznaczało sprawdzenie CAŁEJ maszyny wirtualnej w kontroli wersji. Widząc, że dysk wirtualny składa się z około 6 x 2 GB obrazów, faktycznie poszło całkiem nieźle. Brzmi nieźle, ale bardzo ułatwiło to życie osobie, która poszła za mną i musiała z niej skorzystać - 5 lat później.

Podsumowanie: Kontrola wersji jest narzędziem. Używaj go, aby być skutecznym, nie rozwieszaj się na temat znaczenia słów i nie nazywaj go „kontrolą źródła”, ponieważ jest większy.

szybko
źródło
1
A kiedy maszyna wirtualna wymaga aktualizacji balonów repo do 12 GB? Nawet jeśli masz dobre binarne różnice, nadal mówisz o repozytorium 10 GB +
TheLQ
3
Więc nie. Jeśli korzystasz z VMWare, możesz użyć migawek dysku. Przechowują oryginalny obraz dysku podstawowego i dodają nowe pliki zawierające tylko delty, które są dość małe. Trzeba tylko pamiętać, aby sprawdzić nowo utworzone pliki. Na koniec patrzę na to, dodano aktualizację około 250 000 - karma dla kurczaków. Poza tym martwienie się o rozmiar repo nie ma sensu - dysk jest tani.
szybko_now
A co, gdy wbudowane narzędzie łańcucha zależy od licencji sieciowej :)
Dan
18

Neal Ford twierdzi w The Productive Programmer , że powinieneś utrzymywać pliki binarne pod kontrolą źródła:

Po co przechowywać pliki binarne? Dzisiejsze projekty zależą od szeregu zewnętrznych narzędzi i bibliotek. Załóżmy, że używasz jednej z popularnych platform rejestrowania (takich jak Log4J lub Log4Net). Jeśli nie budujesz plików binarnych dla tej biblioteki rejestrowania w ramach procesu kompilacji, powinieneś zachować kontrolę wersji. Pozwala to na kontynuowanie budowy oprogramowania, nawet jeśli ramka lub biblioteka, o której mowa, znikają (lub, co bardziej prawdopodobne, wprowadza przełomową zmianę w nowej wersji). Zawsze zachowuj cały wszechświat wymagany do zbudowania oprogramowania pod kontrolą wersji(bez systemu operacyjnego, a nawet jest to możliwe w przypadku wirtualizacji; patrz „Korzystanie z wirtualizacji” w dalszej części tego rozdziału). Możesz zoptymalizować zachowywanie plików binarnych, zarówno poprzez kontrolę wersji, jak i na udostępnionym dysku sieciowym. W ten sposób nie musisz radzić sobie z nimi co godzinę, ale są one zapisywane na wypadek, gdybyś musiał coś odbudować rok później. Nigdy nie wiesz, czy będziesz musiał coś odbudować. Budujesz go, aż zadziała, a potem o nim zapominasz. Panika skłania do uświadomienia sobie, że musisz odbudować coś sprzed dwóch lat i nie masz wszystkich elementów.

Nie mogłem się więcej zgodzić; chociaż prawdopodobnie podważa to VCS dla zadania, do którego nie zostało zaprojektowane (utrzymywanie plików binarnych), myślę, że korzyści przewyższają potencjalne wady. Ale, jak zauważa później autor, czasami utrzymywanie plików binarnych w VCS może nie być praktycznym rozwiązaniem, dlatego należy rozważyć inne opcje - jak trzymanie ich na zmapowanym dysku sieciowym.

Jeśli pliki binarne nie są zbyt duże, zdecydowanie trzymałbym je w VCS. Wydaje się, że jest to jeszcze bardziej prawdziwe w twoim przypadku, ponieważ pliki binarne są prawdopodobnie małe i pracujesz z bardzo konkretnymi wersjami. Mogą być również trudne do znalezienia z różnych powodów (autorzy zamknęli stronę internetową lub potrzebna wersja nie jest już wymieniona do pobrania). Chociaż mało prawdopodobne, nigdy nie wiadomo, co stanie się za kilka lat.

Chciałbym przeczytać tę książkę kilka lat temu, kiedy pracowałem nad grą wykorzystującą bibliotekę graficzną (która była plikiem DLL); Na chwilę przerwałem programowanie i kiedy chciałem kontynuować, nie mogłem ponownie znaleźć biblioteki DLL, ponieważ projekt umarł.

Mihai Rotaru
źródło
2
Tak, zdarza się to zbyt często. Mam projekt hobby, w którym polegam na generatorze skanera, który został porzucony przez autora 3-4 lata temu. Na szczęście zawsze był pod kontrolą wersji.
Christian Klauser
9

Zasadniczo doceniam obóz „sprawdź wszystko, co potrzebujesz, aby wbudować w kontrolę źródła”, ale zarządzanie zależnościami ewoluowało w ciągu ostatnich kilku lat, dzięki narzędziom takim jak Maven, Ivy i NuGet.

Ponadto w praktyce sprawdzanie plików binarnych powoduje szereg nieprzyjemnych skutków ubocznych. Na przykład Git / Mercurial nie są do tego dostrojone, a Subversion i Perforce mogą doprowadzić cię do szału podczas łączenia gałęzi zawierających pliki binarne.

Dzięki rozwiązaniu do zarządzania zależnościami określasz w pliku kontrolowanym przez źródło w projekcie, od których nazw pakietów i wersji zależy twój projekt. Prawie wszystkie narzędzia do zarządzania zależnościami umożliwiają utworzenie prywatnego repozytorium zależności, zgodnie z pewną konwencją wersjonowania i nazewnictwa; podczas kompilacji narzędzie do zarządzania zależnościami rozwiąże wszystkie zależności typu open source i zastrzeżone z listy zatwierdzonych źródeł, a następnie umieści je w lokalnej pamięci podręcznej. Następnym razem, gdy będziesz budować z tymi samymi zależnościami od wersji, wszystko już istnieje i idzie znacznie szybciej.

Kopię zapasową prywatnego repozytorium można następnie wykonać za pomocą konwencjonalnych narzędzi do tworzenia kopii zapasowych systemu plików.

Pozwala to uniknąć spowolnień, których doświadczyłem, gdy tona plików binarnych jest pobierana z drzewa źródłowego, i zapobiega przechowywaniu w repozytorium wielu trudnych do odróżnienia plików. Istnieje tylko jedna lokalizacja dla dowolnej zależności, według nazwy i numeru wersji, więc nie ma konfliktów scalania do rozwiązania, a buforowanie lokalnego systemu plików oznacza, że ​​nie musisz ponosić kosztów oceny, czy lokalna kopia zmieniła się, gdy pobierasz aktualizacje.

JasonTrue
źródło
8

Kontrola źródła dotyczy źródeł. Źródła są tym, czego nie możesz zbudować z innych rzeczy. Niektóre pliki, które kwalifikują się jako źródła, są czasami plikami binarnymi.

Mój VCS ma w sobie wiele plików binarnych, ale każdy z nich jest jednostką wydaną przez jakiś produkt, którego nie napisałem i nie utrzymuję. Może to być coś w rodzaju GNU ccRTP, który jest wydawany jako skompresowany plik tar. Ten archiwum jest moim źródłem i jest sprawdzane wraz z infrastrukturą, której potrzebuję, aby przekształcić go w gotowy produkt (w moim przypadku specyfikację Makefile i RPM) w jednym, zautomatyzowanym kroku. Kiedy pojawia się nowa wersja ccRTP, traktuję nowy plik archiwum jako zmienione źródło: przechodzi do wypisanej kopii, zostaje skompilowany, przetestowany i oddany z powrotem do VCS. Zrobiłem to samo z produktami komercyjnymi, które nie są dostarczane ze źródłem (kompilatory, biblioteki itp.) I działa w ten sam sposób. Zamiast rozpakować-skonfigurować-skompilować-pakiet, to po prostu rozpakować-pakiet. Oprogramowanie, które wykonuje kompilacje nocne, nie wykonujemake i zdobądź gotowe produkty.

Większość VCSów ma funkcje, które sprawiają, że czytelne dla człowieka źródło jest łatwiejsze w obsłudze i bardziej wydajne w przechowywaniu, ale stwierdzenie, że nie są one dostosowane do plików binarnych, nie jest tak naprawdę prawdą, jeśli binarne programy wbudowane wracają bez przeszkód. To, jak VCS radzi sobie wewnętrznie z plikami binarnymi, zależy całkowicie od tego, czy jego autorzy uważali, że próba tylko przechowywania różnic była warta wysiłku. Osobiście uważam, że przechowywanie pełnych kopii dystrybucji ccRTP przy 600 KB na pop jest więcej niż nadrobione przez możliwość oznaczenia jej wersji wraz ze wszystkimi innymi źródłami.

Blrfl
źródło
4

Przypomina mi to problem „słoików w repozytorium”, który miał jakiś czas temu Java. Ludzie budujący aplikacje Java używali do wypychania swoich zależności (binarnych plików jar) do repozytoriów. Wszyscy byli z tego zadowoleni, ponieważ mielibyśmy system budowania „jednym kliknięciem”, a miejsce na dysku jest tanie, więc kogo to obchodzi. Potem przyszedł Maven i mogłeś pozbyć się tego całego binarnego crufta, a dzięki lokalnemu repozytorium tylko do pamięci podręcznej nadal utrzymujesz kompilacje bullet-prof. Nadal masz system kompilacji „jednym kliknięciem”, ale kontrola źródła nie musi tasować plików binarnych, co nie ma sensu.

Tak, możesz pobrać pliki binarne spod kontroli źródła, ale będzie to wymagało ulepszenia systemu kompilacji, aby uzyskać je w czasie kompilacji. Bez dedykowanego oprogramowania (takiego jak Maven) włożenie ich może wymagać wiele wysiłku.

Jacek Prucia
źródło
1
Martwię się o komplikowanie procesu kompilacji, głównie dlatego, że duża część zespołu to matematycy, a nie wielcy fani procesu.
Daniel Goldberg,
3

Kontrola źródła zawiera źródła tego, co robisz. Jeśli dany binarny obiekt blob można odtworzyć ze źródeł, nie jest on źródłem i nie powinien wchodzić do repozytorium kodu źródłowego. Tylko nieuleczalne obiekty blob powinny być w kontroli źródła.

Zwykle masz inny folder sieciowy repozytorium binarnych obiektów blob utworzonych przez źródła. Można je wdrożyć u klientów lub wykorzystać w projektach (zamiast budować wszystko od nowa za każdym razem).

Więc wstaw to, jeśli jest to źródło. Nie, jeśli nie.


źródło
Kto by to głosował? Ciekawe, dlaczego: D
To nie byłem ja, ale podejrzewam, że ktokolwiek się nie zgodził z drugą połową odpowiedzi.
Joel Coehoorn,
@JoelCoehoorn, interesujące, ponieważ właśnie takie jest repozytorium Maven.
2

Celem jest uzyskanie najnowszego kodu i zbudowanie go bez konieczności instalowania / konfigurowania czegokolwiek (czyli kompilacji „jednym kliknięciem”).

W wielu miejscach byłem, co oznacza sprawdzanie plików binarnych zależności. W innych oznacza to, że skrypty kompilacji pobierają i automatycznie uzyskują zależności.

Zobacz ten post na blogu autorstwa Dereka Greera na ten temat.

Oded
źródło
2

Pracuję nad projektem z dwoma różnymi etapami kompilacji

  • „kompilacja programu głównego” wymaga zaledwie kilku plików binarnych w porównaniu z tysiącami plików tekstowych kodu źródłowego, więc pliki binarne są sprawdzane w repozytorium. To działa dobrze.

  • kompilacja instalatora wymaga wielu komponentów innych firm (niektóre z nich zostały właśnie skopiowane na instalacyjną płytę CD, np. Adobe Reader). Nie umieszczamy ich w repozytorium. Zamiast tego komponenty te znajdują się na dysku sieciowym (nawet ich starsze wersje), a skrypty kompilacji kopiują je we właściwe miejsce. Oczywiście, aby mieć powtarzalne kompilacje, każdy musi uważać, aby nie zmieniać żadnego folderu, w którym przechowywane są komponenty innych firm.

Obie strategie działają dobrze i spełniają wymóg „wymeldowanie z kontroli źródła obejmuje wszystko, czego potrzebujesz do skompilowania kodu”.

Doktor Brown
źródło
1

Musisz zachować wszystko, co będzie potrzebne do odbudowania określonych wersji produktu w pewnym momencie w przyszłości.

Jednak nie musisz mieć wszystkiego pod kontrolą źródła.

Jedna firma utrzymała zamrożony stelaż serwera (ponieważ system operacyjny działał tylko na tym konkretnym sprzęcie, a łańcuch narzędzi działał tylko na tym systemie operacyjnym, a źródło było zależne od tego łańcucha narzędzi). Nie można tego sprawdzić w Kontroli źródła.

Jeśli musisz podzielić wymagania dotyczące kompilacji, masz problem księgowy zsynchronizowania dwóch systemów kontroli wersji. np. skrzynka sprzętowa w tej szafie, maszyna wirtualna lub pliki binarne w tym zachowanym woluminie kopii zapasowej, przejdź do tej wersji kodu źródłowego SVN itp. Jest to bardziej bałagan, że używa jednego systemu kontroli źródła, ale można go rozwiązać.

hotpaw2
źródło
0

Moim zdaniem zamawianie plików binarnych do SCM jest bardzo chaosowe. Prowadziłem bardzo złożony projekt, który ma wiele zależności od bibliotek stron trzecich. Zasady, które przyjęliśmy:

  1. Cały kod źródłowy jest zarządzany za pomocą SCM
  2. Wszystkimi zależnościami zarządza Ivy, który ma doskonałą integrację z zaćmieniami.

To działa całkiem dobrze. Mamy plik konfiguracyjny dotyczący wersji każdej biblioteki zewnętrznej, z którą można skompilować kod źródłowy. Ten plik konfiguracyjny jest sprawdzany w SCM, więc ewoluuje wraz z ewolucją kodu źródłowego. Stosując to podejście, możemy dokładnie odtworzyć kompilację bez zbędnego korzystania z wersji bibliotek zewnętrznych.

James Gan
źródło
0

Osobiście, filozoficznie, jestem skłonny pozwolić, aby kontrola źródła sprawdzała wskaźniki do dużych plików binarnych (małe zasoby binarne są w porządku), a nie zawartość pliku. Ten wskaźnik zawierałby skrót zawartości pliku binarnego.

Sam plik binarny nie byłby zarządzany przez kontrolę źródła. Byłby przechowywany w jakiejś bibliotece, w której można go pobrać za pomocą wskaźnika, a konkretnie skrótu.

Git LFS i git annex to robią, ale starają się także w pewnym stopniu zarządzać plikami binarnymi, nie chcę, żeby to robili. Chcę, aby Git przechowywał tylko sumy kontrolne i powiedział mi, czy moje pliki binarne uległy zmianie, czy nie - ale nie chcę, aby próbowało nimi zarządzać i je przechowywać. Chcę to zrobić sam.

Myślę, że git może obsługiwać małe i średnie pliki binarne, ale nie jestem pewien, czy jest to właściwe narzędzie do zarządzania dużymi plikami binarnymi.

Rolf
źródło