Perforce dla użytkowników Git? [Zamknięte]


173

Istnieje wiele dokumentacji „Git for Perforce users”, ale na pozór niewiele jest czegoś przeciwnego.

Wcześniej korzystałem tylko z Gita, a niedawno zacząłem pracę, w której muszę często używać Perforce i przez większość czasu czuję się bardzo zdezorientowany. Koncepcje, do których przywykłem z Git, wydają się w ogóle nie mapować do Perforce.

Czy ktoś jest zainteresowany zebraniem kilku wskazówek dotyczących używania Perforce dla kogoś, kto jest przyzwyczajony do Git?

Odpowiedzi:


334

To coś, nad czym pracowałem przez ostatnie kilka tygodni. Wciąż ewoluuje, ale może być pomocny. Proszę zauważyć, że jestem pracownikiem Perforce.

Wprowadzenie do Perforce dla użytkowników Git

Powiedzieć, że przejście z Git na Perforce lub z Perforce na Git jest nietrywialne, to wielkie niedomówienie. Ponieważ są dwoma narzędziami, które rzekomo robią to samo, ich podejście nie może być bardziej różne. Ten krótki opis ma na celu pomóc nowym użytkownikom Perforce pochodzącym z Git zrozumieć nowy świat, w którym się znajdują.

Jeden krótki objazd, zanim wskoczymy; jeśli wolisz Gita, możesz całkiem dobrze używać Gita z Perforce. Udostępniamy narzędzie o nazwie Git Fusion, które generuje repozytoria Git, które są zsynchronizowane z serwerem Perforce. Osoby korzystające z Git i Perforce mogą żyć w harmonii, pracując nad tym samym kodem, w większości niezmienione przez wybór kontroli wersji przez współpracowników. Git Fusions 13.3 jest dostępny w witrynie internetowej Perforce . Musi być zainstalowany przez administratora Perforce, ale jeśli go zainstalujesz, przekonasz się, że jego funkcja krojenia repozytorium może być bardzo przydatna jako użytkownik Git.

Jeśli nie możesz przekonać administratora do zainstalowania Git Fusion, sam Git jest wyposażony w powiązanie Perforce o nazwie Git-P4, które umożliwia używanie Git do zmiany i przesyłania plików w obszarze roboczym Perforce. Więcej informacji na ten temat można znaleźć pod adresem : https://git.wiki.kernel.org/index.php/GitP4

Ciągle tutaj? Dobrze, spójrzmy na Perforce.

Niektóre różnice terminologiczne do uporządkowania

Zanim przejdziemy do szczegółów, musimy pokrótce omówić kilka różnic terminologicznych między Git i Perforce.

Pierwsza to kasy . W Gicie w ten sposób dostajesz kopię kodu z danej gałęzi do swojego obszaru roboczego. W Perforce nazywamy to synchronizacją z wiersza poleceń lub z naszego GUI P4V „Pobierz najnowszą wersję”. Perforce używa słowa checkout z P4V lub p4 editz wiersza poleceń, aby zaznaczyć, że planujesz zmienić plik w systemie kontroli wersji. W pozostałej części tego dokumentu będę używał płatności w sensie Perforce.

Drugi to zatwierdzanie Git a przesyłanie Perforce . Tam, gdzie zobowiązałbyś się w Git, prześlesz w Perforce. Ponieważ wszystkie operacje są wykonywane na udostępnionej usłudze zarządzania wersjami Perforce, Perforce nie ma odpowiednika dla git push. Podobnie nie mamy pull; polecenie sync z góry dba o pobieranie plików dla nas. W Perforce nie ma koncepcji czystego lokalnego przesyłania, chyba że zdecydujesz się skorzystać z naszego narzędzia P4Sandbox, które zostało krótko opisane poniżej.

Kluczowe pojęcia w Perforce

Gdybym miał uprościć Perforce do dwóch kluczowych koncepcji, skupiłbym się na zajezdni i obszarze roboczym. Skład Perforce to repozytorium plików, które znajdują się na serwerze Perforce. Serwer Perforce może mieć dowolną liczbę magazynów, a każdy magazyn może zawierać dowolną liczbę plików. Często można usłyszeć, że użytkownicy Perforce używają zamiennie magazynu i serwera, ale są one różne. Witryna Perforce może mieć wiele serwerów, ale najczęściej wszystkie pliki znajdują się na jednym serwerze.

