Git dla użytkowników Perforce


86

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 :

  1. utwórz wiele oczekujących list zmian w jednym kliencie. ( p4 change)
  2. edytuj oczekującą listę zmian. (też p4 change)
  3. zobacz listę wszystkich moich oczekujących list zmian ( p4 changes -s pending)
  4. lista wszystkich zmienionych plików w moim kliencie ( p4 opened) lub w oczekującej liście zmian ( p4 describe)
  5. zobacz różnicę oczekującej listy zmian (używam do tego skryptu opakowującego, który używa p4 diffi p4 describe)
  6. dla danego pliku, zobacz, które przesłane listy zmian wpłynęły na które linie ( p4 annotate)
  7. dla danego pliku zobacz listę opisów list zmian, które wpłynęły na plik ( p4 log)
  8. prześlij oczekującą listę zmian ( p4 submit -c)
  9. 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 addjest to związane z bieżącą gałęzią. O ile wiem, kiedy git commitzamierzam zatwierdzić wszystkie pliki, które wykonałem, git addbez 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 statuswydaje się, że wykonanie zatwierdzenia w jednej z nich będzie miało ten sam efekt. czy robię coś źle?


2
Możesz po prostu użyć siły do ​​swojego osobistego kodu, zakładając, że wystarczy pięciu darmowych klientów.
Logan Capaldo

3
To właśnie robiłem, ale chciałbym przełączyć się na coś, co jest open source i jest również używane w projektach open source. Rozważałem zarówno gita, jak i Mercurial. Skłaniam się ku gitowi, ponieważ wydaje się, że ma większy rozpęd.
Laurence Gonsalves,

1
Lepiej byłoby nauczyć się Gita od podstaw. Przepływ pracy zalecany przez Git bardzo różni się od przepływu pracy zalecanego przez Perforce. Przetłumaczone przepływy pracy będą niewygodne, a próba zrównania funkcji może utrudnić zrozumienie. Na szczęście społeczność Git oferuje bogactwo dokumentacji dla początkujących, np. git-scm.com/book
Colonel Panic

1
@ColonelPanic Rozumiem, co masz na myśli, ale problem z taką dokumentacją polega na tym, że marnuje czas na wyjaśnianie podstawowych rzeczy, które każdy użytkownik Perforce już wiedział. Czytanie takiej dokumentacji jest tak samo denerwujące, jak próba przeczytania samouczka na temat innego języka programowania, w którym rozdział wyjaśnia, czym są zmienne.
Laurence Gonsalves

@ColonelPanic To powiedziawszy, przeczytałem inną dokumentację gita, w tym Git From the Bottom Up i Git for Computer Scientists, które były całkiem przydatne. Używam Gita od kilku lat (zwróć uwagę, kiedy pierwotnie zadano to pytanie) i czuję, że główne problemy z nauką gita to nie brak dokumentacji, ale słaba nomenklatura, niespójność wewnętrzna, mocno przeciążone polecenia i pewne niedokończone części, które nie są gotowe do rzeczywistego użytku. Chciałabym, żeby ktoś poszedł i posprzątał to wszystko, ale to by zirytowało tych, którzy się do tego przyzwyczaili.
Laurence Gonsalves

Odpowiedzi:


72

