Strategia użycia kontroli wersji w systemie modułowym

15

Załóżmy (dla uproszczenia), że mamy aplikację zawierającą klienta i serwer; czy jest lepszy pomysł na użycie jednego repozytorium dla obu lub pary oddzielnych repozytoriów?

Mieszanie ich prawdopodobnie ułatwi śledzenie skorelowanych zmian i utrzymanie skorelowanych gałęzi (tj. Ewolucji protokołu), ale z drugiej strony sprawi, że indywidualny rozwój będzie bardziej zagracony ...

mbq
źródło
A co jest złego w korzystaniu z oddzielnych gałęzi? Deweloper musi mieć tylko gałąź, nad którą aktualnie pracuje, lokalnie, więc nawet nie zobaczy rzeczy, które znajdują się tylko w innych gałęziach. Ale jeśli z jakiegoś powodu musi dostać się do oddziału, może.
Spencer Rathbun,
@SpencerRathbun - Korzystanie z oddzielnych gałęzi takich jak ta jest receptą na katastrofę . Byłoby naprawdę trudno wymianę plików między serwerem a klientem, zwłaszcza interfejsów oraz dokumentacji systemowej itd z DVCS byłoby wymagać, aby sklonować wszystkich zobowiązuje klienta i serwera, nawet jeśli tylko tego chce, i nie daje wszelkie wskazówki, które wersje klienta i serwera będą ze sobą współpracować. W porównaniu do monolitycznego (pojedynczego) repozytorium lub modułowego (wielokrotnego) rozbicia repozytorium, faktycznie dostajesz najgorsze z obu światów .
Mark Booth,
@MarkBooth Humm, myślałem o sekcjach projektu w każdej gałęzi, ponieważ wskazał, że będą udostępniać kod. Wystarczy oznaczyć każdą sekcję jako odpowiednie gałęzie i jesteś dobry. Czy Twój DVCS nie pozwala plikowi / zatwierdzeniu mieć wielu znaczników?
Spencer Rathbun,

Odpowiedzi:

12

Jeśli używasz git lub merkurialu , możesz przyjrzeć się podmodułom lub podrepozytoriom .

Klient, serwer i ich pliki interfejsów byłyby w swoich własnych repozytoriach, ale byłyby powiązane na poziomie super repozytorium . Umożliwiłoby to dokonanie jednej transakcji na najwyższym poziomie i / gitlub hgsprawdzenie odpowiedniego zatwierdzenia każdego z podmodułów / podrepozytorów.

Przypisując się do super-repozytorium tylko wtedy, gdy zarówno klient, jak i serwer były do ​​siebie odpowiednie, super-repozytorium dawałoby tylko możliwość sprawdzenia działającego systemu - więc nigdy nie próbowałbyś uruchomić nowego klienta na starym serwer lub odwrotnie.

Podmoduły / podrepozytoria dają wszystkie zalety korzystania z oddzielnych repozytoriów, wraz z zaletami pojedynczego repozytorium monolitycznego, kosztem nieco większej złożoności.

Ta odpowiedź nie jest przeznaczony do adwokata gitlub hgnad innymi SCM, to po prostu zdarza się, że wiem tylko te SCM wystarczająco dobrze, by wiedzieć, że ta opcja istnieje. Nie rozumiem svnna przykład, jak działają zewnętrzne.

Mark Booth
źródło
1
TO TO interesująca funkcja. Byłbym zainteresowany, aby zobaczyć odpowiednie studia przypadków dotyczące jego zastosowania, nawet o tym wcześniej nie słyszałem!
Ed James
Podobną rzeczą w subversion są definicje zewnętrzne: svnbook.red-bean.com/en/1.0/ch07s03.html . Działa to jednak w nieco inny sposób.
liori,
1
@MarkBooth: tak, możesz. Na tej stronie możesz zobaczyć parametry, które wyglądają jak -r12345 - te określają, którą wersję chcesz uzyskać. A ponieważ właściwość svn: externals jest wersjonowana jak każdy plik tekstowy, możesz mieć różne wartości dla -r dla każdej wersji. Przeglądasz również starodawną dokumentację 1.0. Definicje zewnętrzne zmieniono w wersji 1.5, a aktualna wersja to 1.7. Zobacz: svnbook.red-bean.com/en/1.7/svn.advanced.externals.html
liori
6

Oddzielny!

W rzeczywistości prawdopodobnie miałbym trzy repozytoria, jedno dla klienta i odpowiednie biblioteki tylko dla klienta, jedno dla serwera (i odpowiednich bibliotek) i jedno dla bibliotek współdzielonych (zawierających interfejsy API, które ujawniają funkcjonalność między tymi dwoma oraz wszelkie inne wspólne kody). Myślę, że to naprawdę klucz, wspólny kod powinien przejść do osobnego repozytorium. W ten sposób możesz mieć pewność, że interoperacyjność między twoim klientem a serwerem jest zawsze w tej samej wersji ORAZ jest odizolowana od projektu każdego z jej konsumentów.

Oczywiście nie zawsze jest to możliwe, w zależności od konkretnej struktury komunikacyjnej, której używasz, ale prawdopodobnie zostanie udostępniony kod, który dyktuje format obiektów przesyłania danych lub kroki uzgadniania w niestandardowym protokole (lub w innym przykładzie) .

