Git kısa başvuru sayfası [PDF]
(wizardzines.com)- Git’te sık takılınan işlemleri commit oluşturma, branch değiştirme, değişiklik karşılaştırma, uzak depo eşitleme ve değişiklikleri geri alma komutları üzerinden hızlıca bulunabilecek şekilde düzenleyen bir PDF
- Yerel iş akışı, stage öncesi ve sonrası durumu kontrol edip commit oluşturmak için
git status,git add,git commit,git diffetrafında şekilleniyor - Branch işlemleri, oluşturma·geçiş·birleştirme·yeniden tabanlama için
git switch,git checkout,git branch,git merge,git rebase,git cherry-pickkullanıyor - Geçmişi inceleme ve kurtarma için
git log,git blame,git show,git reflog,git reset,git restoreyer alıyor; branch’ler, tag’ler,HEADve uzak branch’ler de commit referansı olarak kullanılabiliyor - Uzak depo işlemleri, değişiklikleri alma ve gönderme sürecini
git remote add,git fetch,git pull,git push,git push --force-with-lease,git push --tagsile ele alıyor
Depoyu başlatma ve mevcut durumu kontrol etme
- Yeni depo başlatma:
git init
- Mevcut bir depoyu kopyalama:
git clone $URL
- Geçerli konumu ve durumu kontrol etme:
git status
Commit hazırlama ve oluşturma
- Takip edilmeyen dosya ekleme:
git add $FILE
- Tüm takip edilmeyen dosyaları ve stage edilmemiş değişiklikleri ekleme:
git add .
- Bir dosyadaki değişikliklerin yalnızca bir kısmını seçerek stage etme:
git add -p
- Dosya silme veya taşıma:
git rm $FILEgit mv $OLD $NEW
- Dosyayı silmeden Git takibinden çıkarma:
git rm --cached $FILE
- Tüm stage işlemlerini iptal etme:
git reset HEAD
- Commit oluşturma:
git commit- Mesajı yazmak için metin düzenleyiciyi açar
- Mesajı doğrudan belirterek commit oluşturma:
git commit -m 'message'
- Stage edilmemiş değişiklikleri de dahil ederek mesajla birlikte commit oluşturma:
git commit -am 'message'
Branch değiştirme ve yönetimi
- Branch değiştirme:
git checkout $NAMEgit switch $NAME
- Branch oluşturma:
git checkout -b $NAMEgit switch -c $NAME
- Branch listesini görüntüleme:
git branch
- Branch’leri en son commit’e göre sıralama:
git branch --sort=-committerdate
- Branch silme:
git branch -d $NAME
- Branch’i zorla silme:
git branch -D $NAME
Geçmişi inceleme ve kod takibi
- Bir branch’in geçmişini görüntüleme:
git log main
- İki branch arasındaki ilişkiyi grafik olarak görüntüleme:
git log --graph a b
- Tek satırlık log görüntüleme:
git log --oneline
- Dosyadaki her satırı en son kimin değiştirdiğini görme:
git blame $FILENAME
- Dosyayı değiştiren tüm commit’leri görüntüleme:
git log $FILENAME
- Belirli bir metni ekleyen veya kaldıran commit’leri bulma:
git log -S banana
Değişiklikleri karşılaştırma
- Bir commit ile ebeveyn commit’i arasındaki farkı görüntüleme:
git show $COMMIT_ID
- Bir merge commit ile birleştirilen ebeveynleri arasındaki farkı görüntüleme:
git show --remerge-diff $COMMIT_ID
- Diff özetini görüntüleme:
git diff $COMMIT_ID --statgit show $COMMIT_ID --stat
- İki commit’i karşılaştırma:
git diff $COMMIT_ID $COMMIT_ID
- Yalnızca belirli bir dosyayı commit ile karşılaştırma:
git diff $COMMIT_ID $FILENAME
- Stage edilmiş ve stage edilmemiş tüm değişiklikleri karşılaştırma:
git diff HEAD
- Yalnızca stage edilmiş değişiklikleri karşılaştırma:
git diff --staged
- Yalnızca stage edilmemiş değişiklikleri karşılaştırma:
git diff
Yapılandırma dosyaları ve seçenekler
- Yerel Git yapılandırma dosyası:
.git/config
- Genel Git yapılandırma dosyası:
~/.gitconfig
- Yoksayılacak dosya listesi:
.gitignore
- Yapılandırma seçeneği belirleme:
git config user.name 'Julia'
- Genel seçenek belirleme:
git config --global ...
- Alias ekleme:
git config alias.st status
- Kullanılabilir yapılandırma seçeneklerini görüntüleme:
man git-config
Geçmişi düzenleme ve dosya geri yükleme
- En son commit’i geri alma, çalışma dizinini olduğu gibi koruma:
git reset HEAD^
- Başarısız bir rebase’i geri alma:
git reflog BRANCHNAMEgit reset --hard $COMMIT_ID
- Son 5 commit’i tek commit’te birleştirme:
git rebase -i HEAD^^^^^^- Birleştirilecek commit’lerde
pickyerinefixupyazılır
- Başka bir branch veya commit’ten dosya sürümünü alma:
git checkout $COMMIT_ID $FILEgit restore $FILE --source $COMMIT_ID
- Commit mesajını değiştirme veya unutulan dosyaları ekleme:
git commit --amend
Branch’leri birleştirme
- Geçerli branch’i başka bir branch üzerinden güncelleyen fast-forward merge:
git switch maingit merge banana
- Bir commit’i başka bir branch’e kopyalama:
git cherry-pick $COMMIT_ID
- Ayrışmış branch’leri rebase ile birleştirme:
git switch bananagit rebase main
- Ayrışmış branch’leri merge ile birleştirme:
git switch maingit merge bananagit commit
- Ayrışmış branch’leri squash merge ile birleştirme:
git switch maingit merge --squash bananagit commit
Uzak depo ve eşitleme
- Uzak depo ekleme:
git remote add $NAME $URL
mainbranch’inioriginuzak deposuna push etme:git push origin main
- İlk kez push edilen branch’i
origine gönderip takip branch’ini ayarlama:git push -u origin $NAME
- Geçerli branch’i uzak takip branch’ine push etme:
git push
- Zorla push etme:
git push --force-with-lease
- Tag’leri push etme:
git push --tags
- Değişiklikleri alma, yerel branch’leri değiştirmeme:
git fetch origin main
- Tüm branch’leri fetch etme:
git fetch --all
- Fetch sonrası geçerli branch üzerinde rebase yapma:
git pull --rebase
- Fetch sonrası geçerli branch üzerinde merge yapma:
git pull origin maingit pull
Commit’i işaret etme yöntemleri
$COMMIT_IDyerine çeşitli referanslar kullanılabilir:- Branch:
main - Tag:
v0.1 - Commit ID:
3e887ab - Uzak branch:
origin/main - Geçerli commit:
HEAD - 3 commit önceki durum:
HEAD^^^ - 3 commit önceki durum:
HEAD~3
- Branch:
Değişiklikleri atma
- Tek bir dosyadaki stage edilmiş ve stage edilmemiş tüm değişiklikleri silme:
git checkout HEAD $FILE
- Tek bir dosyadaki stage edilmemiş değişiklikleri silme:
git checkout $FILE
- Tüm stage edilmiş ve stage edilmemiş değişiklikleri silme:
git reset --hard
- Stage edilmiş ve stage edilmemiş değişiklikleri stash’e alma:
git stash
- Takip edilmeyen dosyaları silme:
git clean
1 yorum
Hacker News görüşleri
Birkaç gizli cevher gibi komut var:
git diff --stagedson commit ile şu anda stage edilen içerik arasındaki farkı gösteriyor; bu yüzden dosya ya da hunk’ları ince ayarla eklerken yalnızca amaçlanan içeriğin girdiğini doğrulamak için çok iyigit log <file>yalnızca o dosyanın değiştirildiği commit’leri gösteriyor; böylece tümgit logçıktısını kurcalama ihtiyacı azalıyor ve özellikle sık değişmeyen dosyalarda faydalı oluyorgit add --patchkullanırken Git’in böldüğü hunk’lardan daha ayrıntılı seçim yapmak istersenizeseçeneğini deneyin. Tek tek satırları nasıl dahil edip hariç tutacağınızı yönlendiriyor, yani ezberlemeniz gerekmiyorgit diff --stagedkomutunungit diff --cachediçin bir takma ad olduğunu ancak şimdi öğrendim. Yıllardırcachedkullanıyordum amastagedkesinlikle daha sezgisel. Yine de bu kas hafızasını silebilir miyim emin değilimİlgileniyorsanız bakabilir veya takma ad önerebilirsiniz: https://gitlab.com/Falimonda/gitrc
git config --global commit.verbose trueayarlanırsa Git, commit mesajı düzenleyicisindeki yorum alanına stage edilmiş diff’i otomatik olarak ekliyorListede yok ama sevdiğim komutlardan biri
git log -LstartLine,endLine:fileNameGenişletilmiş bir
git blamegibi çalışıyor; belirtilen satırların zaman içinde nasıl değiştiğini ve bunları kimin değiştirdiğini gösteriyor. Satır numaraları değişse veya dosya taşınsa bile takibi sürdürüyor“Bunu kim, ne zaman, neden böyle yaptı?” ya da “Bu ne zamandan beri böyle?” gibi sorulara cevap veriyor
Phil Karlton’ın “Bilgisayar biliminde zor olan yalnızca iki şey vardır: cache invalidation ve isimlendirme.” sözü aklıma geldi
Bu açıdan bakınca Git komut adının
blameolması epey tuhaf gelmişti; bunu sadece ben düşünmüyormuşumWhat does 'git blame' do? https://stackoverflow.com/questions/31203001/what-does-git-blame-do
Blame someone else for your bad code https://news.ycombinator.com/item?id=27963868
Git blame should be called git credit https://dev.to/damcosset/git-blame-should-be-called-git-credit-27h5
Does Git Blame sound too negative? https://www.reddit.com/r/ProgrammerHumor/comments/r5lzyo/does_git_blame_sound_too_negative_just_look_up/
gitolduğunu düşününce,blamemarkaya uygun bir isim gibi duruyorblameadınıwhoolarak değiştirdim. Aslında koyu bir Vim kullanıcısı olduğum için sadecewkullanıyorumGit’i öğrenme biçimini beğendim. İlk başta üçüncü taraf bir Git GUI’si olan Sourcetree ile başladım; kullanması ve anlaması çok kolaydı
Sonra
git guiya geçtim ama bu aşama atlanabilir. Ardından UI açmak zahmetli gelmeye başladı ve terminal komutlarını öğrendimGit’e yeni başlayanlara bunu öneririm ama sonuçta bu yalnızca benim n=1 deneyimim
clone,pull,commit,pushve şimdiye kadar bu yetti. Git bu kadar basit de olabilir. Elbette ihtiyaç olursa daha karmaşık kullanım biçimleri de öğrenilebilirMagit kullanmaya başladığım anda Git’i anlamaya başladım
Sublime Merge hakkında söyleyebileceğim tek şey övgü
Git’in gereksiz yere karmaşık olmasının tarihsel nedenleri olup olmadığını merak ediyorum
Bu kopya kağıdını görünce bu karmaşıklığı daha çok hissediyorum
Bu kadar yaygınlaşmış olması “mutlu bir kaza” da olabilir, talihsizlik de. GitHub’ın “ücretsiz Git barındırma” ile Git’i yaygınlaştırmadaki payı büyük ama Git’in birçok proje için ideal sürüm kontrol sistemi olduğunu düşünmüyorum
Linus ve Linux için yapıldığı için, terminoloji ve iş akışı diğer sıradan sürüm kontrol sistemlerine göre ters hissettirebiliyor.
Pull Requestadı da, Linux geliştirmede Linus’un ya da bakımcının değişiklikleri çekirdek ağacına çekmesinden geliyor. Diğer sistemlerde buna geneldeMerge Requestdeniyor; değişikliklerin nereden geldiğinden bağımsız olarak ağaca birleştirilmesini anlattığı için o ad çok daha mantıklıGit, devasa kod tabanlarını hızlı işleyebilen neredeyse tek açık kaynak dağıtık sürüm kontrol sistemi idi ve bu yüzden büyük şirketlerde de ataleti arttı
Kişisel projelerde Mercurial’i çok daha fazla tercih ediyor ve gerçekten kullanıyorum ama Android AOSP gibi büyük kod tabanlarında Hg kullanmayı denerseniz ciddi şekilde tekliyor. Mercurial’ın kullanıcı arayüzü ve komut sistemi daha iyi, ayrıca değişiklik ağacını görmek için anında bir web sunucusu açma özelliği de var; ancak Python ile yazıldığı için performans ve ölçeklenebilirlik açısından ideal değil
git checkoutgibi mevcut alt komutlara sürekli yeni işlevler yüklendi ve bu da kullanıcı deneyimini daha kafa karıştırıcı hale getirdiModern Git’te yeni alt komut ekleme maliyeti azaldı ve
git switchgibi daha spesifik komutlar eklenmeye başlandılog,add,commit,pull,pushgibi birkaç Git komutunu bilmek yeterli bence. GUI araçları da varDürüst olmak gerekirse, tipik kullanımda Git’in o kadar da karmaşık olduğunu düşünmüyorum. Sadece gerektiğinde kullanılabilecek çok sayıda güçlü özelliği var
Çekirdek geliştiricileri merkezi olmayan bir şekilde birbirleriyle iletişim kurmak ve birbirlerinin işi üzerine tekrar çalışmak zorundaydı. 15.000 kişinin kod yazdığı bir projede nasıl çalışılır? Git bu amaç için yapıldı
Tasarlandığı iş akışını desteklemek için gerektiği kadar karmaşık. Daha basit bir araç yapmak kolaydır ama o zaman Linux çekirdeği geliştirme gibi karmaşık iş akışlarını destekleyemez. Bu yüzden gereksiz yere karmaşık değil ama daha basit kullanım senaryoları için gerekenden karmaşık olduğu doğru
Daha az karmaşık bir frontend istiyorsanız, Git’i daha kolay kullanmanızı sağlayan çok araç var. Tam zamanlı bir yazılım geliştiricisi değilseniz Git’i doğrudan kullanmanızı önermem. Ama tam zamanlı geliştiriciyseniz, iç kavramları anlamaya zaman ayırmaya değer ve bir kez anladığınızda Git yaptığı işe göre oldukça zarif
Bir yazılım geliştiricisini Git biliyor mu diye elemem ama bu tür temel sistemlerin nasıl çalıştığını kendi başına çözmek size dopamin vermiyorsa bu alan size göre olmayabilir. Yine de sorun değil; herkes için uygun olan ve olmayan şeyler var
Git dallanıp ilerlemeyi öğrenmek için https://learngitbranching.js.org tavsiye ederim. Tabii https://xkcd.com/1597/ de geçerli
git add -pkomutunu bilmiyordum, gerçekten çok faydalı-p,--patch, indeks ile çalışma ağacı arasındaki patch hunk’larını etkileşimli olarak seçip indekse eklemenizi sağlar. Değişiklikleri indekse eklemeden önce farkları gözden geçirme fırsatı verirBuraya eklemek istediğim şey,
git commit --fixup $COMMIT_IDilegit rebase -i upstream/master --autosquashkombinasyonuSon dönemdeki iş akışımın vazgeçilmez bir parçası oldu. Julia’nın örneğinde önceki 5 commit’i rebase etmek için
HEAD^^^^^kullanılıyor ama ben yakın zamana kadarHEAD~5kullanıyordum. Fakat artık upstreamHEAD’e kadar olan tüm commit’leri doğrudan rebase edebileceğimi öğrendimgit commit --fixup $COMMIT_ID’i hemen kullanmaya başlamalıyım. Ben hep “oops GET users/me” gibi küçük düzeltme commit’leri oluşturup bir sonraki etkileşimli rebase sırasında bunları elle taşıyıp fixup yapıyordum ama bu yöntem çok daha iyi“Son 5 commit’i tek bir commit’te birleştir:
git rebase -i HEAD^^^^^^” ifadesinde doğru olanıngit rebase -i HEAD~5olduğunu düşünüyorumTabii yalnızca doğrusal geçmişi rebase etmeye çalışıyorsanız
https://stackoverflow.com/questions/2221658/whats-the-difference-between-head-and-head-in-git
En büyük farkındalık, tüm commit’lerin hala içeride durduğunu anladığım andı. Tag’ler ve branch’ler yalnızca commit’leri işaret ediyor; branch’in eskiden işaret ettiği commit’ler de kaybolmuş olmuyor
Birçok komut, hatta muhtemelen neredeyse hepsi yıkıcı değil; bu yüzden branch’in önceki durumlarına kolayca başvurabiliyorsunuz
git reflog’u görmüştüm ama çoğunlukla sadece “Daha önce üzerinde çalıştığım o branch hangisiydi?” diye hatırlamak için kullanıyordumİstenmeyen bir conflict çözümünün tam ortasına düşürebilecek işlemlere karşı yarı sağlıklı bir korku geliştirmiştim. Çünkü genelde yanlış commit’e ya da branch’e referans verip conflict çıkarıyordum
O korku tamamen geçmiş değil ama en azından rebase gibi işlemler arasında önceki çalışmaları geri getirme konusunda artık epey rahatım
Bir işlemin ardından conflict çıkıp çıkmayacağını bilmiyorsam, sadece yapıp sonucu görüyorum. Conflict çıkarsa çözüyorum ya da conflict’i yaratan işlemi geri alıyorum; ya da başka yerde yeni bir commit oluşturup conflict’i daha sonra ele alacak şekilde bırakıyorum
Conflict çıkacağını biliyorsam ilgili branch’i kopyalayıp önceden uyumlu hale getirmeyi deniyorum ya da conflict çıkaran işlemi çalıştırıp çözüm sürecinden geçiyorum. Çözüm dağınık hale gelirse, çözümlerin bir kısmını geri alıp denemeye devam edebiliyor, bir süre erteleyip başka iş yapabiliyor ya da tüm ağacı atabiliyorum
Açık konuşmak gerekirse, Git’i bırakıp JJ’ye bakmak lazım
https://martinvonz.github.io/jj/v0.17.1/
Sanırım Linus bile Git’in UI’ının berbat olduğunu düşünürdü. JJ’nin iş akışı harika
Yine de biraz kurcalamış olmam dışında gerçek işte derinlemesine kullanmış değilim, o yüzden kesin konuşmak zor