Nie używałem zbyt często siły, więc może to nie być dokładnie tłumaczenie 1: 1. Z drugiej strony, rozproszone systemy kontroli źródła, takie jak git i mercurial, i tak mają inny przepływ pracy, więc tak naprawdę nie ma (i nie powinno być) tłumaczenia 1: 1. Tak czy inaczej, oto idzie:

  • Utwórz wiele oczekujących list zmian -> Zamiast tego użyj gałęzi. W git branch jest lekki i szybki, jego utworzenie zajmuje mniej niż sekundę, a łączenie zajmuje zwykle mniej niż dwie sekundy. Nie bój się często rozgałęziania i rebase.

    git branch new-branch-name
    git checkout new-branch-name
    

    Lub zrób to wszystko w jednej linii:

    git checkout -b new-branch-name
    
  • Zobacz listę wszystkich oczekujących list zmian -> Ponieważ odpowiednikiem wielu oczekujących list zmian jest wiele gałęzi, wystarczy wyświetlić gałęzie:

    git branch
    

    Jeśli chcesz zobaczyć również zdalne oddziały:

    git branch -a
    

    Za dobrą praktykę uważa się natychmiastowe usuwanie gałęzi po pomyślnym scaleniu, aby nie trzeba było śledzić, która gałąź oczekuje na scalenie, a która już została scalona.

  • Lista wszystkich zmienionych plików -> Dla pojedynczej oczekującej "listy zmian" w określonej gałęzi git ma pojęcie indeksu lub pamięci podręcznej. Aby zatwierdzić zmianę, musisz najpierw dodać pliki do tego indeksu. Pozwala to ręcznie wybrać, która grupa plików reprezentuje pojedynczą zmianę, lub zignorować nieistotne pliki. Aby zobaczyć stan, które pliki są dodawane lub nie do tego indeksu, po prostu wykonaj:

    git status
    
  • Zobacz różnicę oczekującej listy zmian -> Są to dwie części. Najpierw zobacz różnicę między katalogiem roboczym a indeksem:

    git diff
    

    Ale jeśli chcesz poznać różnicę między tym, co teraz wpisujesz, a ostatnim zatwierdzeniem, to naprawdę prosisz o różnicę między katalogiem roboczym + indeksem a nagłówkiem:

    git diff HEAD
    
  • Dla danego pliku zobacz, które przesłane listy zmian wpłynęły na które wiersze -> To proste:

    git blame filename
    

    lub nawet lepiej, jeśli jesteś w środowisku okienkowym:

    git gui blame filename
    

    Git gui zajmuje więcej czasu na parsowanie pliku (został napisany w tcl zamiast w C), ale ma wiele fajnych funkcji, w tym możliwość „podróży w czasie” z powrotem do przeszłości poprzez kliknięcie na identyfikator zatwierdzenia. Chciałbym tylko, żeby zaimplementowali funkcję „podróży w czasie” do przyszłości, abym mógł dowiedzieć się, jak dany błąd zostanie ostatecznie rozwiązany ;-)

  • Dla danego pliku zobacz listę opisów list zmian, które wpłynęły na plik -> również łatwe:

    git log filename
    

    Ale git log jest znacznie potężniejszym narzędziem niż tylko to. W rzeczywistości większość moich osobistych skryptów jest pobierana z dziennika gita, aby odczytać repozytorium. Przeczytaj stronę podręcznika.

  • Prześlij oczekującą listę zmian -> Również łatwe:

    git commit
    

Zobacz moją odpowiedź na poprzednie pytanie, aby zobaczyć mój typowy przepływ pracy w gicie: Nauka Git. Muszę wiedzieć, czy jestem na dobrej drodze

Jeśli zastosujesz się do opisanego przeze mnie przepływu pracy, zauważysz, że narzędzia takie jak gitk są znacznie bardziej wartościowe, ponieważ pozwalają wyraźnie zobaczyć grupy zmian.


Dodatkowa odpowiedź:

Git jest bardzo elastyczny i istnieje kilka sposobów na zrobienie tego, co opisujesz. Należy pamiętać, aby zawsze rozpoczynać nową gałąź dla każdej funkcji, nad którą pracujesz. Oznacza to, że gałąź główna nie jest dotykana, więc zawsze możesz do niej wrócić, aby naprawić błędy. Pracę w git prawie zawsze należy zacząć od:

git checkout -b new-feature-a

Teraz możesz edytować plik a.txt. Aby pracować jednocześnie nad inną funkcją, wykonaj:

git checkout master
git checkout -b new-feature-z

Teraz możesz edytować plik z.txt. Aby wrócić do a.txt:

git checkout new-feature-a

Ale poczekaj, są zmiany w nowej funkcji-z, a git nie pozwoli ci zmienić gałęzi. W tym momencie masz dwie możliwości. Pierwsza jest najprostsza, zatwierdź wszystkie zmiany w bieżącej gałęzi:

git add .
git commit
git checkout new-feature-a

To właśnie polecam. Ale jeśli naprawdę nie jesteś gotowy, aby zatwierdzić kod, możesz go tymczasowo ukryć:

git stash

Teraz możesz przełączyć się na gałąź new-feature-a. Aby wrócić do kodu, nad którym pracowałeś, po prostu włóż skrytkę:

git checkout new-feature-z
git stash pop

Kiedy wszystko jest gotowe, z powrotem scal wszystkie zmiany do mastera:

git merge --no-ff new-feature-a
git merge --no-ff new-feature-z