Zakładając, że masz dość przyzwoitą konfigurację ciągłej integracji i kontroli jakości (dość duże założenie, z mojego doświadczenia, ale i tak zamierzam to zrobić. Jeśli nie masz działu kontroli jakości, powinieneś przynajmniej zdobyć trochę CI), nie powinieneś nie musisz używać wzorca pojedynczej operacji repo jako obrony przed możliwymi błędnymi dopasowaniami kodu, albo twój serwer CI oznaczy interoperacyjność bibliotek, albo twój zespół kontroli jakości wyłapie błędy w czasie wykonywania (lub, co lepiej, testy jednostkowe).

Zalety podzielonych repozytoriów polegają na możliwości osobnej wersji oddzielnych części systemu. Chcesz wziąć kopię serwera z zeszłego tygodnia i uruchomić go z klientem w tym tygodniu, aby spróbować zablokować źródło problemu z wydajnością? Bez obaw.

Ed James
źródło
1

W Mercurial można użyć tego schematu, używając ->do oznaczenia relacji subrepo:

product -> client -|-> (many components)
                   |->  shared component A

        -> server -|-> (many components)
                   |->  shared component A

Produkt ma klienta subrepos, serwer. Każdy z nich ma swoje komponenty jako podrepo, prawdopodobnie co najmniej jedno podporządkowanie wspólne dla obu.

Tagowanie powinno prawdopodobnie odbywać się na pierwszych dwóch poziomach, a nie poniżej.

Zatwierdzenia są wykonywane na poziomie komponentu, superrepos skutecznie śledzą nazwane gałęzie i wersje produktu. Nazwane gałęzie / zakładki są zwykle lepsze niż klonowane gałęzie pod względem użyteczności (tj. Możliwości szkolenia) i zgodności z podrepami.

hg zmierza do założenia, że ​​superrepos produktem, a zatwierdzenia są wykonywane na najwyższym poziomie, ale nie działa to szczególnie dobrze, gdy wiele produktów używa tych samych komponentów. :-)

Nie sądzę, że ten schemat zmieni się znacznie, jeśli przejdzie do git, ale jeszcze go nie wypróbowałem w git.

Paul Nathan
źródło
1

Jest to problem zarządzania konfiguracją, a nie problem kontroli wersji. Jak zawsze programista za pomocą śrubokręta wbija gwóźdź. Sprawdź, jak będziesz zarządzać swoimi konfiguracjami, kontrola wersji zadba o siebie.

mattnz
źródło
1

The Najprostszym sposobem jest użycie jednego repozytorium, więc jeśli lubisz złożoności dla dobra złożoności, a następnie, że powinien być domyślnym wyborem w przypadku braku istotnych argumentów w inny sposób.

Czy rozwój klienta i serwera będzie realizowany przez różne organizacje? Czy będzie wiele implementacji klienta (lub serwera)? Czy klient jest open source i implementacja serwera jest tajna? Jeśli odpowiedź na wszystkie te pytania brzmi „nie”, wówczas coś bardziej złożonego niż pojedyncze repozytorium może przynieść jedynie niedogodności bez korzyści.

Jeśli zdecydujesz się na utrzymanie oddzielnych baz kodów, będziesz potrzebować jasnych zasad dotyczących tego, jak to jest administrowane, aby uniknąć piekła niezgodności i zależności. Po przeanalizowaniu kilku pierwszych czkawek możesz odkryć, że najbezpieczniejszym rozwiązaniem jest zawsze sprawdzenie razem obu repozytoriów, zbudowanie ich razem i rozmieszczenie razem ... co oczywiście nie pozwala na ich rozdzielenie!

Modułowość to dobra właściwość, ale dzielenie repozytoriów nie jest narzędziem do osiągnięcia tego. Jak sugeruje poprzedni akapit, możesz mieć wysoce sprzężone komponenty, które są podzielone na wiele baz kodu (niepożądane), a także możesz mieć wysoce modułowe komponenty w tej samej bazie kodu (pożądane).

Niejednokrotnie zalecałem (z powodzeniem) mojemu zespołowi połączenie istniejących repozytoriów git, ponieważ uprościło to programowanie i wdrażanie.

Todd Owen
źródło
0

Zapomnij na chwilę o repozytorium. Jak zorganizowałbyś dwa projekty na swoim komputerze, gdybyś nikomu nie udostępniał? Jak zrobiłaby to reszta zespołu? Czy mógłbyś ...

  • Umieścić wszystkie pliki źródłowe dla klienta i serwera w tym samym katalogu?

  • Czy utworzyć główny katalog projektu, który zawiera podkatalogi dla klienta i serwera?

  • Czy dwa projekty są całkowicie oddzielne?

Po osiągnięciu konsensusu w tej sprawie, jako zespół, możesz sprawdzić projekty w swoim repozytorium kodów. Wszystkie narzędzia kontroli wersji, które mogę wymyślić, chętnie odtwarzają dowolną strukturę katalogów, którą lubisz - nie dbają o to, który plik należy do którego projektu. Różnica między posiadaniem jednego repozytorium lub dwóch (lub sześciu) zwykle nie jest tak duża, pomijając niewielkie różnice administracyjne.

Na przykład w przypadku Subversion największa różnica między oddzielnymi repozytoriami dla klienta i serwera a pojedynczym repozytorium połączonym polega na sposobie zmiany numerów wersji. W przypadku pojedynczego repozytorium numer wersji będzie się zwiększał za każdym razem, gdy przekażesz kod klientowi lub serwerowi. Przy osobnych repozytoriach zatwierdzenie do projektu serwera nie zmieni numeru wersji głównej dla klienta.

Caleb
źródło