Obszar roboczy lub klient Perforce to obiekt w systemie, który mapuje zestaw plików na serwerze Perforce do lokalizacji w systemie plików użytkownika. Każdy użytkownik ma obszar roboczy dla każdego używanego komputera, a często użytkownicy mają więcej niż jeden obszar roboczy dla tego samego komputera. Najważniejszą częścią obszaru roboczego jest mapowanie lub widok obszaru roboczego.

Widok obszaru roboczego określa zestaw plików w składzie, które powinny być odwzorowane na komputer lokalny. Jest to ważne, ponieważ istnieje duża szansa, że ​​nie będziesz potrzebować wszystkich plików dostępnych na serwerze. Widok obszaru roboczego pozwala wybrać tylko zestaw, na którym Ci zależy. Należy zauważyć, że obszar roboczy może mapować zawartość z wielu składów, ale może mapować zawartość tylko z jednego serwera.

Aby porównać Perforce z Git w tym względzie, za pomocą Git wybierasz i wybierasz zestaw repozytoriów Git, który Cię interesuje. Każde repozytorium jest zwykle ściśle określone, aby zawierało tylko powiązane pliki. Zaletą tego jest brak konieczności konfiguracji z Twojej strony; robisz git klon rzeczy, na których Ci zależy i gotowe. Jest to szczególnie przyjemne, jeśli pracujesz tylko z jednym lub dwoma repozytoriami. Dzięki Perforce musisz poświęcić trochę czasu na wybieranie i wybieranie żądanych fragmentów kodu.

Wiele sklepów Perforce używa strumieni, które mogą automatycznie generować widok obszaru roboczego, lub generują widok za pomocą skryptów lub szablonów obszarów roboczych. Równie wielu pozostawia swoim użytkownikom samodzielne generowanie obszarów roboczych. Jedną z zalet możliwości mapowania wielu modułów w jednym obszarze roboczym jest to, że można łatwo modyfikować wiele modułów kodu za jednym zameldowaniem; możesz mieć pewność, że każdy z podobnym widokiem klienta, który zsynchronizuje się z Twoim zameldowaniem, będzie miał cały kod we właściwym stanie. Może to jednak prowadzić do nadmiernie zależnego kodu; wymuszona separacja Git może prowadzić do lepszej modułowości. Na szczęście Perforce może również obsługiwać ścisłą modułowość. Wszystko zależy od tego, jak zdecydujesz się używać tego narzędzia.

Dlaczego przestrzenie robocze?

Myślę, że wychodząc z Gita, łatwo jest poczuć, że cała koncepcja przestrzeni roboczej jest o wiele bardziej kłopotliwa, niż jest warta. W porównaniu z klonowaniem kilku repozytoriów Git jest to niewątpliwie prawda. Tam, gdzie obszary robocze błyszczą, a powodem, dla którego Perforce nadal działa po tych wszystkich latach, jest to, że obszary robocze to fantastyczny sposób na ograniczenie wielomilionowych projektów plików dla programistów, a jednocześnie ułatwianie kompilacji i wydawania w celu zebrania wszystkich źródeł razem jedno wiarygodne źródło. Obszary robocze to jeden z głównych powodów, dla których Perforce może skalować się równie dobrze.

Obszary robocze są również przyjemne, ponieważ układ plików w magazynie i układ na komputerze użytkownika mogą się różnić w razie potrzeby. Wiele firm organizuje swoje magazyny, aby odzwierciedlić organizację swojej firmy, tak aby ludzie mogli łatwo znaleźć zawartość według jednostki biznesowej lub projektu. Jednak ich system kompilacji nie mógł mniej przejmować się tą hierarchią; obszar roboczy umożliwia im zmianę hierarchii składów w dowolny sposób, który ma sens dla ich narzędzi. Widziałem również, jak to jest używane przez firmy, które używają niezwykle nieelastycznych systemów kompilacji, które wymagają kodu w bardzo specyficznych konfiguracjach, które są całkowicie mylące dla ludzi. Obszary robocze umożliwiają tym firmom posiadanie hierarchii źródłowej, po której można poruszać się przez człowieka, podczas gdy ich narzędzia kompilacji uzyskują strukturę, której potrzebują.