Ponieważ scalanie jest tak szybkie i łatwe (łatwe, ponieważ konflikty są tak rzadkie, a rozwiązywanie konfliktów, kiedy się zdarzają, niezbyt trudne), używamy gałęzi w git do wszystkiego.

Oto kolejny przykład typowego użycia gałęzi w git, którego nie widzisz w innych narzędziach kontroli źródła (z wyjątkiem być może mercurial):

Chcesz ciągle zmieniać pliki konfiguracyjne, aby odzwierciedlić środowisko programistyczne? Następnie użyj gałęzi:

git checkout -b dev-config

Teraz edytuj pliki konfiguracyjne w ulubionym edytorze, a następnie zatwierdź zmiany:

git add .
git commit

Teraz każda nowa gałąź może zaczynać się od gałęzi dev-config zamiast master:

git checkout dev-config
git checkout -b new-feature-branch

Gdy skończysz, usuń zmiany w dev-config z nowej gałęzi funkcji za pomocą interaktywnej rebase:

git rebase -i master

Usuń niepotrzebne zmiany, a następnie zapisz. Teraz masz czystą gałąź bez niestandardowych edycji konfiguracji. Czas na powrót do mastera:

git checkout master
git merge --no-ff new-feature-branch
# because master have changed, it's a good idea to rebase dev-config:
git checkout dev-config
git rebase master

Należy zauważyć, że usuwanie zmian za pomocą git rebase -inawet działa, gdy wszystkie zmiany zachodzą w tym samym pliku. Git pamięta zmiany, a nie zawartość plików *.

* uwaga: właściwie, technicznie nie do końca prawda, ale jako użytkownik tak się czuje


Więcej dodatkowej odpowiedzi:

Z twoich komentarzy wynika, że ​​chcesz mieć dwie gałęzie, aby istniały jednocześnie, abyś mógł przetestować, jak działa połączony kod. Cóż, to dobry sposób, aby zilustrować siłę i elastyczność gałęzi.

Najpierw kilka słów na temat wpływu taniego rozgałęziania i modyfikowalnej historii na przepływ pracy. Kiedy używałem CVS i SVN, zawsze byłem trochę niechętny do zatwierdzania. Dzieje się tak, ponieważ zatwierdzenie niestabilnego kodu nieuchronnie zniszczyłoby działający kod innych osób. Ale z git straciłem ten strach. To dlatego, że w git inni ludzie nie otrzymają moich zmian, dopóki nie połączę ich z master. Więc teraz zaczynam pisać kod co 5 linii, które piszę. Nie potrzebujesz doskonałej przewidywania, aby się zaangażować. Musisz tylko zmienić swój sposób myślenia: commit-to-branch == add-to-changeset, merge-to-master == commit-changeset.

Wróćmy więc do przykładów. Oto jak bym to zrobił. Powiedzmy, że masz gałąź new-feature-zi chcesz ją przetestować new-feature-a. Po prostu utworzyłbym nową gałąź, aby ją przetestować:

# assume we are currently in branch new-feature-z
# branch off this branch for testing
git checkout -b feature-z-and-feature-a
# now temporarily merge new-feature-a
git merge --no-ff new-feature-a

Teraz możesz przetestować. Jeśli chcesz coś zmodyfikować, aby funkcja feature-z działała z feature-a, zrób to. Jeśli tak, możesz z powrotem scalić zmiany w odpowiedniej gałęzi. Służy git rebase -ido usuwania nieistotnych zmian z scalania.

Alternatywnie możesz również użyć git rebase, aby tymczasowo zmienić podstawę new-feature-z, aby wskazywała na new-feature-a:

# assume we are currently in branch new-feature-z
git rebase new-feature-a

Teraz historia rozgałęzień jest modyfikowana tak, że new-feature-z będzie bazował na new-feature-a zamiast master. Teraz możesz przetestować. Wszelkie zmiany dokonane w tej gałęzi będą należeć do gałęzi new-feature-z. Jeśli chcesz zmodyfikować nową funkcję, po prostu przełącz się z powrotem do niej i rebase, aby uzyskać nowe zmiany:

git checkout new-feature-a
# edit code, add, commit etc..
git checkout new-feature-z
git rebase new-feature-a
# now new-feature-z will contain new changes from new-feature-a

