Używam Perforce od wielu lat. Chciałbym przełączyć się na używanie git do mojego osobistego kodu, ale wszystkie samouczki git, które widziałem, zakładają, że masz pełną kontrolę źródła n00b (co czyni je niesamowicie żmudnymi) lub że jesteś do tego przyzwyczajony svn (którym nie jestem).
Znam p4 i rozumiem też ideę rozproszonego systemu kontroli źródła (więc nie potrzebuję promocji, dzięki). To, co chciałbym, to tablica translacji z polecenia p4 na równoważne polecenia git, a także polecenia „nie można żyć bez”, które nie mają odpowiednika p4.
Ponieważ podejrzewam, że każdy użytkownik p4 używa innego podzbioru p4, oto kilka rzeczy, które regularnie robię w p4, które chciałbym robić w git, a które nie są od razu widoczne w dokumentach, które przeglądałem :
- utwórz wiele oczekujących list zmian w jednym kliencie. (
p4 change
) - edytuj oczekującą listę zmian. (też
p4 change
) - zobacz listę wszystkich moich oczekujących list zmian (
p4 changes -s pending
) - lista wszystkich zmienionych plików w moim kliencie (
p4 opened
) lub w oczekującej liście zmian (p4 describe
) - zobacz różnicę oczekującej listy zmian (używam do tego skryptu opakowującego, który używa
p4 diff
ip4 describe
) - dla danego pliku, zobacz, które przesłane listy zmian wpłynęły na które linie (
p4 annotate
) - dla danego pliku zobacz listę opisów list zmian, które wpłynęły na plik (
p4 log
) - prześlij oczekującą listę zmian (
p4 submit -c
) - przerwać oczekującą listę zmian (
p4 revert
)
Wiele z nich obraca się wokół „list zmian”. „lista zmian” to terminologia p4. Jaki jest odpowiednik terminu git?
Wygląda na to, że użytkownicy git mogą używać gałęzi zamiast tego, co p4 nazywa listami zmian. Nieco zagmatwane, ponieważ p4 ma również coś, co nazywa się gałęzią, chociaż wydają się być tylko niejasno powiązanymi pojęciami. (Chociaż zawsze myślałem, że koncepcja gałęzi p4 jest dość dziwna, po raz kolejny różni się od klasycznej koncepcji gałęzi RCS).
W każdym razie ... Nie jestem pewien, jak osiągnąć to, co normalnie robię na listach zmian p4 z gałęziami git. W p4 mogę zrobić coś takiego:
$ p4 edit a.txt
$ p4 change a.txt
Change 12345 created.
W tym momencie mam listę zmian, która zawiera plik.txt. Mogę edytować opis i kontynuować pracę bez przesyłania listy zmian. Ponadto, jeśli okaże się, że muszę wprowadzić pewne zmiany w innych plikach, na przykład naprawić błąd w innej warstwie kodu, mogę to zrobić w tym samym kliencie:
$ p4 edit z.txt
$ p4 change z.txt
Change 12346 created.
Teraz mam dwie oddzielne listy zmian w tym samym kliencie. Mogę pracować nad nimi jednocześnie i nie muszę nic robić, aby „przełączać się” między nimi. Kiedy przychodzi czas na zatwierdzenie, mogę przesłać je osobno:
$ p4 submit -c 12346 # this will submit the changes to z.txt
$ p4 submit -c 12345 # this will submit the changes to a.txt
Nie mogę wymyślić, jak to powtórzyć w git. Z moich eksperymentów wynika, że nie git add
jest to związane z bieżącą gałęzią. O ile wiem, kiedy git commit
zamierzam zatwierdzić wszystkie pliki, które wykonałem, git add
bez względu na gałąź, w której byłem w tym czasie:
$ git init
Initialized empty Git repository in /home/laurence/git-playground/.git/
$ ls
a.txt w.txt z.txt
$ git add -A .
$ git commit
Initial commit.
3 files changed, 3 insertions(+), 0 deletions(-)
create mode 100644 a.txt
create mode 100644 w.txt
create mode 100644 z.txt
$ vi a.txt z.txt
2 files to edit
$ git status
# On branch master
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: a.txt
# modified: z.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
$ git branch aardvark
$ git checkout aardvark
M a.txt
M z.txt
Switched to branch 'aardvark'
$ git add a.txt
$ git checkout master
M a.txt
M z.txt
Switched to branch 'master'
$ git branch zebra
$ git checkout zebra
M a.txt
M z.txt
Switched to branch 'zebra'
$ git add z.txt
$ git status
# On branch zebra
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: a.txt
# modified: z.txt
#
$ git checkout aardvark
M a.txt
M z.txt
Switched to branch 'aardvark'
$ git status
# On branch aardvark
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: a.txt
# modified: z.txt
W tym przykładzie gałęzie mrównika i zebry wydają się zawierać dokładnie ten sam zestaw zmian, a na podstawie ich wyniku git status
wydaje się, że wykonanie zatwierdzenia w jednej z nich będzie miało ten sam efekt. czy robię coś źle?