4.01.20229 min

Harsh MaheshwariApplied Scientist

Przydatna ściągawka poleceń Gita dla wszystkich koderów

15 przydatnych komend Gita i ułatw sobie nimi codzienną pracę. Znajdziesz również rozwiązanie odkopania Twojego starego kodu.

Przydatna ściągawka poleceń Gita dla wszystkich koderów

Czy zdarzyło Ci się kiedyś przez przypadek usunąć jakieś pliki lub niezbędny kod? A może chciałbyś spojrzeć jeszcze raz na starszą wersję swojego kodu? Jeśli chodzi o Gita, to w moim wachlarzu uczuć pojawia się miłość połączona z nienawiścią, czyli: kocham Gita, jeśli mogę sam pracować nad projektem i jednocześnie go nienawidzę, kiedy muszę połączyć mój kod z kodem innej osoby.

Ale wszystkie małżeństwa mają swoje wzloty i upadki, prawda? Prawda jest taka, że będąc koderem, w pewnym momencie będziesz potrzebował Gita, a kiedy już zaczniesz go używać, to zostaniesz z nim na długo, nawet jeśli czasami będzie dla Ciebie frustrujący. Przedstawiam ci więc ściągawkę, z której możesz skorzystać, jeśli chcesz wrócić do Gita po dłuższym czasie, chcesz odkryć więcej zastosowań Gita lub jeśli musisz cofnąć się w czasie i chcesz odzyskać swój dawny kod.

Ostrzeżenie: Git nie może pokazać ci Twojego kodu z przyszłości; będziesz musiał to zrobić sam ? .


Zanim bardziej zagłębimy się w temat, pozwól mi wyjaśnić strukturę Gita, abyś lepiej zrozumiał polecenia.

  • Repozytoria: Są one zbiorem plików różnych wersji projektu.
  • Zdalne repozytorium: Bieżące repozytorium, które jest przechowywane zdalnie/online. Tak więc repozytoria, które widzimy na stronie Github lub Gitlab są zdalnymi repozytoriami dla tych projektów. Zawierają one dokonane i wprowadzone przez wszystkich zmiany.
  • Lokalne repozytorium: Bieżące repozytorium, które jest przechowywane na lokalnym urządzeniu. Zawiera ono dokonane przez Ciebie zmiany i może również zawierać zmiany obecne w repozytorium zdalnym.
  • Commity: Mają za zadanie przedstawiać zmiany dokonane w kodzie.  Każdy commit zawiera zmiany dotyczące ostatniego stanu repozytorium.
  • Branche: Gałąź poboczna (branch) jest niezależną linią developmentu. Kiedy tworzymy gałąź, tworzymy zupełnie nowy katalog roboczy (working directory), przechowalnie (staging area) i historię projektu. Nowe commity są wtedy zapisywane w historii bieżącego brancha.


Zaraz dowiemy się o nich nieco więcej, tak więc zaczynajmy.


1. git config

Zacznijmy od skonfigurowania naszego środowiska dla Gita. Uruchom te polecenia w swoim terminalu, aby ustawić konfigurację Git globalnie (dla wszystkich przyszłych repozytoriów).

$ git config --global user.name "John Doe"
$ git config --global user.email "johndoe@email.com"


Innym ciekawym zastosowaniem tego polecenia jest ustawianie aliasów. Ustawiliśmy alias dla polecenia git commit w poniższym poleceniu, więc teraz git co będzie faktycznie uruchamiał git commit. Jest to bardzo pomocne przy dłuższych poleceniach, które mają dużo zmiennych.

$ git config --global alias.co commit


2. git init

Teraz musimy zainicjować folder jako repozytorium gita. W rzeczywistości to polecenie tworzy ukryty folder .git wewnątrz Twojego folderu. Ten folder to repozytorium Gita, w którym Git przechowuje własne metadane.

//Run the following command inside the folder
$ git init
//Run the following command to create a new directory that is a git repo
$ git init DIRECTORY_PATH/DIRECTORY_NAME


3. git clone

Jeśli chcesz użyć już istniejącego repozytorium Gita (repozytorium zdalne), musisz najpierw utworzyć jego kopię na swoim lokalnym urządzeniu (lokalne repozytorium). W tym celu używamy polecenia clone. W pierwszej kolejności skopiuj link do klonowania tego repozytorium (znajduje się zazwyczaj tam, gdzie Twoje zdalne repozytorium).

Link będzie wyglądał mniej więcej tak: https://github.com/harsh-99/SCL.git. Następnie uruchom poniższe polecenie w folderze, do którego chcesz pobrać swoje repozytorium.

$ git clone LINK
$ git clone https://github.com/anveenaik99/onboardScripts.git


4. git fetch

Załóżmy, że wiele osób edytuje zdalne repozytorium Twojego projektu, co oznacza, że wszyscy kodujecie zespołowo, więc zmiany reszty zespołu są dla ciebie istotne. Aby pobrać w razie potrzeby te zmiany, ważne jest, aby Twoje lokalne repozytorium wiedziało o tych zmianach, tj. musisz pobrać zmiany.