Kiedy skończysz, po prostu wróć do mastera, aby usunąć zmiany z nowej funkcji:

# assume we are currently in branch new-feature-z
git rebase master

Nie bój się otwierać nowego oddziału. Nie bój się założyć jednorazowej gałęzi. Nie bój się wyrzucić gałęzi. A ponieważ merge == submit and commit == add-to-changeset, nie bój się często zatwierdzać. Pamiętaj, commit to najlepsze narzędzie programisty do cofania zmian.

Aha, i jeszcze jedno, w git usunięte gałęzie nadal istnieją w twoim repozytorium. Więc jeśli przypadkowo usunąłeś coś, co później okaże się przydatne, zawsze możesz to odzyskać, przeszukując historię. Nie bój się więc wyrzucać gałęzi.


1
Czy każda gałąź ma swój własny „indeks”, czy też istnieje jeden indeks współdzielony między oddziałami? Mój eksperyment wydaje się sugerować to drugie, ale mówisz, że „git z określonej gałęzi ma pojęcie indeksu lub pamięci podręcznej”, co sugeruje to pierwsze.
Laurence Gonsalves,

4
To inne narzędzie. Potrzebujesz innego przepływu pracy, a przy tym innego sposobu myślenia i nawyku. Żaden git nie działa tak, jak opisujesz. To gałęzie i nic więcej. Ale istnieją bardzo potężne narzędzia do manipulacji gałęziami. Sugeruję, abyś uważał się za nowicjusza, który nie wie nic o kontroli źródła i zapoznał się z podstawowymi samouczkami. Zastanów się nad swoim obecnym „złym nawykiem”, przeciwko któremu musisz zostać reedukowany w git-land. Przepraszam ...
slebetman

1
Więc co robisz w git, gdy masz dwie rzeczy, nad którymi chcesz pracować jednocześnie (i w tym samym miejscu, aby móc testować niezatwierdzone zmiany względem siebie), ale chcesz zatwierdzić je osobno? Ponadto, jak edytować komunikat dotyczący zatwierdzenia przed wykonaniem zatwierdzenia? Mogę zaakceptować, że przepływ pracy jest inny, ale nie powiedziałeś, jaki jest przepływ pracy odpowiadający gitowi. Stwierdzenie, że są to złe nawyki, brzmi bardzo podobnie do próby przedstawienia błędu jako funkcji.
Laurence Gonsalves,

2
Przeczytaj moją zaktualizowaną odpowiedź. Nadal myślisz w kategoriach niezatwierdzonych zmian, podczas gdy powinieneś myśleć o niepołączonych gałęziach.
slebetman

2
Bardzo obszerna odpowiedź. W którym momencie powinno to zostać uproszczone?
Tim Clemons

1

Nie mam wystarczającego doświadczenia z p4, aby stworzyć rzeczywisty arkusz do ściągnięcia, ale są przynajmniej pewne podobieństwa, na których można się oprzeć. "Zbiór zmian" p4 to "zatwierdzenie" gita.

Zmiany w lokalnej przestrzeni roboczej są dodawane do „indeksu” za pomocą git add, a indeks zostaje później zatwierdzony git commit. Więc indeks jest twoją oczekującą listą zmian, dla wszystkich zamiarów i celów.

Patrzysz na zmiany za pomocą git diffi git status, gdzie git diffzwykle pokazuje zmiany między obszarem roboczym a indeksem, ale git diff --cachedpokazuje zmiany między indeksem a repozytorium (= twoja oczekująca lista zmian).

Aby uzyskać bardziej szczegółowe informacje, polecam http://progit.org/book/ . Ponieważ ogólnie znasz kontrolę wersji, prawdopodobnie możesz ją przejrzeć i wyodrębnić informacje specyficzne dla gita ...


1
Nie zgodziłbym się, że "zestaw zmian p4 jest zatwierdzeniem git"; to najbliższe odpowiedniki, prawda, ale zbiór zmian p4 jest znacznie bliższy zestawowi zatwierdzeń git. Zestaw zmian p4 reprezentuje cechę, podczas gdy gałąź git reprezentuje cechę.
RJFalconer,

@RJFalconer Erm. „Oddział” to też oddział w Perforce, prawda? A „zestaw zmian” to niepodzielny zbiór zmian w jednym lub kilku plikach, bardzo podobny do zatwierdzenia? Jeśli nie, co byś powiedział, jest odpowiednikiem commita na p4?
Jakob Borg