Obszary robocze w Perforce są używane nie tylko do mapowania zestawu plików, z którymi użytkownik chce pracować, ale są również używane przez serwer do dokładnego śledzenia wersji każdego pliku, który użytkownik zsynchronizował. Umożliwia to systemowi wysyłanie poprawnego zestawu plików do użytkownika podczas synchronizacji bez konieczności skanowania plików w celu sprawdzenia, które pliki wymagają aktualizacji. Przy dużych ilościach danych może to być znaczna korzyść w zakresie wydajności. Jest to również bardzo popularne w branżach, w których obowiązują bardzo surowe zasady audytowania; Administratorzy Perforce mogą łatwo śledzić i rejestrować, którzy programiści zsynchronizowali które pliki.

Więcej informacji na temat pełnych możliwości obszarów roboczych Perforce można znaleźć w artykule Konfigurowanie P4 .

Jawne wypisanie vs. niejawne wypisanie

Jednym z największych wyzwań dla użytkowników przechodzących z Git do Perforce jest koncepcja jawnego zakupu. Jeśli jesteś przyzwyczajony do przepływu pracy Git / SVN / CVS polegającego na zmianie plików, a następnie nakazaniu systemowi kontroli wersji, aby szukał tego, co zrobiłeś, może to być niezwykle bolesne przejście.

Dobra wiadomość jest taka, że ​​jeśli wybierzesz taką opcję, możesz pracować z przepływem pracy w stylu Git w Perforce. W Perforce możesz ustawić opcję „allwrite” na swoim obszarze roboczym. To powie Perforce, że wszystkie pliki powinny być zapisywane na dysku z ustawionym zapisywalnym bitem. Możesz wtedy zmienić dowolny plik bez konieczności jawnego powiadamiania Perforce. Aby Perforce uznał te zmiany, które wprowadziłeś, możesz uruchomić "status p4". W razie potrzeby otworzy pliki do dodawania, edycji i usuwania. Pracując w ten sposób, będziesz chciał użyć „p4 update” zamiast „p4 sync”, aby pobrać nowe wersje z serwera; „Aktualizacja p4” sprawdza zmiany przed synchronizacją, więc nie blokuje zmian lokalnych, jeśli jeszcze nie uruchomiłeś „statusu p4”.

Dlaczego jawna płatność?

Często otrzymuję pytanie „dlaczego miałbyś kiedykolwiek chcieć skorzystać z jawnej płatności?” Na pierwszy rzut oka rumieniec może wydawać się szaloną decyzją projektową, ale wyraźne sprawdzenie ma kilka potężnych zalet.

Jednym z powodów korzystania z jawnego wyewidencjonowywania jest eliminacja konieczności skanowania plików pod kątem zmian zawartości. Podczas gdy w mniejszych projektach obliczanie skrótów dla każdego pliku w celu znalezienia różnic jest dość tanie, wielu naszych użytkowników ma miliony plików w obszarze roboczym i / lub pliki o rozmiarze 100 megabajtów, jeśli nie większe. Obliczanie wszystkich skrótów w takich przypadkach jest niezwykle czasochłonne. Jawne wyewidencjonowanie pozwala Perforce wiedzieć dokładnie, z którymi plikami musi pracować. To zachowanie jest jednym z powodów, dla których Perforce jest tak popularny w dużych branżach plików, takich jak gry, filmy i sprzęt.

Inną korzyścią jest to, że wyewidencjonowanie płatności zapewnia formę asynchronicznej komunikacji, która pozwala programistom ogólnie wiedzieć, nad czym pracują ich rówieśnicy lub przynajmniej gdzie. Może dać ci znać, że możesz chcieć uniknąć pracy w określonym obszarze, aby uniknąć niepotrzebnego konfliktu, lub może cię ostrzec o tym, że nowy programista w zespole wkroczył w kod, którego być może nie potrzebuje do edycji. Moje osobiste doświadczenie jest takie, że zwykle pracuję w Git lub używam Perforce z Allwrite w projektach, w których jestem jedynym lub sporadycznym współpracownikiem, i jawnie sprawdzam, gdy pracuję ściśle z zespołem. Na szczęście wybór należy do Ciebie.