Tak więc polecenie git fetch pobiera szczegóły zdalnego repozytorium i zmiany na Twoim urządzeniu. Użyj polecenia w następujący sposób:

//download the state for all the branches
$ git fetch
//fetch for just one branch
$ git fetch <remote> <local>
//<remote> is the name of the remote branch
//<local> is the name of the local branch
//an example of it is
$ git fetch origin master


5. git pull

git pull to połączenie dwóch poleceń: git fetch + git merge. Kiedy wcześniej użyliśmy git fetch, pobierał on najpierw aktualny stan zdalnego repozytorium na nasze lokalne urządzenie, jednak nasze pliki nie zostały jeszcze zmienione. Aby wprowadzić zmiany do naszego pliku, potrzebujemy git merge, który zaktualizuje nasze lokalne pliki, w oparciu o wersję zdalną.

Powiedzmy, że mam plik o nazwie test.py, a w moim lokalnym repozytorium wygląda to tak:

print("hello")
print("Good evening")


Wersja zdalna pliku wygląda tak:

print("Good morning")
print("hello")
print("world")


Chcemy wprowadzić te zmiany, a także połączyć je z naszymi zmianami. Jeśli nie kolidują one ze sobą, to scalanie przebiega bezproblemowo. Jednak bywa tak, że dokonujemy zmian w tym samym kawałku kodu, który ktoś inny również zmienił. To właśnie wtedy Git wyrzuca KONFLIKT SCALANIA. Byłem przerażony tym komunikatem, ale zdałem sobie sprawę, że jest to najprostsza rzecz do rozwiązania. Sprawdźmy jak to zrobić w naszym poprzednim przykładzie.

Istnieją dwa możliwe sposoby scalenia powyższych wersji tego samego pliku. Możliwości te są następujące:

print("Good morning")
print("hello")
print("Good evening")
print("world")


opcja 2:

print("Good morning")
print("hello")
print("world")
print("Good evening")


Wybór, którą wersję wybrać należy do Ciebie i zależy od tego, co chcesz osiągnąć, ale pozwól, że pokażę ci, co zrobić. Kiedy wyrzucony zostanie konflikt scalania, wygląda to mniej więcej tak:

<<<<<<< HEAD
print("Good morning")
print("hello")
print("world")
=======
print("hello")
print("Good evening")
>>>>>>> origin/<remotebranch>


Linijki 1, 5 i 8 oznaczają, że Twój plik ma konflikt scalania, i aby ten konflikt usunąć, musisz wybrać albo pierwszą wersję (linijki 2-4), drugą wersję (linijki 6-7), albo kombinację tych dwóch. Następnie usuń linijki 1,5 i 8, i rób dalej, to co robiłeś.


6. git status

Po uruchomieniu tak wielu poleceń chcemy oczywiście sprawdzić, czy wszystko poszło zgodnie z planem. Dobrą wiadomością jest fakt, że Git pozwala nam na sprawdzenie statusu w dowolnym momencie.

$ git status //a sample output of this command is as follows
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)

Untracked files:
(use "git add <file>..." to include in what will be committed)

README.txt
lab1


Wszystkie sugerowane powyżej polecenia zostały omówione na moim blogu, dlatego jeśli chciałbyś coś zrozumieć lepiej, przekieruj się na wybrane polecenie.


7. git add

Kolejnym krokiem, który chcemy wykonać, jest poinformowanie Gita o zmianach, które chcemy, aby zapamiętał. Tak więc dla każdego commitu używamy polecenia git add, aby dodać zmiany do folderu, które chcemy zastosować do tego commitu.

Powiedzmy więc, że zadeklarowałem nową zmienną, w pliku o nazwie test.py, w moim repozytorium Gita o nazwie GitTutorial. Chcę poinformować Gita o tej zmianie i skłonić go do jej zapisania. Użyję polecenia git add w następujący sposób:

$ git add /path-to-test-py/test.py


Teraz, gdy uruchomisz polecenie git status, zobaczysz, że nazwa tego pliku jest zapisana na zielono, ponieważ Git jest na bieżąco z tym plikiem.

Jeśli chcesz usunąć plik lub folder, możesz skorzystać z polecenia git rm.


8. git commit

Teraz gdy dodaliśmy lub usunęliśmy zmiany, o których musimy poinformować Gita, zatwierdzamy je. To w pewnym sensie sfinalizowało kolejną wersję naszej bazy kodu. Możemy cofnąć się do wszystkich poprzednich commitów, aby zobaczyć historię wersji. Polecenie działa tak:

$ git commit -m "The message you want to write to describe this commit"


Zmienna -m pomaga napisać wiadomość opisującą commit.


9. git push

Do tej pory, cokolwiek robiliśmy, działo się w naszym lokalnym repozytorium, ale w pewnym momencie musieliśmy wypchnąć to również do zdalnego repozytorium, aby inni mogli zobaczyć i użyć naszego kodu. Robi to właśnie polecenie git push. Nazwij wszystko tak jak tutaj:

$ git push <remote> <local> 
//<remote> is the name of the remote branch
//<local> is the name of the local branch
//an example of it is
$ git push origin master


Powyższe polecenie wypycha nasze lokalne commity do brancha „master”.


