Hasktir, Git!?!

Git zordur, sıçıp batırmak ise kolay, hatta bazı durumlarda Cafer bile size bez getirmeyebilir. Git dökümantasyonuna girip aramaya başladığında ise, bu karmaşadan nasıl kurtulabileceğini bulmanın tek yolunun karşılaştığın hatanın adının ne olduğunu bildiğin zaman mümkün olabileceğini anlarsın. Sonra tavuk mu yumurtadan çıkar, yumurta mı tavuktan moduna girersin.

Bu yüzden, burada kendimi içine soktuğum durumlardan bazılarını, ve bunlardan zamanla nasıl kurtulduğumu basit bir Türkçe ile anlatmaya çalışacağım.

Hassktir, çok boktan bişey yaptım, git'in bunu geri alacak bir zaman makinası var de bana, n'olur!?!

git reflog
# tüm branch'lar dahil, git'te yaptığın her
# şeyin bir listesini göreceksin. Her birinin
# HEAD@{index} şeklinde bir indeksi olacak.
# sıçmaya başlamadan önce son temiz yeri bul,
git reset HEAD@{index}
# al sana sihirli zaman makinası.

Bunu yanlışlıkla sildiğin bir şeyi geri almaya, veya reponun çalışmamasına sebep olan bir denemeni kaldırmaya, veya yanlışlıklarla dolu bir merge işleminin ardından kodları tekrar ayağa kaldırmaya, ya da herşeyin çalıştığına emin olduğun bir noktaya tüm sistemi geri almaya kullanabilirsin. Ben reflog'u ÇOK SIK kullanırım. Bunu buraya eklememi bana öneren herkese saygıyla şapka çıkartıyorum!

Sktir ya, Kodları commit'ledim ve hemen peşinden küçük bir değişiklik yapmam gerektiğini unuttum!

# değişikliği yap
git add . # veya dosyaları tek tek ekle
git commit --amend --no-edit
# ve şimdi son yaptığın commit bu değişikliği de içerecek!
# UYARI: hiç bir zaman push ettiğin commit'leri amend etme!

Bu genelde benim başıma kodu commit ettikten sonra testleri/linter'ları vs. çalıştırdıktan sonra gelir, mesela, aklımı skiyim, bir eşittir işaretinden sonra boşluk koymayı unutmuşumdur. Bu değişikliği yapmanın başka bir yolu da, gerekli düzeltmeyle yeni bir commit oluşturup, rebase -i komutuyla ikisini birleştirmektir, ama bu yöntem nerdeyse bir milyon kat daha hızlıdır.

Uyarı: Kesinlikle public/shared branch'lara push ettiğiniz bir commit'i amend etmemelisiniz! Sadece lokalinizde bulunan bir commit'i amend etmelisiniz, aksi takdirde kötü zamanlar geçirmeye hazır olun.

Sktir ya, son commit'teki açıklamayı değiştirmem lazım!

git commit --amend
# commit açıklamasını değiştirmek için yönergeleri takip et..

Skmişim commit açıklamasının format standartlarını..

Sktir ya, Yanlışlıkla yeni bir branch açıp oraya commitlemem gereken bir şeyi, master branch'ına commitledim!

# master'ın şu anki haliyle bir branch alın
git branch some-new-branch-name
# master'dan son commit'i silin
git reset HEAD~ --hard
git checkout some-new-branch-name
# yeni commit artık bu branch'te yaşayacak :)

Not: eğer commit'i çoktan bir public/shared repo'ya push etmişseniz, ve bu çözümü uygulamadan başka şeyleri de denemişseniz, bu çalışmayacaktır, belki de HEAD~ yerine git reset HEAD@{birkaç-commit-öncesi} kullanmanız gerekebilir. Sonsuz mutsuzluk. Benim bildiğimden çok çok daha kısa olan bu yöntemi bana öneren bir çok kişi oldu. Hepsine çok teşekkürler!

Hassktir, yanlışlıkla başka branch'a commitlemişim kodu!

# son commit'i geri al, ama değişiklikler kalsın
git reset HEAD~ --soft
git stash
# doğru branch'i seç
git checkout name-of-the-correct-branch
git stash pop
git add . # ya da tek tek dosyaları ekle
git commit -m "buraya aciklama yaz";
# şimdi değişiklikler doğru branch'e geçti

Çoğu insan bu durum için cherry-pick komutunu da kullanabileceğimi önerdiler, o yüzden hangisi aklınıza daha yatkın geliyorsa onu kullanabilirsiniz!

git checkout dogru-branchin-adi
# master'daki son commit'i çek
git cherry-pick master
# master'dan o commit'i sil
git checkout master
git reset HEAD~ --hard

Sktir, iki saattir diff yapmaya çalışıyorum, ama sonuç vermiyor?!

Dosyaları değiştirdiğinizi biliyorsunuz, ama diff komutu size sonuç vermiyorsa, muhtemelen dosyaları add'lemişsiniz ve bu yüzden özel bir flag kullanmanız gerekecek.