Jawna płatność również dobrze współgra z koncepcją Perforce dotyczącą oczekujących list zmian. Oczekujące listy zmian to zasobniki, w których możesz umieścić otwarte pliki, aby uporządkować swoją pracę. W Git możesz potencjalnie użyć różnych gałęzi jako zasobników do organizowania pracy. Gałęzie są świetne, ale czasami dobrze jest zorganizować swoją pracę w wiele nazwanych zmian przed wysłaniem ich na serwer. Dzięki modelowi Perforce, który umożliwia potencjalnie mapowanie wielu gałęzi lub wielu projektów w jeden obszar roboczy, oczekujące listy zmian ułatwiają organizowanie oddzielnych zmian.

Jeśli używasz IDE do programowania, takiego jak Visual Studio lub Eclipse, zdecydowanie polecam zainstalowanie wtyczki Perforce dla twojego IDE. Większość wtyczek IDE automatycznie pobiera pliki, gdy zaczniesz je edytować, zwalniając Cię od konieczności samodzielnego pobierania.

Perforce Replacements dla funkcji Git

  • git stash ==> p4 shelve
  • git local branching ==> półki Perforce lub gałęzie zadań
  • git blame==> p4 annotatelub Perforce Timelapse View z GUI

Praca odłączona

Istnieją dwie opcje pracy bez połączenia z usługą wersjonowania Perforce (to nasze fantazyjne określenie dla serwera Perforce).

1) Użyj P4Sandbox, aby mieć pełne lokalne przechowywanie wersji i lokalne rozgałęzienia

2) Edytuj pliki według własnego uznania i użyj opcji „p4 status”, aby poinformować Perforce, co zrobiłeś

Dzięki obu powyższym opcjom możesz zdecydować się na użycie ustawienia „allwrite” w obszarze roboczym, aby nie trzeba było odblokowywać plików. Podczas pracy w tym trybie będziesz chciał użyć polecenia „p4 update” do synchronizacji nowych plików zamiast „p4 sync”. „Aktualizacja p4” sprawdzi pliki pod kątem zmian przed ich zsynchronizowaniem.

Perforce Szybki start

Wszystkie poniższe przykłady zostaną wykonane z wiersza poleceń.

1) Skonfiguruj połączenie z Perforce

export P4USER=matt
export P4CLIENT=demo-workspace
export P4PORT=perforce:1666

Możesz umieścić te ustawienia w pliku konfiguracyjnym powłoki, użyć p4 setdo zapisania ich w systemie Windows i OS X lub użyć pliku konfiguracyjnego Perforce.

1) Utwórz obszar roboczy

p4 workspace

# set your root to where your files should live:
Root: /Users/matt/work

# in the resulting editor change your view to map the depot files you care about
//depot/main/... //demo-workspace/main/...
//depot/dev/...  //demo-workspace/dev/...

2) Pobierz pliki z serwera

cd /Users/matt/work
p4 sync

3) Pobierz plik, nad którym chcesz pracować i zmodyfikuj go

p4 edit main/foo; 
echo cake >> main/foo

4) Prześlij go na serwer

p4 submit -d "A trivial edit"

5) Uruchom, p4 help simpleaby zobaczyć podstawowe polecenia potrzebne do pracy z Perforce.


5
Wspaniały przegląd. Zapiszę ten wpis (lub wynikowy wpis na stronie internetowej), aby przekazać niektórym z naszych nowych pracowników.
Caleb Huitt - cjhuitt

@Matt mówi, że „wychodząc z Gita, łatwo jest odnieść wrażenie, że cała koncepcja przestrzeni roboczej jest o wiele bardziej kłopotliwa niż jest warta”. Możliwe - ale takie mapowanie robię w RCS i CVS od lat. Nie używając modułów CVS, ale tworząc drzewa dowiązań symbolicznych, które wskazują na jedno lub więcej repozytoriów CVS. Rzadkie drzewa, nie zawierające wszystkich katalogów. Z wielu powodów opisujesz, że Perforce to robi. Utrzymywanie tego w CVS może być uciążliwe. (I git, i hg, i bzr ... nie jestem taki pewien bzr.)
Krazy Glew

Dzięki Matt, niezwykle przydatna lektura. Nadal uważam, że system wersjonowania powinien mi powiedzieć, co zmieniłem lokalnie w porównaniu ze zdalnym repozytorium lub między oddziałami, a nie na odwrót :)
jupp0r