10. git log

I oczywiście po wykonaniu wielu commitów, będziemy chcieli sprawdzić to, jak nasz kod ewoluował. Jak dowiemy się za moment, istnieje również taka możliwość, że wiele osób dokona commitów w swojej gałęzi i w pewnym momencie może chcieć scalić swoją gałąź z inną gałęzią. Wszystkie takie działania, które zostały wykonane w naszym repozytorium, mogą być dostępne za pomocą polecenia git log, tak jak poniżej:

$ git log --graph --oneline --decorate
//a sample output
* 0e25143 (HEAD, main) Merge branch 'feature'
|\
| * 16b36c6 Fix a bug in the new feature
| * 23ad9ad Start a new feature
* | ad8621a Fix a critical security issue
|/
* 400e4b7 Fix typos in the documentation
* 160e224 Add the initial code base


Tutaj kody alfanumeryczne, które widzimy na początku każdej linijki, reprezentują każdy commit i będą używane, jeśli będziemy chcieli przywrócić lub wykonać inne funkcje.

Sprawdź również git shortlog.


11. git revert

Dochodzimy do części Gita, która będzie nam potrzebna, gdy popełnimy jakiś błąd i będziemy chcieli odbyć podróż w czasie do poprzedniej wersji kodu. git revert można opisać jako przycisk cofania, jednak bardzo sprytny. Nie tylko cofa się w czasie, ale wprowadza przeszłe zmiany do następnego commitu, w taki sposób, że niechciane zmiany są nadal częścią historii wersji.

Dla git revert, będziemy potrzebować kodów commitów, które widzieliśmy wcześniej w logu.

$ git log --oneline
86bb32e prepend content to demo file
3602d88 add new content to demo file
299b15f initial commit
$ git reset --hard c14809fa
//this command will not changes files that you have not git added


Istnieje wiele innych sposobów na przywrócenie. Na wypadek gdybyś ich kiedyś potrzebował,warto je sprawdzić.


12. git branch

To polecenie pozwala nam tworzyć, wymieniać, zmieniać nazwy i usuwać branche. Przyjrzyjmy się kilku przykładom.

//this lists the name of the branches present
$ git branch
main
another_branch
feature_inprogress_branch
//delete a branch safely
$ git branch -d <branch>
$ git branch -d another_branch


13. git checkout

Polecenie git checkout pozwala poruszać się pomiędzy branchami, utworzonymi przez git branch.

//switch to a different branch
$ git checkout <branch_name>
$ git checkout another_branch
//create a new branch
$ git checkout -b <new_branch_name>
$ git checkout -b new_feature_branch


14. git diff

Zdarzą się sytuacje, w których będziemy musieli porównać kod pomiędzy wersjami lub branchami; wtedy właśnie używamy git diff.

//print any uncommitted changes since the last commit.
$ git diff
//compare code between two branches
$ git diff branch1 branch2
//print the uncommitted changes made in one file
$ git diff /filepath/filename


15. git rebase

Dotarliśmy do naszej ostatniej komendy, tej, której najbardziej się boję :P. Zdarzy się, że będziemy musieli scalić kody lub pobrać kod z “mastera” do naszej gałęzi.

Powiem w skrócie:

Rebase jest jednym z dwóch narzędzi Gita, które specjalizuje się w integrowaniu zmian z jednej gałęzi na inną. Innym narzędziem do integracji zmian jest git merge. Scalanie (merge) jest zawsze bieżącym zapisem zmiany. Alternatywnie, rebase posiada potężne funkcje przepisywania historii.

Zobaczmy namacalnie, co robi git rebase.

    B -- C (another_branch)
/
A--------D (master)
Rebasing another_branch onto master

B -- C (another_branch)
/
A--------D (master)


Odpowiedni kod:

$ git pull origin master
$ git checkout another_branch
$ git rebase master


Rebasing i merging są prawdopodobnie najbardziej angażującymi poleceniami w tym sensie, że będziesz musiał rozwiązać wiele konfliktów scalania, aby przywrócić w kodzie porządek. Te polecenia są jednak niezbędne, abyś mógł trzymać się środowiska opartego na kontroli wersji. Proszę, abyś trzymał się ich, nawet gdy stają się niechlujne, aby integralność strukturalna Twojego kodu pozostała właściwa. Rozwiązuj konflikty scalania tak, jak robisz to normalnie, mając na względzie wszystkie fragmenty kodu, które są dla Ciebie ważne.

Inną funkcją podobną do rebase jest git merge (jak widzieliśmy powyżej). Z git merge korzysta się głównie do scalania dwóch gałęzi i działa podobnie jak rebase.


Wnioski

Mam nadzieję, że ten artykuł okaże się dla Ciebie pomocny; daj znać w komentarzu co o tym myślisz. Mimo, że naśmiewałem się z Gita, to jest to zdecydowanie jedno z najbardziej niezbędnych narzędzi dla każdego developera i lepiej od razu je opanować! Tak więc odkrywaj i eksperymentuj dalej.


Oryginał tekstu w języku angielskim przeczytasz tutaj.

<p>Loading...</p>