git diff --staged

¯\_(ツ)_/¯ kategorisine ekleyin. (aynen, bu bir özellik, bir bug değil, ama beyin sikiyor ve ilk defa karşılaşan birisi açıkça ne yapacağını bilmiyor.)

Sktir, 5-6 commit önce kaydettiğim bir commit'i geri almam lazım!

# geri almanız gereken commit'i bulun
git log
# ok tuşlarını kullanarak geçmişte yukarı/aşağı gezinin
# commit'i bulduğunuzda, hash değerini bir yere kaydedin
git revert [kaydettiğiniz hash]
# git sizin için bunu geri alan bir commit oluşturacak
# commit açıklamasını değiştirmek için yönergeleri takip edin
# veya sadece kaydedin ve commitleyin

Öyle görünüyor ki, bir değişikliği geri almak için değişen yerleri bulup tek tek dosya içine kopyalayıp vs. uğraşmaya hiç gerek yokmuş! Eğer yanlışlıkla bir bug'a sebep olan bir kod commitlemişseniz, bu yaptığınızı tek bir seferde revertile geri alabilirsiniz.

Ayrıca, tüm bir commit'i geri almak yerine, tek tek dosyaları da geri alabilirsiniz! E tabi, gerçek git metoduna göre, her amk işleminin farklı farklı komutu var..

Sktir, bir dosyadaki değişiklikleri geri almam lazım!

# dosya değişmeden önceki bir hash'i bulun
git log
# ok tuşlarını kullanarak geçmişte aşağı/yukarı gezinin
# commit'i bulduğunuzda, ilgili hash'i bir yere kaydedin
git checkout [kaydettiğiniz hash] -- dosyanin/yolu/ve/adi
# dosyanin eski versiyonu şimdi index'inizde görünecek
git commit -m "Vay be, geri almak için kopyala yapıştıra gerek yokmuş"

Bunu ilk öğrendiğimde bu benim için MUAZZAM'dı. MUAZZAM. MU-AZ-ZAM. Ama cidden, hangi sktiğimin gezegeninde checkout -- kullanarak bir dosyanın geri alınmasının en iyi yolunun bu olduğu mantıklıdır? :shakes-fist-at-linus-torvalds:

Yeter bu kadar çektiğim, bırakıyorum.

cd ..
sudo rm -r sikik-git-repo-klasoru
git clone https://some.github.url/sikik-git-repo-klasoru.git
cd sikik-git-repo-klasoru

Eric V.'ye bu örnek için teşekkürer. Bu şaka içerisindeki sudo kullanımı ile ilgili tüm şikayetleri ona yöneltebilirsiniz.

Ama gerçekten, eğer local branch'iniz gerçekten sikilmişse, ve durumu remote repo'daki son haline "git-onaylı" bir şekilde geri döndürmek istiyorsanız, bunu kullanın, ama dikkat edin, bu işlem yıkıcı ve geri dönüşü olmayan işlemlerdendir!

# origin'in son halini alın
git fetch origin
git checkout master
git reset --hard origin/master
# değişiklik yaptığınız commit bekleyen tüm dosya/klasörleri geri alın
git clean -d --force
# her sikik branch için bunu tekrarlayın

*Sorumluluk reddi: Bu sitenin teferruatlı bir kaynak olma gibi bir amacı yoktur. Ve haklısınız, burada yazılan çözümleri gerçekleştirmenin daha saf teorik veya her neyse, başka yöntemleri de var, ama ben bu çözümlere deneme yanılma yoluyla, bolca küfrederek ve masa/sandalyeyi sağa sola fırlatarak ulaştım, ve bunları sağlıklı bir dozda alçakgönüllülük ve küfürle paylaşmak gibi çılgınca bir fikre kapıldım. İster alın, istemezseniz bırakın gidin.

Bu siteyi yeni dillere çevirmek için gönüllü olan herkese çok çok teşekkürler, harikasınız! Björn Söderqvist (sv) · Moritz Stückler (de) · Daniil Golubev (ru) · Łukasz Wójcik (pl) · fedemcmac (it) · Michel (fr) · Andriy Sultanov (ua) · Meiko Hori (ja) · Alex Tzimas (gr) · Martijn ten Heuvel (nl) · Elad Leev (he) · Franco Fantini (es) · Catalina Focsa (ro) · Davi Alexandre (pt_BR) · Nemanja Vasić (sr) · Tao Jiayuan (zh) · Eduard Tomek (cs) · Ricky Gultom (id) · Khaja Md Sher E Alam (bn) · Rahul Dahal (ne) · Taha Paksu (tr) · Kitt Tientanopajai (th) · Gyeongjae Choi (ko) . Ayrıca Iain Murray · Frank Taillandier · David Fyffe · Lucas Larson · Artem Vorotnikov 'ın yardımlarıyla.

Eğer siz de yardımcı olup kendi dilinize çevirmek isterseniz, GitHub repo'suna bir PR isteği gönderin.