1
W rzeczy samej! Na szczęście możesz to zrobić z Perforce; Od lat nie uruchamiałem „p4 edit”. perforce.com/blog/131112/say-goodbye-p4-edit
Matt

8
Dzięki, ale sugestia. Słowo „potężny” jest raczej dziwaczne i skłania mnie do zignorowania tego stwierdzenia jako propagandy. Wolałbym, żebyś wyjaśnił tę funkcję, a potem pozwól mi zdecydować, czy jest potężna, czy nie.
damian

24

Największą różnicą między git i p4, których nie dotyczy żadna z istniejących odpowiedzi, jest to, że używają różnych jednostek abstrakcji.

  • W git abstrakcją jest łatka (inaczej diff, inaczej zestaw zmian). Zatwierdzenie w git jest zasadniczo wynikiem działania diffmiędzy poprzednim a bieżącym stanem zatwierdzonych plików.
  • Z konieczności abstrakcją jest plik . Zatwierdzenie w p4 to pełna zawartość plików w zatwierdzeniu w tym momencie. Jest to zorganizowane w listę zmian, ale same wersje są przechowywane osobno dla każdego pliku, a lista zmian po prostu zbiera razem różne wersje plików.

Wszystko inne wypływa z tej różnicy . Rozgałęzianie i scalanie w git jest bezbolesne, ponieważ z punktu widzenia abstrakcji gita każdy plik można w pełni zrekonstruować, nakładając po kolei zestaw łatek, a zatem aby scalić dwie gałęzie wystarczy nałożyć wszystkie łaty na gałąź źródłową które nie są obecne w gałęzi docelowej do gałęzi docelowej w prawidłowej kolejności (zakładając, że nie ma łat na obu gałęziach, które się nakładają).

Oddziały Perforce są różne. Operacja rozgałęzienia w perforce kopiuje pliki z jednego podfolderu do drugiego, a następnie zaznacza połączenie między plikami za pomocą metadanych na serwerze. Aby scalić plik z jednej gałęzi do drugiej ( integrationw kategoriach konieczności), perforce przeanalizuje całą zawartość pliku na początku gałęzi źródłowej i całą zawartość pliku na początku gałęzi docelowej i w razie potrzeby połącz, używając wspólnego przodka. Nie jest w stanie nakładać łatek jeden po drugim, takich jak git, co oznacza, że ​​ręczne scalanie zdarza się częściej (i jest bardziej bolesne).


10
Nie sądzę, aby ten opis był całkowicie dokładny - git przechowuje pełne migawki wszystkich plików i tworzy nową migawkę, gdy plik jest zmieniany (co czyni go kosztownym w przypadku częstych zmian w dużych plikach binarnych), więc zatwierdzenie zawiera tylko linki (poprzez skróty) do aktualnego stanu wszystkich plików. Dlatego przełączanie gałęzi w git jest zwykle bardzo szybkie - wystarczy skopiować wersje, do których istnieją odwołania, wszystkich plików, których skróty zostały zmienione w obszarze roboczym. Różnice są tworzone w locie tylko wtedy, gdy jest to konieczne do porównania i scalenia / zmiany bazy.
ChrAfonso

3
Niezależnie od dokładnej implementacji pod maską, polecenie merge w git (szczególnie trywialne scalanie lub przewijanie do przodu) wydaje się działać przy użyciu poprawek z punktu widzenia użytkownika końcowego , o co próbuję.
damian

Perforce może łączyć listę zmian (zestaw zmian). Oto pytanie dotyczące przepełnienia stosu, które o tym mówi. stackoverflow.com/questions/6158916/perforce-merge-changelist/…
Br.Bill

5
@ Br. Bill Ponownie, nie chodzi mi o to, czy P4 jest zdolny do robienia rzeczy (bo oczywiście!). Chodzi o abstrakcję , czyli model, który użytkownik musi zinternalizować, aby zrozumieć, jak to działa.
damian

1
Dziękuję Ci za to. Natychmiast wyjaśnia, w jaki sposób możemy pobrać najnowszą wersję określonego pliku, w jaki sposób możemy uzyskać określoną listę zmian. To była dla mnie najbardziej zagmatwana część, ponieważ pochodziłem z gita.
Abdulsattar Mohammed

20