Powiedziałbym, że p4 nie ma odpowiednika, po prostu dlatego, że stopień atomowości nie jest taki sam; w git mogę wprowadzić kilka zmian w danym pliku, a następnie zatwierdzić je różnymi zatwierdzeniami (git add -p), oddzielając w ten sposób refaktoryzację / czyszczenie w historii od funkcji / poprawki błędów. Gdybym miał to zrobić w p4, musiałbym rozwinąć te dwa osobno. Nawet wtedy moje zatwierdzenia mogą nie być ciągłe, ponieważ inni programiści mogą przesyłać między nimi (chyba że mam oddział prywatny, co wiąże się z niepraktycznym powielaniem na dysku).
RJFalconer

Zastrzeżenie: Używam p4 tylko przez kilka miesięcy i jest całkiem możliwe, że jest w nim jakaś funkcja, która to umożliwia, a której po prostu jeszcze nie spotkałem.
RJFalconer

Listy zmian p4 i gałęzie p4 są logicznie takie same, jak zatwierdzenia git i gałęzie git. p4 shelve jest odpowiednikiem git stash. Różnią się implementacją (tj. Rozproszona a klient-serwer) i ta różnica skutkuje odpowiednikiem p4 git checkout obejmującym wiele kroków i znaczny czas. Narzut jest taki, że wiele gałęzi jest zwykle zachowywanych lokalnie na dysku, zamiast robić to, co odpowiada git checkout. Półki p4 są przechowywane na serwerze, a nie w lokalnym repozytorium.
Josh Heitzman

1

Podobnie jak ty cierpię z powodu braku koncepcji „listy zmian”, która nie jest dokładnie tym samym, co git branches.

Napisałbym mały skrypt, który utworzy plik listy zmian z listą plików na tej liście zmian.

Kolejne polecenie, aby przesłać tylko określoną listę zmian, po prostu wywołując git commit -a @ change_list_contents.txt, a następnie „git commit”

Mam nadzieję, że to pomoże, Elias


Tak, właściwie rozważałem zrobienie czegoś takiego, chociaż w czasie, gdy zadawałem to pytanie, byłem nowy w git, więc chciałem poznać „natywne” rozwiązanie. Teraz stwierdzam, że najważniejszą rzeczą, za którą tęsknię, jest możliwość pracy nad komunikatem zatwierdzenia bez faktycznego zatwierdzania. W ten sposób można by to rozwiązać przez posiadanie pliku do przechowywania "komunikatu o oczekującym zatwierdzeniu" i być może trochę magii, która automatycznie czyta go podczas pisania komunikatu o zatwierdzeniu.
Laurence Gonsalves,

@LaurenceGonsalves, przepływ pracy, którego używam, polega na zatwierdzaniu niedoskonałych komunikatów o zatwierdzeniach (lub nawet po prostu „WIP”), gdy jestem skupiony na pracy, a następnie później wprowadzam poprawki podczas mojej rebase. Ponieważ zatwierdzenia są czysto lokalne, nie muszą być ostateczne, dopóki nie udostępnisz swojej gałęzi (przesyłając ją do pilota lub podobnego).
RJFalconer,

1

W git jest lżejsza alternatywa, która może stanowić część twojego przepływu pracy; używając obszaru przemieszczania git.

Często po prostu wprowadzam zmiany, a następnie przesyłam je jako kilka zatwierdzeń (np. Dodam instrukcje debugowania, refaktoryzację, faktycznie naprawiam błąd). Zamiast konfigurować listy zmian, a następnie wprowadzić zmiany, a następnie przesłać, możesz po prostu wprowadzić zmiany, a następnie wybrać sposób ich przesłania (opcjonalnie korzystając z obszaru przejściowego git).

Możesz zatwierdzić określone pliki z wiersza poleceń za pomocą:

git commit a.txt
git commit z.txt

Lub jawnie najpierw przemieszczaj pliki:

git add a.txt
git commit
git add z.txt
git commit

git gui pozwoli ci wybrać linie lub porcje z plików, aby zbudować zatwierdzenie w obszarze przejściowym. Jest to bardzo przydatne, jeśli masz zmiany w jednym pliku, które chcesz umieścić w różnych zatwierdzeniach. Przeszedłem od gita do konieczności i jest to jedna rzecz, za którą naprawdę tęsknię.

