Na szczęście dla tych z nas, którzy wciąż są zmuszeni używać CVS, git dostarcza całkiem dobrych narzędzi do robienia dokładnie tego, co chcesz. Moje sugestie (i co robimy tutaj w $ work):
Tworzenie początkowego klonu
Służy git cvsimport
do klonowania historii wersji CVS do repozytorium git. Używam następującego wywołania:
% git cvsimport -d $CVSROOT -C dir_to_create -r cvs -k \
-A /path/to/authors/file cvs_module_to_checkout
Ta -A
opcja jest opcjonalna, ale pomaga sprawić, by historia wersji zaimportowana z CVS wyglądała bardziej jak git (zobacz man git-cvsimport
więcej informacji o tym, jak to jest skonfigurowane).
W zależności od rozmiaru i historii repozytorium CVS, ten pierwszy import zajmie BARDZO dużo czasu. Możesz dodać -v do powyższego polecenia, jeśli chcesz mieć pewność, że coś się dzieje.
Po zakończeniu tego procesu będziesz mieć master
gałąź, która powinna odzwierciedlać HEAD CVS (z wyjątkiem, że git cvsimport
domyślnie ignoruje ostatnie 10 minut zatwierdzeń, aby uniknąć przechwycenia zatwierdzenia, który jest w połowie ukończony). Następnie możesz użyć git log
i znajomych do zbadania całej historii repozytorium, tak jakby używało git od początku.
Poprawki konfiguracji
Istnieje kilka poprawek konfiguracyjnych, które ułatwią w przyszłości przyrostowy import z CVS (a także eksport). Nie są one udokumentowane na git cvsimport
stronie podręcznika, więc przypuszczam, że mogą ulec zmianie bez powiadomienia, ale FWIW:
% git config cvsimport.module cvs_module_to_checkout
% git config cvsimport.r cvs
% git config cvsimport.d $CVSROOT
Wszystkie te opcje można określić w wierszu poleceń, dzięki czemu można bezpiecznie pominąć ten krok.
Import przyrostowy
Kolejne git cvsimport
powinno być znacznie szybsze niż pierwsze wywołanie. Robi to jednak cvs rlog
w każdym katalogu (nawet w tych, w których są tylko pliki Attic
), więc może to potrwać kilka minut. Jeśli powyżej określiłeś sugerowane konfiguracje, wszystko, co musisz zrobić, to wykonać:
% git cvsimport
Jeśli nie skonfigurowałeś swoich konfiguracji, aby określić wartości domyślne, musisz określić je w wierszu poleceń:
% git cvsimport -r cvs -d $CVSROOT cvs_module_to_checkout
Tak czy inaczej, dwie rzeczy, o których należy pamiętać:
- Upewnij się, że jesteś w katalogu głównym repozytorium git. Jeśli jesteś gdziekolwiek indziej, spróbuje zrobić coś nowego
cvsimport
, co znowu zajmie wieczność.
- Upewnij się, że jesteś w swoim
master
oddziale, aby zmiany mogły zostać scalone (lub przeniesione) do gałęzi lokalnych / tematycznych.
Dokonywanie lokalnych zmian
W praktyce radzę zawsze wprowadzać zmiany w gałęziach i scalać je tylko master
wtedy, gdy jesteś gotowy do wyeksportowania tych zmian z powrotem do repozytorium CVS. Możesz użyć dowolnego przepływu pracy na swoich gałęziach (scalanie, ponowne bazowanie, zgniatanie itp.), Ale oczywiście obowiązują standardowe zasady ponownego bazowania: nie zmieniaj bazy, jeśli ktoś inny opierał swoje zmiany na twojej gałęzi.
Eksportowanie zmian do CVS
git cvsexportcommit
Komenda pozwala na eksport pojedynczy zobowiązać się do serwera CVS. Możesz określić pojedynczy identyfikator zatwierdzenia (lub cokolwiek, co opisuje określone zatwierdzenie zgodnie z definicją w man git-rev-parse
). Następnie generowany jest plik różnicowy, stosowany do pobrania CVS, a następnie (opcjonalnie) zatwierdzany do CVS przy użyciu rzeczywistego cvs
klienta. Mógłbyś wyeksportować każde mikro zatwierdzenie do gałęzi tematycznych, ale generalnie lubię tworzyć zatwierdzenie scalające na aktualnym master
i eksportować to pojedyncze zatwierdzenie scalające do CVS. Kiedy eksportujesz zatwierdzenie przez scalanie, musisz powiedzieć gitowi, którego rodzica zatwierdzenia ma użyć do wygenerowania różnicy. Nie zadziała to również, jeśli scalanie było szybkim przewijaniem do przodu (zobacz sekcję „JAK DZIAŁA ŁĄCZENIE”, man git-merge
aby zapoznać się z opisem szybkiego łączenia do przodu), więc musisz użyć--no-ff
podczas łączenia. Oto przykład:
# on master
% git merge --no-ff --log -m "Optional commit message here" topic/branch/name
% git cvsexportcommit -w /path/to/cvs/checkout -u -p -c ORIG_HEAD HEAD
Możesz zobaczyć, co oznacza każda z tych opcji na stronie podręcznika man dla git-cvsexportcommit . Masz możliwość ustawienia -w
opcji w konfiguracji git:
% git config cvsexportcommit.cvsdir /path/to/cvs/checkout
Jeśli łatka zawiedzie z jakiegokolwiek powodu, z mojego doświadczenia wynika, że prawdopodobnie (niestety) lepiej będzie skopiować zmienione pliki ręcznie i zatwierdzić za pomocą klienta cvs. Nie powinno to jednak mieć miejsca, jeśli upewnisz się, że jesteś master
na bieżąco z CVS przed scaleniem gałęzi tematu.
Jeśli zatwierdzenie nie powiedzie się z jakiegokolwiek powodu (problemy z siecią / uprawnieniami itp.), Możesz przenieść polecenie wydrukowane na twój terminal na końcu wyjścia błędu i wykonać je w katalogu roboczym CVS. Zwykle wygląda to mniej więcej tak:
% cvs commit -F .msg file1 file2 file3 etc
Następnym razem, gdy wykonasz git cvsimport
(czekając co najmniej 10 minut), powinieneś zobaczyć łatkę wyeksportowanego zatwierdzenia ponownie zaimportowaną do lokalnego repozytorium. Będą miały różne identyfikatory zatwierdzeń, ponieważ zatwierdzenie CVS będzie miało inny znacznik czasu i prawdopodobnie inną nazwę osoby zatwierdzającej (w zależności od tego, czy ustawiłeś plik autorów w swoim inicjału cvsimport
powyżej).
Klonowanie klonu CVS
Jeśli masz więcej niż jedną osobę, która musi to zrobić cvsimport
, bardziej wydajne byłoby posiadanie jednego repozytorium git, które wykonuje cvsimport, a wszystkie inne repozytoria zostały utworzone jako klon. Działa to doskonale, a sklonowane repozytorium może wykonywać polecenia cvsexportcommits, tak jak opisano powyżej. Jest jednak jedno zastrzeżenie. Ze względu na sposób, w jaki zatwierdzenia CVS powracają z różnymi identyfikatorami zatwierdzeń (jak opisano powyżej), nie chcesz, aby Twoja sklonowana gałąź śledziła centralne repozytorium git. Domyślnie w ten sposób git clone
konfiguruje się repozytorium, ale można to łatwo naprawić:
% git clone [CENTRAL_REPO_HERE]
% cd [NEW_GIT_REPO_DIR_HERE]
% git config --unset branch.master.remote
% git config --unset branch.master.merge
Po usunięciu tych konfiguracji będziesz musiał wyraźnie powiedzieć, skąd i co należy wyciągnąć, jeśli chcesz pobrać nowe zatwierdzenia z centralnego repozytorium:
% git pull origin master
Ogólnie rzecz biorąc, stwierdziłem, że ten przepływ pracy jest całkiem łatwy w zarządzaniu, a „następna najlepsza rzecz” podczas całkowitej migracji do git nie jest praktyczna.