Git/Przypadki
Szybki start (do uporządkowania)
[edytuj]Wymagania
[edytuj]Zakładamy, że
- zainstalowano program git
- zainstalowano SSH[1] i ustalono ustawienia
- utworzeno nowy lub skopiowano istniejący projekt
Schemat pracy z projektem
[edytuj]Schemat zależy od sytuacji projektu
Proponowany podstawowy schemat pracy : [2]
- wprowadzenie zmian w pliku lub plikach
- sprawdzamy jakie pliki zostały zmienione : git status
- sprawdzamy co zostało zmienione w pliku : git diff [file]
- zatwierdzamy zmianę : git commit -a -m [message] [3]
mkdir git_repo # tworzymy katalog w którym będzie nasze repozytorium plików, możemy nazwać jak chcemy cd git_repo # przechodzimy do tego katalogu git init # inicjalizujemy bazę repozytorium (katalog .git)
Teraz wgrywamy do tego katalogu pliki lub tworzymy nowe.
git add . # dodajemy wszystkie pliki do śledzenia z aktualnego katalogu, kropka oznacza właśnie katalog aktualny git status # sprawdzamy status naszego repozytorium, to polecenie pokaże które pliki zmienione, a które nowe git commit -a # zatwierdzamy zmiany czyli wysyłamy pliki do bazy repozytorium
Samo polecenie git commit zapisze tylko pliki, które zostały dodane poleceniem git add. Dlatego dodajemy -a, żeby nie dodawać ręcznie każdego zmienionego pliku. Nowe pliki trzeba jednak dodać przez git add.
git log # sprawdzamy historię zatwierdzeń git whatchanged -p # historia zmian razem z diff git whatchanged --pretty=oneline # wyświetla tylko nazwy zmienionych plików
Zaawansowane możliwości :
- gałęzie ( dodawanie, scalanie i usuwanie, konflikty)
- zdalne repozytoria[4]
- zbiorowa praca nad projektem
Podstawowa obsługa Gita
[edytuj]- Większość operacji wykonuje się przez "git polecenie".
- Tworzenie gałęzi to "git checkout -b".
- "git branch" powinno być używane tylko do wylistowania i usuwania gałęzi.
- Współdzielisz swoją pracę przez "git fetch" (pobranie) i "git push" (wysłanie). To są przeciwieństwa.
- uaktualnianie lokalnego repozytorium ze zdalnego : "git pull" może również zrobić "git fetch" ale to jest opcjonalne.
- git nie dodaje pustych katalogów do repozytorium. To wynika z koncepcji, że git śledzi zawartość plików a nie pliki.
Pomoc
[edytuj]Aby uzyskać pomoc na temat jakiegoś polecenia wpisujemy "git help polecenie" lub "git --help".
Przypadki użycia
[edytuj]Projekt
[edytuj]Mamy dwie możliwości
git init # tworzenie nowego repozytorium w istniejącym projekcie lub nowo utworzonym projekcie git clone /path/to/repository # kopiowanie z dysku lokalnego git clone username@host:/path/to/repository # kopiowanie ze zdalnego serwera ( from origin to local )
katalogi
[edytuj]Jak zmienić nazwę katalogu ? [5]
Jak znależć wszystkie katalogi -git ?
[edytuj]Za pomocą find[6]
find . -name .git -type d -prune
bez ".git"
find . -type d -exec test -e '{}/.git' ';' -print -prune
z użyciem xargs
find ~ -type d -name .git | xargs -n 1 dirname
usunąć katalog
[edytuj]Usunąć katalog[7]
git rm -r --cached some-directory git commit -m 'Remove the now ignored directory "some-directory"' git push origin master
problemy z dostepem do katologów
[edytuj]Jak zmienić włąściciela i uprawninia ukrytych katalogów:[8]
shopt -s dotglob chmod -R 775 *
oraz:[9]
git update-index --chmod=+x
Pliki
[edytuj]Zmiany lokalne :
git add * git commit -m "Commit message"
Przesyłanie zmian na serwer :
git remote add origin <server> # jeśli nie mamy ustwaionego zdalnego repo[10] git push origin master # jeśli mamy ustawione zdalne repo
Jeśli nie mamy dostępu do serwera zdalnego to :
git push origin master
error: Cannot access URL http://code.mathr.co.uk/mandelbrot-graphics.git/, return code 22
fatal: git-http-push failed
error: failed to push some refs to 'http://code.mathr.co.uk/mandelbrot-graphics.git'
wtedy tworzymy łatę i wysyłamy mailem :
- git-format-patch - Prepare patches for e-mail submission
- git-send-email - Send a collection of patches as emails
Niejasności związane z git add
[edytuj]Uruchamiamy git add tekst.txt i cały plik tekst.txt jest wrzucany do indeksu. Razem z zawartością. Jeśli teraz wprowadzimy jakieś poprawki do tekst.txt i nie zrobimy znowu git add tekst.txt, to git commit tekst.txt wyśle do repozytorium starszą wersję znajdującą się w indeksie.
Dlatego git add używamy tylko w trzech wariantach:
git add . git add nowy_plik git add nowy_plik nowy_plik2 itd.
Kopiowanie plików na serwer
[edytuj]Dodajemy zdalny serwer ( tutaj GitHub) :
git remote add github_c https://github.com/adammaj1/c
Sprawdzamy zdalne repo :
git remote show github_c
Otrzymujemy wynik :
* remote github_c Fetch URL: https://github.com/adammaj1/c Push URL: https://github.com/adammaj1/c HEAD branch: master Remote branch: master new (next fetch will store in remotes/github_c) Local ref configured for 'git push': master pushes to master (local out of date)
Próbujemy wysłać pliki do zdalnego repozytorium ( ang. remote ):
git push github_c master
Najpierw musimy się zalogować :
Username: Password:
Otrzymujemy odpowiedź :
To https://github.com/adammaj1/c ! [rejected] master -> master (non-fast-forward) error: failed to push some refs to 'https://github.com/adammaj1/c' To prevent you from losing history, non-fast-forward updates were rejected Merge the remote changes (e.g. 'git pull') before pushing again. See the 'Note about fast-forwards' section of 'git push --help' for details.
Przyczyną błędu jest zmiana dokonana w zdalnym repo (na serwerze github), której nie ma w lokalnym repo
Rozwiązaniem jest : [11]
git pull github_c master
Otrzymujemy :
From https://github.com/adammaj1/c * branch master -> FETCH_HEAD Merge made by recursive. README.md | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) create mode 100644 README.md
Następnie powtarzamy :
git push github_c master
I mamy pliki w zdalnym repo !
Wrzucanie pojedynczego nowego pliku
[edytuj]Załóżmy, że stworzyliśmy nowy plik tekst.txt i chcemy go wrzucić do repozytorium. Tutaj też najpierw trzeba go wrzucić do poczekalni
git add tekst.txt
Dopiero potem wysyłamy plik do repozytorium.
git commit -m 'pierwszy plik'
Wrzucanie zmienionego pojedynczego pliku
[edytuj]Nasz plik tekst.txt już jest w repozytorium, ale zrobiliśmy zmiany, które chcemy zapisać w repozytorium. W tym przypadku możemy pominąć poczekalnię
git commit tekst.txt -m 'drobna zmiana'
Wrzucanie tylko zmienionych plików bez plików nie śledzonych
[edytuj]Załóżmy, że zmieniliśmy wiele plików, ale w naszym katalogu projekt1 są pliki, których nie chcemy w repozytorium jeszcze. Komenda git add . tu nam nie pomoże. Ale jest inna, która doda tylko pliki już śledzone przez git.
git add -A
Wrzucanie dwóch z wielu zmienionych plików
[edytuj]Znowu zmieniliśmy tekst.txt, ale także tekst2.txt oraz tekst3.txt. Chcemy jednak wysłać do zmiany dotyczące tekst.txt oraz tekst2.txt.
git commit tekst.txt tekst2.txt
usuwanie pliku ze zdalnego repo bez usuwania z lokalnego
[edytuj]Opis[12]
git rm --cached mylogfile.log git commit -m "rmv" git push -u origin main
Wrzucanie katalogu
[edytuj]Wrzucamy katalog html i wszystkie pliki w nim zawarte :
git add html/*
Drzewo i jego gałęzie
[edytuj]Jeśli chcemy, możemy rozgałęziać nasz projekt tworząc gałęzie. Domyślnie nowy projekt jest w gałęzi master.
git branch # Wszystkie gałęzie można wylistować poleceniem : git checkout -b feature_x # tworzy gałąź feature_x i przełącza na nią git branch -d feature_x # usuwa gałąź feature_x git checkout master # przełączamy do gałęzi master git push origin feature_x # wysyła na zdalny serwer gałąź feature_x
Graficzne drzewo
[edytuj]Jeśli chcemy graficznie zobaczyć nasze drzewo kodu, to trzeba użyć polecenia gitk (w gentoo "gitview")
Można też skorzystać z parametru --graph w git log --graph --oneline.
Usuwanie gałęzi ze zdalnego repo
[edytuj]git push origin :<branch_name>
zaawansowane
[edytuj]poczta
[edytuj]Wysyłanie łat mailem : [13]
# create a patch for each commit from origin's master to yours git format-patch origin/master..master # now send them... # there are a zillion options here, and also some configuration; read the man page git send-email --to=maintainer@project.com --from=me@here.com ... *.patch git am will accept the patches created by format-patch, and apply them sequentially, for example:
Odbiorca maila ( jeśli akceptuje łaty ):
git am *.patch
Cofanie zmian (do uprządkowania)
[edytuj]Poniższe polecenia działają na plikach już śledzonych. Jeśli chcemy usunąć także pliki nie śledzone, trzeba to zrobić ręcznie. Można najpierw usunąć wszystkie pliki poleceniem
rm -Rf *
To nie usunie katalogów o nazwach zaczynających się na kropkę czyli repozytorium .git.
git reset HEAD^ # nie ruszaj plików roboczych - pozostaw zmiany git reset --hard HEAD^ # zresetuj również pliki robocze git reset --hard HEAD~5 # cofnij się o 5 zapisów git reset --hard origin # wyczyść wszystkie zmiany i zacznij od nowa
git-checkout -- nazwa_pliku # Przywróć ostatnią wersję pliku z repozytorium dla aktualnej gałęzi git-checkout revision nazwa_pliku # Przywróć plik w wersji revision
Uwaga!
git-checkout revision #utworzy nam oderwaną gałąź, co nie koniecznie jest oczekiwane
git reset --hard revision # uaktualni HEAD i aktualną gałąź do punktu określonego przez revision, i uaktualni drzewo robocze aby odzwierciedlało nowy index.
Jeśli git reset --hard HEAD^ nie zadziała to trzeba trzeba inaczej
git reflog
wyświetli nam się lista operacji i znajdujemy numer tej operacji, do której chcemy wrócić.[14]
git reset --hard HEAD@{1}
Wycofanie nie zapisanych zmian (dwa polecenia)
git checkout file-to-revert git reset HEAD <file>
Cofnięcie wszystkich lokalnych zmian
git checkout -f
Problemy
[edytuj]git mv error : fatal: bad source
[edytuj]Przyczyna :
- próbujemy przesunąć plik który nie był zmieniony. Sprawdzamy za pomocą git status
Unable to write new index file, czyli brak miejsca na dysku
[edytuj]Opis [15]
Nie można ponowić czynności clone
[edytuj]Opis[16]
Odnośniki
[edytuj]- ↑ Setup git from github
- ↑ Understanding Git by Charles Duan
- ↑ How to properly commit to your git repository (rebasing) by Andrew Brown
- ↑ Praca-ze-zdalnym-repozytorium
- ↑ Rename-files-and-folders-with-git by Patrick Wied
- ↑ stackoverflow question : how-to-quickly-find-all-git-repos-under-a-directory
- ↑ stackoverflow question: remove-directory-from-remote-repository-after-adding-them-to-gitignore
- ↑ superuser question: how-to-chmod-and-chown-hidden-files-in-linux
- ↑ stackoverflow question: /how-to-add-chmod-permissions-to-file-in-git
- ↑ gi guide by by Roger Dudler
- ↑ Rip's Domain : Git: push rejected non-fast forward
- ↑ stackoverflow question: rremove-a-file-from-a-git-repository-without-deleting-it-from-the-local-filesyste
- ↑ stackoverflow questions : getting-started-with-git-am
- ↑ Guide
- ↑ | Brak miejsca na dysku
- ↑ można ponowić czynności clone