W przypadku tego przepływu pracy należy pamiętać o małym zastrzeżeniu. Jeśli dokonasz zmian A i B w pliku, przetestuj plik, a następnie zatwierdź A, a wtedy nie przetestowałeś tego zatwierdzenia (niezależnie od B).


Z pewnością prawdą jest, że git pozwala na wykonywanie nawet drobniejszych zatwierdzeń niż fororce (tj .: wiersze i porcje). Rzeczą, której (wciąż) brakuje mi z powodu perforce, jest możliwość śledzenia opisu zmiany (zwanego również komunikatem zatwierdzenia) tego, nad czym obecnie pracuję. Na przykład, kiedy mam naprawić błąd # 12345, utworzyłem listę zmian, mówiącą, że to robię (ale nie przesyłam, czyli zatwierdzam). Następnie, pracując nad tym, zaktualizowałem opis zmiany, aby wskazać, co zrobiłem. Wreszcie, kiedy skończę, popełniłbym listę zmian.
Laurence Gonsalves

W git wydaje się, że przybliżonym odpowiednikiem jest wysłanie tych małych (często niedziałających) bitów do gałęzi deweloperskiej, a następnie, gdy wszystko jest w porządku, scalenie zmian. Wciąż wydaje mi się to o wiele bardziej nudne i niezgrabne. Poza tym nadal nie przyzwyczaiłem się do idei zatwierdzania kodu, który nawet się nie kompiluje.
Laurence Gonsalves

@LaurenceGonsalves Ciekawy, jeśli w międzyczasie przyzwyczaiłeś się do tego. Przychodzę do Perforce z Git i brakuje mi możliwości angażowania się co 15 minut, a następnie naciskania, gdy będę gotowy.
damian

0

To nie odpowiada konkretnie na twoje pytanie, ale nie wiem, czy wiesz, że wersję forfororce dla 2 użytkowników i 5 obszarów roboczych można pobrać i używać za darmo ze strony internetowej perforce .

W ten sposób, jeśli chcesz, możesz używać siły w domu do swoich osobistych projektów. Jedyną irytacją jest 5 obszarów roboczych, które mogą być nieco ograniczające, ale niewiarygodne jest mieć siłę dostępną do użytku domowego.


2
To właśnie robiłem, ale chciałbym przełączyć się na coś, co jest open source i jest również używane w projektach open source.
Laurence Gonsalves,

0

Po dość intensywnym używaniu zarówno Perforce, jak i git, jest tylko jeden sposób, aby znaleźć się w pobliżu list zmian Perforce z git.

Pierwszą rzeczą do zrozumienia jest to, że poprawne zaimplementowanie tej funkcjonalności w git w taki sposób, że nie jest to kompletna kluga, np. Próba wbicia jej w gałęzie, wymagałoby następującej zmiany: git wymagałby wielu obszarów przejściowych dla jednej gałęzi .

Listy zmian Perforce pozwalają na przepływ pracy, który po prostu nie ma odpowiednika w git. Rozważ następujący przepływ pracy:

Check out a branch
Modify file A and add it to changelist 1
Modify file B and add it to changelist 2

Jeśli spróbujesz to zrobić za pomocą gałęzi w git, skończysz z dwoma gałęziami, z których jedna zawiera zmiany w pliku A, a druga ma zmiany w pliku B, ale nie ma miejsca, w którym możesz zobaczyć zmiany w obu plikach Ai Bw o tym samym czasie.

Najbliższym przybliżeniem widzę jest wykorzystanie git add . -p, a następnie użyj 'a'i 'd'sub-polecenia, aby wybrać lub odrzucić całe pliki. Jednak to nie jest dokładnie to samo, a różnica tutaj wynika z fundamentalnej rozbieżności w ogólnym sposobie działania obu systemów.

Git (i subversion, nie ma to znaczenia w tej dyskusji) pozwalają na zmianę pliku bez uprzedniego powiadamiania nikogo o tym. Po prostu zmieniasz plik, a następnie pozwalasz gitowi to wszystko uporządkować po zatwierdzeniu zmian. Perforce wymaga, abyś aktywnie pobierał plik, zanim zmiany zostaną dopuszczone, iz tego powodu listy zmian muszą istnieć. Zasadniczo Perforce wymaga dodania pliku do indeksu przed jego zmianą. Stąd potrzeba wielu list zmian w Perforce, a także powód, dla którego git nie ma odpowiednika. Po prostu ich nie potrzebuje.


