Korzystanie z programu Git (index)
Stany plików:
Cykl życia plików w repo, główny podział jest na tracked (unmodified, modified, staged) i untracked. Tuż po sklonowaniu repo wszystkie pliki są tracked i unmodified.
Untracked Unmodified Modified Staged | | | | | Add the file | | | |----------------------------------------------------------o| | | Edit the file | | | |------------------o| | | | | Stage the file | | | |------------------o| | Remove the file | | | |o------------------| | | | | Commit | | | |o--------------------------------------|
$ git status # stan repo $ git status -s # lub --short, short status # Mamy dwuliterowe statusy plików (A, D, R, M, ?). $ git diff --cached # różnice między indeksem a HEAD (co obejmie commit) $ git diff # różnice między indeksem a working directory $ git diff HEAD # różnice między HEAD a working directory $ git log # historia rewizji $ git log --pretty=oneline -5 # jest wiele opcji dostępnych $ git log --grep=lekcja # string "lekcja" w komentarzach $ git log --author=Andrzej # z pełnego imienia i nazwiska $ git log --stat # statystyki
Zakładam, że jesteśmy świeżo po wykonaniu commit.
$ git branch # mamy jedną gałąź master, którą będziemy zwiedzać * master $ git log --pretty=oneline -4 # ostatnie 4 rewizje 48ae450a329c92558038de3b721a029d8eea8c14 UnionFind changed. 64ec8f8edb9ca891b18d94d906d885f91e67e220 Sudoku 6x6 added. 63557016925125da2239af31bc788efac907e186 Rich comparisons. 60a68aa1427fc8f4fd47a06ff6d963908c144c0c lekcja10 changed. # Historia: ...--60a6--6355--64ec--48ae <-- master <-- HEAD $ git checkout 60a6 # HEAD odkleja się od master Note: checking out '60a6'. You are in 'detached HEAD' state. ... HEAD is now at 60a68aa... lekcja10 changed. $ git branch * (no branch) master $ git checkout master # powrót do ostatniej rewizji ... Switched to branch 'master'
Te operacje wykonujemy tylko na prywatnych gałęziach, bo w publicznym repo może popsuć się synchronizacja (chyba że nikt nie korzystał w ostatnim czasie).
$ git reset --hard # stan repo z ostatniej rewizji $ git reset --hard HEAD # jw $ git reset --hard HEAD^ # kasowanie ostatniej rewizji $ git reset --hard [sha1] # kasowanie historii!
# Ignorujemy zmiany które nastapiły po ostatniej rewizji. $ git checkout -f # lub --force, stan repo z ostatniej rewizji $ git checkout -f HEAD # jw
HEAD to nazwa symboliczna wskazująca na ostatnią rewizję w bieżącej gałęzi. HEAD^ oznacza pierwszego rodzica ostatniej rewizji. X^n oznacza n-tego rodzica rewizji X. X~n oznacza przodka n-tej generacji rewizji X.
# Pełny opis metod identyfikacji rewizji: $ git revisions --help
To jest bezpieczne, jeżeli ostatnia rewizja nie została udostępniona publicznie. Chodzi o sytuację, gdy wykonaliśmy commit za wcześnie, a jeszcze potem doszły pewne drobne zmiany. Stara rewizja zostanie usunięta i powstanie nowa. W ten sposób można poprawić komentarz ostatniej rewizji bez wprowadzania faktycznych zmian w repo.
$ git add -A # albo coś podobnego $ git commit --amend -m "Komentarz."
Tą operację można bezpiecznie wykonywać na publicznych rewizjach.
# git revert --no-edit [sha1] # Domyślny komentarz będzie postaci: Revert "..." # git revert HEAD # odwrócenie ostatniej rewizji # git revert HEAD^ # odwrócenie przedostatniej rewizji (możliwy konflikt)
Łączenie wszystkich rewizji występujących po rewizji [sha1] w jedną rewizję [zakładam liniowa historię repo]. Opcja -i włącza tryb interaktywny. Łączenie wykonuje się na rewizjach, które nie zostały udostępnione publicznie.
# git rebase -i [sha1] # lub --interactive $ git rebase -i HEAD~3 # łączenie trzech ostatnich rewizji w jedną
Pliki, które Git ma ignorować, umieszczamy w pliku ukrytym .gitignore. Zwykle stosujemy tu znaki uogólniające (*.log, *.[oa]).
GitHub maintains an official list of recommended .gitignore files for many popular operating systems, environments, and languages in the github/gitignore public repository.
https://github.com/github/gitignore (kolekcja plików .gitignore)
$ git add file1 # dodawanie pliku do indeksu, jest staged, będzie committed $ git rm file1 # usuwa plik, jest staged, będzie untracked $ git rm --cached file1 # zostaje na dysku, będzie untracked $ git mv file1 file2 # Git wie, że jest zmiana nazwy pliku
Git umożliwia oznaczanie rewizji przy użyciu znaczników (ang. tags). Dostępne są dwa rodzaje znaczników:
$ git tag # wypisanie znaczników $ git tag -l "v1.8*" # wzorzec wyszukiwania # git tag -a [tag_name] -m "Komentarz." # tworzenie znacznika opisanego # git tag [tag_name] # tworzenie znacznika lekkiego # git tag [tag_name] [sha1] # tworzenie znacznika lekkiego # git tag -d [tag_name] # usuwanie znacznika (obu) $ git tag -a v1.0 -m "My version 1.0" # znacznik opisany # Domyślnie "git push" nie przesyła znaczników do remote. # Trzeba specjalnie sobie tego zażyczyć. # git push origin [tag_name] # git push origin --tags # wszystkie tagi