Prawdopodobnie nie ma zbyt wiele takiej dokumentacji, ponieważ Perforce jest dość tradycyjnym systemem kontroli wersji (bliższym CVS, Subversion itp.) I zwykle jest uważany za mniej skomplikowany niż nowoczesne rozproszone systemy kontroli wersji.

Próba przypisania poleceń z jednego do drugiego nie jest właściwym podejściem; koncepcje ze scentralizowanych i rozproszonych systemów kontroli wersji nie są takie same. Zamiast tego opiszę typowy przepływ pracy w Perforce:

  1. Uruchom p4 editna każdym pliku, który chcesz edytować. Musisz powiedzieć Perforce, które pliki edytujesz. Jeśli dodajesz nowe pliki, użyj p4 add. Jeśli usuwasz pliki, użyj p4 delete.
  2. Wprowadź zmiany w kodzie.
  3. Uruchom, p4 changeaby utworzyć zestaw zmian. Tutaj możesz stworzyć opis swojej zmiany i opcjonalnie dodać lub usunąć również pliki ze swojego zestawu zmian. W p4 change CHANGE_NUMBERrazie potrzeby możesz później przeprowadzić edycję opisu.
  4. W razie potrzeby możesz wprowadzić dodatkowe zmiany w kodzie. Jeśli chcesz dodać / edytować / usunąć inne pliki, możesz użyć p4 {add,edit,delete} -c CHANGE_NUMBER FILE.
  5. Uruchom, p4 syncaby pobrać najnowsze zmiany z serwera.
  6. Uruchom, p4 resolveaby rozwiązać wszelkie konflikty związane z synchronizacją.
  7. Kiedy będziesz gotowy do przesłania zmiany, uruchom p4 submit -c CHANGE_NUMBER.

Możesz użyć, p4 revertaby cofnąć zmiany w plikach.

Pamiętaj, że możesz pracować jednocześnie nad wieloma zestawami zmian, o ile żaden z ich plików nie nakłada się. (Plik w twoim kliencie Perforce może być otwarty tylko w jednym zestawie zmian na raz.) Czasami może to być wygodne, jeśli masz małe, niezależne zmiany.

Jeśli okaże się, że musisz edytować pliki, które zostały już otwarte w innym zestawie zmian, możesz utworzyć oddzielnego klienta Perforce lub zachować istniejący zestaw zmian na później za pośrednictwem p4 shelve. (W przeciwieństwie do git stashregałów półkowych nie przywraca plików w lokalnym drzewie, więc należy je przywrócić osobno).


3
Przepraszam, nie rozumiem: czy nowoczesne systemy muszą być bardziej skomplikowane niż tradycyjne? Prostota jest zawsze zasadą w inżynierii oprogramowania. W pewnym sensie myślę, że P4 jest znacznie bardziej nowoczesny zarówno pod względem koncepcji, jak i użyteczności (i łatwości utrzymania) niż Git. Nie nienawidzę Gita, ale widzę, że po 30 latach rozwoju inżynierii oprogramowania ludzie są zmuszeni powrócić do konsoli tekstowej, aby wydawać polecenia VCS - degeneracja w ewolucji człowieka!
Dejavu

5
@Dejavu Nie chodzi tak bardzo o tradycję kontra nowoczesność; chodzi bardziej o scentralizowane i rozproszone (a rozproszone są bardziej nowoczesne). Te rozproszone niekoniecznie są bardziej skomplikowane, ale powiedziałem konkretnie, że „Perforce… jest uważane za mniej skomplikowane…”, co jest stwierdzeniem opinii, a nie faktem, i które nie ma być kocem oświadczenie o wszystkich systemach. Osobiście uważam, że git jest bardziej złożony, ponieważ dodaje więcej pojęć (np. Wypychanie, ciągnięcie, rebasing), a niektóre rzeczy nie są tak proste (np. Skróty zamiast globalnych liczb zmian).
jamesdlin

2
Dzięki za wyjaśnienie, James! Ostatnio czuję się trochę urażony, widząc, że wszyscy współpracownicy muszą zostać przeszkoleni jako git hacker, który powinien znać kilka umiejętności hakerskich, aby rozwiązać niektóre problemy, które wydawały się tak intuicyjne podczas korzystania z Perforce.
Dejavu

4
@Dejavu, twój komentarz nie ma sensu, biorąc pod uwagę, że współczesne IDE są obsługiwane graficznie giti robią to od lat.
Acumenus
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.