Jak wyeksportować historię wersji z mercurial lub git do cvs?

Będę pracował z innymi ludźmi nad kodem z projektu wykorzystującego cvs. Chcemy użyć rozproszonego vcs do naszej pracy i kiedy skończymy, a może raz na jakiś czas chcemy zatwierdzić nasz kod i całą naszą historię zmian do cvs. Nie mamy dostępu do repozytorium CV projektu, więc nie możemy się często angażować. Jakiego narzędzia możemy użyć do eksportowania naszej historii wersji do cvs? Obecnie myśleliśmy o użyciu git lub mercurial, ale moglibyśmy użyć innego rozproszonego VC jeśli to może ułatwić eksport.

Author: skiphoppy, 2009-02-25

3 answers

Na szczęście dla tych z nas, którzy wciąż są zmuszeni do używania CVS, git dostarcza całkiem dobre narzędzia do robienia dokładnie tego, co chcesz zrobić. Moje sugestie (i co tu robimy w $work):

Tworzenie klonu początkowego

Użyj git cvsimport, aby sklonować historię wersji CVS do repozytorium git. Używam następującej inwokacji:

% git cvsimport -d $CVSROOT -C dir_to_create -r cvs -k \
  -A /path/to/authors/file cvs_module_to_checkout

Opcja -A jest opcjonalna, ale pomaga sprawić, że historia wersji importowanych z CVS będzie wyglądać bardziej jak git (zobacz man git-cvsimport aby uzyskać więcej informacji na temat tego, 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ć A-v do powyższego polecenia, jeśli chcesz mieć pewność, że coś się dzieje.

Po zakończeniu tego procesu, będziesz miał master gałąź, która powinna odzwierciedlać głowę CVS (z tym wyjątkiem, że git cvsimport domyślnie ignoruje ostatnie 10 minut commitów, aby uniknąć przechwycenia commita to jest w połowie skończone). Następnie możesz użyć git log i znajomych, aby sprawdzić całą historię repozytorium tak, jakby używało ono Gita od samego początku.

Zmiany Konfiguracji

Istnieje kilka poprawek konfiguracji, które w przyszłości ułatwią Przyrostowy import z CVS (jak również eksport). Nie są one udokumentowane na stronie man git cvsimport, więc przypuszczam, że mogą się zmienić 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ć na linii poleceń, dzięki czemu można bezpiecznie pominąć ten krok.

Przyrostowy Import

Kolejne git cvsimport powinny być znacznie szybsze niż pierwsze wywołanie. Robi jednak cvs rlog na każdym katalogu (nawet tych, które mają tylko pliki w Attic), więc może to potrwać kilka minut. Jeśli podałeś powyżej sugerowane konfiguracje, wszystko, co musisz zrobić, to wykonać:

% git cvsimport

Jeśli nie skonfigurowałeś configs tak, aby określał wartości domyślne, musisz je określić na wiersz poleceń:

% git cvsimport -r cvs -d $CVSROOT cvs_module_to_checkout

Tak czy inaczej, dwie rzeczy do zapamiętania:

  1. upewnij się, że jesteś w głównym katalogu swojego repozytorium git. Jeśli jesteś gdziekolwiek indziej, spróbuje zrobić świeżą cvsimport, która ponownie zajmie wieczność.
  2. upewnij się, że jesteś w swojej gałęzi master, aby zmiany mogły zostać scalone (lub rebasowane) w gałęziach lokalnych/tematycznych.

Dokonywanie Lokalnych Zmian

W praktyce zalecam zawsze wprowadzanie zmian na gałęziach i tylko scalanie do master, gdy będziesz gotowy do wyeksportowania tych zmian z powrotem do repozytorium CVS. Możesz użyć dowolnego przepływu pracy na swoich gałęziach (scalanie, rebasing, zgniatanie itp.), ale oczywiście obowiązują standardowe reguły rebasingu: nie rebasuj, jeśli ktoś inny oparł swoje zmiany na Twojej gałęzi.

Eksportowanie zmian do CVS

Polecenie git cvsexportcommit pozwala wyeksportować pojedynczy commit do serwera CVS. Możesz określić pojedynczy identyfikator zatwierdzenia (lub cokolwiek, co opisuje określony commit zdefiniowany w man git-rev-parse). Następnie generowany jest diff, zastosowany Do kasy CVS, a następnie (opcjonalnie) oddany do CVS przy użyciu rzeczywistego klienta cvs. Możesz wyeksportować każdy mikro commit do swoich gałęzi tematycznych, ale ogólnie lubię tworzyć commit scalający na bieżąco master i eksportować ten pojedynczy commit scalający do CVS. Kiedy eksportujesz commit scalający, musisz powiedzieć gitowi, którego rodzica commita użyć do wygenerowania różnic. Również, to nie zadziała, jeśli połączenie było przewijanie do przodu (patrz sekcja "Jak działa scalanie"man git-merge dla opisu szybkiego scalania), więc musisz użyć opcji --no-ff podczas wykonywania scalania. 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 każda z tych opcji oznacza na stronie podręcznika git-cvsexportcommit . Masz możliwość ustawienia opcji -w w swoim Git config:

% git config cvsexportcommit.cvsdir /path/to/cvs/checkout

Jeśli patch nie powiedzie się z jakiegokolwiek powodu, moje doświadczenie jest takie ,że będziesz (niestety) prawdopodobnie lepiej będzie skopiować zmienione pliki ręcznie i zatwierdzić za pomocą klienta cvs. Nie powinno się to jednak zdarzyć, jeśli upewnisz się, że master jest aktualne z CVS przed połączeniem gałęzi tematu.

Jeśli zatwierdzenie nie powiedzie się z jakiegokolwiek powodu (problemy z siecią/uprawnieniami itp.), możesz pobrać polecenie wydrukowane na terminalu na końcu wyjścia błędu i wykonać je w katalogu roboczym CVS. Zazwyczaj wygląda to mniej więcej tak:

% cvs commit -F .msg file1 file2 file3 etc

The następnym razem, gdy wykonasz git cvsimport (czekając co najmniej 10 minut) powinieneś zobaczyć łatkę wyeksportowanego commita ponownie zaimportowanego do lokalnego repozytorium. Będą one miały różne identyfikatory commitów, ponieważ commit CVS będzie miał inny znacznik czasu i prawdopodobnie inną nazwę commita(w zależności od tego, czy skonfigurowałeś plik authors w początkowej cvsimport powyżej).

Klonowanie klonu CVS

Jeśli masz więcej niż jedną osobę potrzebującą zrobić cvsimport, byłoby bardziej efektywne mieć pojedyncze repozytorium git, które wykonuje cvsimport i posiada wszystkie inne repozytoria utworzone jako klon. Działa to doskonale, a sklonowane repozytorium może wykonywać polecenia cvsexport tak, jak opisano powyżej. Jest jednak jedno zastrzeżenie. Ze względu na sposób, w jaki commity CVS wracają z różnymi identyfikatorami (jak opisano powyżej), nie chcesz, aby sklonowana gałąź śledziła centralne repozytorium git. Domyślnie, w ten sposób git clone konfiguruje swoje repozytorium, ale jest to łatwe

% 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 configów, będziesz musiał wyraźnie powiedzieć, gdzie i CO pobrać, gdy chcesz pobrać nowe commity z centralnego repozytorium:

% git pull origin master

Ogólnie rzecz biorąc, uważam, że ten przepływ pracy jest dość łatwy do opanowania, a "następna najlepsza rzecz" podczas migracji do Gita nie jest praktyczna.

 239
Author: Brian Phillips,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-29 23:25:27

Nie należy ufać cvsimport ślepo i sprawdzać, czy zaimportowane drzewo pasuje do tego, co jest w repo CVs. Zrobiłem to udostępniając nowy projekt za pomocą wtyczki eclipse CVS i stwierdziłem, że były niespójności..

Dwa commity, które zostały wykonane w mniej niż minutę z tym samym komunikatem commit (w celu przywrócenia nieprawidłowo usuniętego pliku) zostały zgrupowane w jeden duży commit, co spowodowało brak pliku z drzewa..

Udało mi się rozwiązać ten problem modyfikując parametr "fuzz" na mniej niż minutę.

Przykład:

% git cvsimport -d $CVSROOT -C dir_to_create -r cvs -k \
  -A /path/to/authors/file cvs_module_to_checkout -z 15

Bottom line: Sprawdź swoje drzewo po zaimportowaniu

 21
Author: shil88,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-28 15:12:42

Oprócz Briana Phillipsa odpowiedź: istnieje również git-cvsserver który działa jak CVS server, ale w rzeczywistości ma dostęp do repozytorium git... ale ma pewne ograniczenia.

 3
Author: Jakub Narębski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-25 20:43:34