Jestem kolejnym użytkownikiem Subversion walczącym o ponowne nauczenie się w Tao rozproszonej kontroli wersji.
Korzystając z Subversion, byłem wielkim fanem niewielkich projektów i wraz z większością moich byłych pracodawców ustrukturyzowaliśmy nasze oddziały repozytoriów; tagi i bagażnik w następujący sposób:
branches-+
+-personal-+
| +-alice-+
| | +-shinyNewFeature
| | +-AUTOMATED-+
| | +-shinyNewFeature
| +-bob-+
| +-AUTOMATED-+
| +-bespokeCustomerProject
+-project-+
+-shinyNewFeature
+-fixStinkyBug
tags-+
+-m20110401_releaseCandidate_0_1
+-m20110505_release_0_1
+-m20110602_milestone
trunk
W obrębie samego drzewa źródłowego użylibyśmy (coś podobnego) następującej struktury:
(src)-+
+-developmentAutomation-+
| +-testAutomation
| +-deploymentAutomation
| +-docGeneration
| +-staticAnalysis
| +-systemTest
| +-performanceMeasurement
| +-configurationManagement
| +-utilities
+-libraries-+
| +-log-+
| | +-build
| | +-doc
| | +-test
| +-statistics-+
| | +-build
| | +-doc
| | +-test
| +-charting-+
| | +-build
| | +-doc
| | +-test
| +-distributedComputing-+
| | +-build
| | +-doc
| | +-test
| +-widgets-+
| +-build
| +-doc
| +-test
+-productLines-+
| +-flagshipProduct-+
| | +-coolFeature
| | +-anotherCoolFeature
| | +-build
| | +-doc
| | +-test
| +-coolNewProduct
+-project-+
+-bigImportantCustomer-+
| +-bespokeProjectOne
| +-bespokeProjectTwo
+-anotherImportantCustomer-+
+-anotherBespokeProject
Ideą było (i nadal jest) wykorzystanie struktury repozytorium, aby pomóc w strukturze komunikacji między zespołem inżynierów; część firmy zorientowana na klienta oraz inni interesariusze i eksperci w tej dziedzinie.
To znaczy: Dokumenty źródłowe znajdujące się w jednym z katalogów „projektu” są wykorzystywane (i zarabiają pieniądze) tylko raz. Dokumenty znajdujące się w jednym z katalogów „productLines” zarabiają tyle razy, ile razy produkt z danej linii zostaje sprzedany. Dokumenty znajdujące się w jednym z katalogów „bibliotek” zarabiają tyle razy, ile sprzedaje którykolwiek z ich produktów.
Wyjaśnia pojęcie amortyzacji kosztów i pomaga zbudować obsługę ponownego wykorzystania dokumentów źródłowych w całej firmie.
Oznacza to również, że istnieje wspólna struktura, nad którą mogą działać nasze narzędzia do automatyzacji kompilacji. (Nasze skrypty kompilacji chodzą po drzewie źródłowym w poszukiwaniu folderów „kompilacji”, w których znajdują pliki konfiguracyjne określające sposób budowania każdego komponentu; podobny proces ma miejsce w przypadku generowania i testowania dokumentacji).
Co znamienne, produkty, nad którymi pracuję, zwykle trwają DŁUGO, aby przeprowadzić testy pomiaru wydajności i charakterystyki; od 20 do 200 godzin; generowanie gdzieś między kilkoma GB a kilkoma TB przetworzonych wyników testów / danych pośrednich (które muszą być przechowywane i powiązane z określoną konfiguracją systemu, aby można było zmierzyć poprawę wydajności w czasie). Ten problem sprawia, że zarządzanie konfiguracją jest ważnym czynnikiem, a także nakłada pewne wymagania dotyczące centralizacji, ponieważ zazwyczaj zasoby obliczeniowe potrzebne do uruchomienia pomiarów wydajności i testów charakteryzujących są ograniczone; (mały klaster złożony z 64-128 rdzeni).
Jako ostatnia uwaga; system ciągłej integracji wie, że musi uruchomić kompilację; analiza statyczna; test dymu i test jednostkowy uruchamiane przy każdej modyfikacji pnia, za każdym razem, gdy modyfikowana jest dowolna gałąź „tag”, oraz za każdym razem, gdy modyfikowana jest dowolna gałąź „AUTOMATED”. W ten sposób indywidualni programiści mogą korzystać z systemu CI ze swoimi osobistymi oddziałami, co jest ważną funkcją, IMHO.
Oto moje pytanie: Jak mogę powtórzyć wszystkie powyższe (i ulepszyć je, jeśli to możliwe), z Mercurial.
--edytować:
Mój obecny sposób myślenia polega na użyciu centralnego repozytorium Subversion, aby zdefiniować ogólną strukturę, ale pozwolić na użycie hg jako klienta, aby programiści mogli mieć repozytoria dostępne lokalnie.
źródło
Odpowiedzi:
Odpowiedź Spoike jest doskonała, ale myślę, że warto dodać kilka rzeczy, które są zbyt duże, by można je było komentować.
Organizacja branżowa
Dzięki Mercurial możesz szczęśliwie zignorować cały swój pierwszy schemat organizacyjny. Jak mówi Spoke, każde repozytorium ma swój własny zestaw tagów, oddziałów (nazwanych i anonimowych) i można je organizować zgodnie z potrzebami biznesowymi.
Jeśli
bespokeProjectTwo
potrzebujesz specjalnej wersjicharting
biblioteki, możesz ją rozgałęzićcharting
, dodać nowe udogodnienia i użyć jejbespokeProjectTwo
. Nowe obiekty (i ich błędy) nie byłyby wykorzystywane w innych projektach, które odwoływałyby się do standardowejcharting
biblioteki. Jeśli wcharting
bibliotece głównej naprawiono błędy, można scalić te zmiany w gałęzi. Jeśli inne projekty również potrzebują tych ułatwień, możesz albo skłonić te projekty do korzystania ze specjalnej gałęzi, albo połączyć gałąź z linią główną i zamknąć gałąź.Ponadto nic nie stoi na przeszkodzie, abyś posiadał politykę strukturyzowania nazw oddziałów w celu zapewnienia określonych udogodnień, takich jak oddziały AUTOMATION.
Organizacja katalogów
Nie ma powodu, dla którego nie można zachować katalogu źródłowego dokładnie tak, jak w przypadku Mercurial. Jedyna różnica polega na tym, że podczas gdy w Subversion masz jedno monolityczne
(src)
repozytorium, w Mercurial lepiej jest podzielić na repozytoria, które są logicznie pogrupowane. Z Twojej struktury drzewa źródłowego prawdopodobnie wyodrębniłbym każde z poniższych jako osobne repozytoria:Umożliwia to dowolnemu produktowi lub projektowi na zamówienie korzystanie z dowolnej kombinacji bibliotek w dowolnej wersji. Przejrzyj repozytoria rtęciowe, aby w łatwy sposób zarządzać bibliotekami używanymi w dowolnej wersji produktu lub projektu.
Przepływ pracy
Alternatywą dla sugerowanego przepływu pracy Spoike (deweloper pobiera z błogosławionego repozytorium, działa lokalnie, wydaje żądanie ściągnięcia, a na koniec integrator pobiera te zmiany i łączy je) byłoby użycie systemu ciągłej integracji jako pośrednika.
Tak jak poprzednio, deweloper pobiera z pobłogosławionego repozytorium i działa lokalnie, ale po zakończeniu ponownie wyciąga z błogosławionego repozytorium i łączy się przed przejściem do nieskażonego repozytorium. Wszelkie zmiany niezwróconego repozytorium są następnie sprawdzane (ręcznie lub automatycznie) i przenoszone do błogosławionego repozytorium tylko wtedy, gdy zostaną zatwierdzone.
Oznacza to, że integrator zaakceptował lub odrzucił zmianę, a nie scalił. Z mojego doświadczenia wynika, że prawie zawsze lepiej jest dla programisty, który napisał kod do wykonania scalenia, niż dla kogoś innego.
Jak zasugerowano w książce rtęci, haczyki można wykorzystać do automatyzacji tej procedury:
Inne sprawy
Problem dużych zestawów danych testowych można również rozwiązać, umieszczając te dane testowe w pod-repozytorium rtęciowym . Zapobiegnie to rozdęciu repozytorium kodu danymi testowymi, jednocześnie utrzymując dane testowe pod kontrolą wersji.
źródło
productLines
lubbigImportantCustomer
jako super-repo.Dobra, próbuję odpowiedzieć na to po prostu.
Co musisz wiedzieć
Pierwszą rzeczą, którą musisz wiedzieć: Mercurial jest rozproszoną kontrolą wersji i ma pewne właściwości, o których powinieneś wiedzieć poniżej.
Typowym modelem, z którym ludzie pracują w DVCS (który jest wykorzystywany w github i bitbucket) jest robienie tego częściowo scentralizowanego.
Każdy użytkownik ma repozytorium publiczne (w niektórych udziałach lub na bezpiecznym serwerze) i repozytorium prywatne (na własnych stacjach roboczych). Oba są klonami „błogosławionego” repozytorium integratora. Ilekroć czują, że są gotowi opublikować swój kod, mogą przekazać zmiany z repozytorium publicznego. Integrator może następnie wybrać, którzy użytkownicy mają pobrać kod do „błogosławionego” repozytorium.
Jeśli integrator nie może łatwo scalić kodu użytkownika, zmiany są odrzucane i to właśnie ten użytkownik musi zaktualizować swoje repozytorium i samodzielnie naprawić scalenie. Zwykle nie jest to trudne, jeśli często się scalasz (ponieważ jest mniej kodu, który trzeba scalić) i zwykle ten użytkownik powinien wiedzieć, co poszło nie tak podczas scalania.
Konfiguracja repozytoriów na projekt
Tak więc zwykle konfiguruje się, że dla każdego projektu są następujące:
Publiczne repozytorium tylko do odczytu, za które odpowiedzialny jest integrator. Jest „błogosławiony”.
Tj. Wszyscy użytkownicy mogą pobierać / pobierać treści, ale nie mają dostępu do ich przesyłania.
Każdy użytkownik może mieć własny publiczny klon repozytorium.
Najłatwiejsza konfiguracja w postaci dysku współużytkowanego (choć możesz rozważyć hosting taki jak bitbucket). Integrator odbiera żądania ściągania od użytkowników i próbuje pobrać nowy kod z tych repozytoriów. Gdy scalenia są wykonywane bez problemów, jest ono umieszczane w repozytorium tylko do odczytu. Jeśli nie, użytkownicy proszeni są o naprawienie konfliktów scalania, które powstają poprzez lokalną aktualizację i scalenie.
Każdy użytkownik może mieć własne prywatne klony repozytorium.
Dobrą praktyką jest wyciąganie ze swojego publicznego klonu, ale nie ma znaczenia, czy wyciągają ze swojego publicznego czy integratora. Wszystkie zatwierdzenia są jednoznacznie identyfikowalne, więc scalanie zatwierdzeń, które zapomniałeś pobrać w publicznym, jest względnie łatwe do naprawienia (poprzez przeniesienie zmian z prywatnego na publiczne, automatycznie pobiera również zmiany integratora).
Organizacja kodu źródłowego
Tak jak w przypadku aranżacji samego źródła projektu jest coś, co trzeba przemyśleć. Jeśli artefakt wymaga kontroli źródła, włącz kontrolę źródła. Osobiście nie podoba mi się pomysł sprawdzania artefaktów tworzonych przez kompilację lub środowisko wykonawcze (ze względu na wysokie ryzyko konfliktów scalania na tego rodzaju artefaktach), takich jak pliki binarne lub pliki dziennika.
Możesz także sprawdzić konfigurację, o ile ułatwiają one programistom rozpoczęcie pracy i nie psują konfiguracji wydań lub środowiska na żywo / produkcyjnego (takich jak ustawienia aplikacji / serwera WWW). Prowadzi to do wniosku, że jeśli konfiguracja, którą masz poważnie utrudnia programistom rozpoczęcie pracy w ciągu pięciu minut po sprawdzeniu kodu, należy go zrefaktoryzować. Kolejnym wymaganiem jest to, że programiści powinni mieć trudności z zepsuciem wydania lub środowiska na żywo / produkcyjnego.
Wspominasz, że masz dane testowe, które muszą być powiązane z jakąś wersją kodu. Teraz jest to nieco trudniejsze, ponieważ systemy DVCS, takie jak Mercurial i Git, mają tendencję do spowalniania podczas sprawdzania danych, które są OGROMNE. Z mojego doświadczenia wynika, że staje się on nie do zniesienia po 5 GB plików binarnych (twój przebieg może się różnić, więc powinieneś sprawdzić, jak to działa). Zalecałbym jednak umieszczenie wygenerowanych danych we własnym repozytorium i sprawdzenie, czy system testowy odpowiednio je oznaczył (i / lub utworzyć pliki tekstowe dla tych samych celów metadanych).
Mam nadzieję, że to wszystko ma sens. Proszę o komentarz poniżej, jeśli pominąłem jakiś szczegół lub jeśli coś wymaga dalszego wyjaśnienia, a ja spróbuję edytować.
źródło