0

Z Git 2.27 (Q2 2020) " git p4" nauczyłem się czterech nowych podpięć, a także " --no-verify" opcji ich ominięcia (i istniejącego " p4-pre-submit" podpięcia).

Zobacz commit 1ec4a0a , commit 38ecf75 , commit cd1e0dc (14 lutego 2020) i commit 4935c45 , commit aa8b766 , commit 9f59ca4 , commit 6b602a2 (11 lutego 2020) autorstwa Ben Keene ( seraphire) .
(Scalone przez Junio ​​C Hamano - gitster- w zatwierdzeniu 5f2ec21 , 22 kwietnia 2020)

git-p4: dodaj p4 prześlij haki

Podpisał: Ben Keene

Polecenie git " commit" obsługuje wiele punktów zaczepienia, które obsługują zmianę zachowania polecenia commit.

git-p4.pyProgram posiada tylko jeden istniejący hak „ p4-pre-submit”.

To polecenie pojawia się na wczesnym etapie procesu.

W przebiegu procesu nie ma żadnych punktów zaczepienia służących do programowej modyfikacji tekstu listy zmian P4.

Dodaje 3 nowe zaczepy do git-p4.pyopcji przesyłania.

Nowe haki to:

  • p4-prepare-changelist- Wykonaj ten punkt zaczepienia po utworzeniu pliku listy zmian.
    Hak zostanie wykonany, nawet jeśli --prepare-p4-onlyopcja jest ustawiona.
    Ten punkt zaczepienia ignoruje --no-verifyopcję, zachowując istniejące zachowanie git commit.

  • p4-changelist- Wykonaj ten punkt zaczepienia po zakończeniu edycji listy zmian przez użytkownika.
    Nie wykonuj tego przechwytywania, jeśli użytkownik wybrał --prepare-p4-onlyopcję.
    Ten hak będzie honorować --no-verify, zgodnie z konwencjami git commit.

  • p4-post-changelist- Wykonaj ten hak po pomyślnym zakończeniu procesu przesyłania P4.
    Ten punkt zaczepienia nie przyjmuje żadnych parametrów i jest wykonywany niezależnie od --no-verifyopcji.

Zwracana wartość nie będzie sprawdzana.

Wezwania do nowych haków: p4-prepare-changelist, p4-changelist, i p4-post-changelistpowinny być nazywane wewnątrz bloku try-finally.


Przed Git 2.28 (Q3 2020) --prepare-p4-onlyopcja „ ” miała się zatrzymać po powtórzeniu jednego zestawu zmian, ale działała dalej (przez pomyłkę?)

Zobacz commit 2dfdd70 (12 maja 2020) autorstwa Ben Keene ( seraphire) .
(Scalone przez Junio ​​C Hamano - gitster- w zatwierdzeniu 7a8fec9 , 02 czerwca 2020)

git-p4.py: napraw --prepare-p4-onlybłąd z wieloma zatwierdzeniami

Podpisał: Ben Keene

Korzystając git p4 submitz tej --prepare-p4-onlyopcji, program powinien przygotować pojedynczą listę zmian p4 i powiadomić użytkownika, że ​​oczekuje więcej zatwierdzeń, a następnie zatrzymać przetwarzanie.

W p4-changelistfunkcji przechwytywania wprowadzono błąd, który powoduje, że program nadal próbuje przetwarzać wszystkie oczekujące listy zmian w tym samym czasie.

Funkcja applyCommitzwraca, Truegdy zatwierdzenie zakończyło się pomyślnie i program powinien kontynuować.
Jednak po ustawieniu opcjonalnej flagi --prepare-p4-onlyprogram powinien zatrzymać się po pierwszej aplikacji.

Zmień logikę w metodzie uruchamiania, aby P4Submit sprawdzał flagę --prepare-p4-onlypo pomyślnym zakończeniu applyCommitmetody.

Jeśli więcej niż 1 zatwierdzenie oczekuje na przesłanie do P4, metoda prawidłowo przygotuje listę zmian P4, jednak nadal zakończy działanie aplikacji z kodem wyjścia 1.

Aktualna dokumentacja nie definiuje co kod wyjścia powinna być w tym stanie.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.