Kurs
Bazı durumlarda, yerel bir Git dalının durumunu uzak depo ile hizalamak, böylece tüm yerel değişiklikleri atmak isteyebiliriz. Buna yaygın olarak zorla çekme denir.
Bu, bunu başarmanın yolunun git pull komutunda --force seçeneğini kullanmak olduğu yanılgısını yaratır. Bu yazıda, bunların farklı şeyler olduğunu öğreneceğiz.
Git'e yeniyseniz, önce Git push ve pull eğitimimizi okumayı düşünebilirsiniz.
Aşağıdaki komutları kullanarak, <branch_name> yerine dalınızın adını yazarak yerel durumumuzu uzak durumla üzerine yazabiliriz. Bu işlem, o dalda tüm yerel değişikliklerinizi kalıcı olarak silecektir.
git fetch
git reset --hard origin/<branch_name>
Bu makale bu komutların nasıl çalıştığına ayrıntılı olarak değinecek. Hızlı çözümlerin ötesine geçerek temel işleyişi anlayacak, böylece önemli değişiklikleri kaybetme riski olmadan istenen sonucu elde etmek için daha etkili yöntemler öğreneceğiz. Ayrıca yanlış anlamayı giderip git pull komutunun --force seçeneğinin gerçekte ne yaptığını öğreneceğiz.
Yerel Değişiklikleri Ne Zaman Ezmek Gerekir
Genel olarak, yerel değişiklikleri bu şekilde ezmek Git'in amaçlanan kullanımına aykırıdır. Neredeyse her durum için bunu çözmenin uygun bir Git iş akışı vardır. Ancak, bunların bir kısmı Git'i daha derinlemesine anlamayı gerektirir ve uygulaması daha uzun sürer. En iyi uygulama olmasa da, yerel değişiklikleri ezmek bazen işi en hızlı şekilde bitirmenin yolu olabilir.
Benim için bu genellikle çok aşina olmadığım bir özellikle çalışırken olur. Bir dal oluşturup birkaç commit yaparak başlarım. Sıkıştığımda bir meslektaşımdan yardım isterim. O, benim hatayı yapmamdan önceki bir commit'ten başlar, sorunu çözer ve değişikliklerini push eder. Bu noktada, özellikle çalışmaya devam edebilmek için yerel sürümümü, yerel değişikliklerimi atarak, güncellenmiş uzak sürümle değiştirmem gerekir.
Bir diğer örnek de bir çatışma olduğunda ve çatışmayı çözmenin, değişikliklerimizi kodun en son sürümünde yeniden uygulamaktan daha zor ya da daha zaman alıcı olduğunu düşündüğüm durumdur.
Nedeni ne olursa olsun, bu değişikliklerin gerçekten gerekli olmadığından emin olun ve güvenle silinebileceklerini doğrulayın ya da önemli çalışmaları kaybetmemek için dalınızı yedekleyin.
Yerel Değişiklikler Doğru Şekilde Nasıl Ezilir
İlk adım, uzak depodaki en son içeriği yerel makinemize fetch (indirme) etmektir. Bu, git'teki fetch komutu kullanılarak yapılır:
git fetch
Varsayılan olarak bu, genellikle ihtiyacımız olan mevcut dalın içeriğini indirir. İndirmek istediğimiz dalı isteğe bağlı olarak belirtebiliriz (aşağıda <branch_name> yerine fetch etmek istediğimiz dalın adını yazarak):
git fetch origin/<branch_name>
Alternatif olarak, her şeyi indirmek için --all seçeneğini kullanabiliriz:
git fetch –all
Uzak depodaki değişiklikleri fetch etmek, geçerli çalışma dalı dizininizdeki dosyaları etkilemez. fetch komutu, uzak depodan değişiklikleri indirir ancak bunları birleştirmez. Yerel depo hem yerel dosyaların hem de uzak dosyaların bir görünümünü tutar ve fetch işlemi uzak dosyaların görünümünü günceller.
Uzak depodan değişiklikleri indirdikten sonra, geçerli çalışma dalını belirli bir duruma sıfırlamak için git'teki reset komutunu kullanabiliriz:
git reset --hard origin/<branch_name>
--hard seçeneği, yerel değişikliklerin uzak değişikliklerle üzerine yazıldığından emin olmak için gereklidir. Yukarıdaki komutta, az önce fetch edilen o dalın uzak sürümüne karşılık gelen origin/<banch_name> ile geçerli çalışma dalını değiştirmeyi seçtik.
git reset komutu, commit edilmiş olsalar bile yerel değişiklikleri siler. Bu nedenle, bu komutu çalıştırmadan önce geçerli dalın yerel bir yedeğini oluşturmanız önerilir. Bu, şu şekilde yapılabilir:
git branch <name_of_the_backup_branck>
Burada <name_of_the_backup_branch> yerine yedek dalın taşımasını istediğiniz adı yazın.
Hepsini bir araya getirirsek, belirli bir dalın tüm yerel değişikliklerini, en güncel uzak sürümle şu şekilde ezebiliriz:
git fetch
git branch <name_of_the_backup_branch>
git reset --hard origin/<branch_name>
Git'te dallarla çalışma bilginizi genişletmek isterseniz, Belirli Bir Dalı Klonlama eğitimine göz atın.
İzlenmeyen dosyaları silerek tam temizleme
Git, izlenmeyen dosyalara (git add ile hiç eklenmemiş dosyalar) dokunmaz. Bu dosyaları da silmek istersek, şu komutla yapabiliriz:
git clean -fdx
Bu, çalışma dizininden izlenmeyen dosyaları kaldırmak için kullanılan tehlikeli bir komuttur. Bu komutu dikkatle kullanmak esastır; çünkü bu dosyaları kalıcı olarak siler ve Git üzerinden geri getirmeyi imkânsız kılar. Komut seçeneklerinin dökümü şöyledir:
-f: Temizleme işlemini zorlar. Git, yanlışlıkla veri kaybını önlemek için bu bayrak olmadan çalışma dizininden izlenmeyen dosyaları silmeyi reddeder.-d:git clean'e yalnızca izlenmeyen dosyaları değil, izlenmeyen dizinleri de kaldırmasını söyler. Varsayılan olarakgit cleanyalnızca izlenmeyen dosyaları hedefler ve dizinleri yok sayar.-x: Varsayılan olarak,git clean.gitignorekurallarına saygı duyar ve bu kalıplarla eşleşen dosya veya dizinleri kaldırmaz. -x eklemek bu davranışı geçersiz kılar ve Git'e.gitignoreveya diğer yok sayma kuralları tarafından yok sayılan dosya/dizinleri de kaldırmasını söyler. Bu, depo içindeki tüm izlenmeyen dosyaları, derleme çıktıları, günlük dosyaları ve genellikle yok sayılan diğer üretilmiş artifaktlar dâhil olmak üzere çok kapsamlı bir temizleme sağlar.
Git Pull'u Anlamak
Yerel depomuzu uzaktaki değişikliklerle güncellemenin alışıldık yolu git pull komutunu kullanmaktır. Ancak bu komut, yerel değişikliklerimizi ezmek için kullanılamaz; çünkü git pull yerel sürümümüzü uzakla birleştirmeye çalışır.
Perde arkasında, git pull şu adımları uygular:
- Uzak depodaki en son sürümü indirmek için
git fetchkullanır. - Yerel ve uzak dalları birleştirmek için
git mergekullanır.
Birleştirme adımı nedeniyle, git pull yerel değişiklikleri yok sayıp atmak istediğimiz durumlar için uygun bir komut değildir.

git pull --force peki?
git pull komutunun belgelerine baktığımızda bir --force seçeneği sunduğunu görürüz. Bu seçeneğin, yerel değişiklikleri uzaktaki değişikliklerle silerek git pull komutunu zorla çalıştıracağı yönünde yaygın bir yanlış kanı vardır.
git pull komutuna --force seçeneğini verdiğimizde, bu seçenek git fetch'e iletilir. Dolayısıyla git pull --force şu adımları uygular:
git fetch --forcegit merge

Fetch'in, uzak deponun yerel görünümünü güncellemek için kullanıldığını öğrendik. Geçerli yerel deponuz ile uzak depo arasındaki tek fark bazı eksik commit'lerse (yerel dal uzak sürümün gerisindeyse), git fetch bu yeni commit'leri geçmişe ekleyerek yerel görünümü basitçe günceller.

Ancak, birinin uzak dalın commit geçmişini yeniden yazması ve bunu yerel görünümle uyumsuz hâle getirmesi de mümkündür. Bu durumda fetch işe yaramaz.

Bunu, Git'i yerel geçmişi yok saymaya ve uzak geçmişle üzerine yazmaya zorlayan --force seçeneğini kullanarak aşabiliriz.
Görüyoruz ki --force seçeneği, commit geçmişini zorla üzerine yazmayla ilgilidir ve çalışma dalı dizinindeki yerel değişiklikleri yok saymakla ilgili değildir.
Yerel Değişiklikleri Entegre Etmek
Yerel değişiklikleri uzak değişikliklerle ezmek yaygın bir Git uygulaması değildir; ancak çatışmalarla uğraşmak istemediğimiz ya da yerel değişikliklerimizi umursamadığımız bazı durumlarda faydalı olabilir.
Birleştirme
Genelde, değişiklikler pull edilir ve çatışmalarla ilgilenilir. İnsanlar çatışmalarla uğraşmaktan çekinir. Bazı çatışmalar bunaltıcı olabilir ama bu sık görülen bir durum değildir. Bir çatışma şu durumlarda ortaya çıkar:
- Hem yerel dalda hem uzak dalda bir dosyanın aynı bölümünde değişiklik yapılmışsa.
- Bir tarafta bir dosya silinmiş, diğer tarafta değiştirilmişse.
Bu durumlarda Git hangi değişiklikleri tutmak istediğimizi tahmin edemez ve bunu kendisine elle belirtmemiz gerekir. Git, dosyalardaki çatışmayı şu şekilde vurgular:

Bir çatışmayı çözmek için, dosyayı düzenleyip bu satırları, tutmak istediklerimiz dışında sileriz. Tüm çatışmaları ele aldıktan sonra değişiklikleri commit edebiliriz. Ayrıntılı bir rehber için, Git'te birleştirme çatışmaları nasıl çözülür konulu bu eğitime göz atın.
Cherry-pick
Yerel sürümümüzü gerçekten önce uzak sürümle eşlemek ve ardından değişikliklerimizi entegre etmek istiyorsak, yedek daldaki commit'leri şu şekilde geçerli dala getirebiliriz:
git cherry-pick <commit_hash>
Burada <commit_hash>, entegre etmek istediğimiz commit'in hash'idir. Bu, git reset yapmadan önce git branch <name_of_the_backup_branck> ile bir yedek dal oluşturduğumuzu ve yerel değişikliklerin commit edildiğini varsayar.
<commit_hash>'i bulmak için, yedek dalda commit hash'lerini aşağıdaki komutla listeleyebiliriz:
git log <name_of_the_backup_branck>
Stash
Alternatif olarak, değişikliklerimizi commit etmek veya bir yedek dal oluşturmak istemiyorsak, birleştirmeden önce değişikliklerimizi şu komutla kenara (stash) alabiliriz:
git stash
Bu komut, mevcut çalışmayı dal geçmişine commit etmeden geçici olarak kaydetmek için kullanılabilir. Stash, değişikliklerinizi bir kenara koyarak temiz bir çalışma dizinine sahip olmanızı sağlar.
Resetledikten sonra, değişikliklerimizi geri getirmek için şu komutu kullanabiliriz:
git stash pop
Stash kullanıldığında, tüm iş akışı şu şekilde görünecektir:
git fetch
git stash
git reset --hard origin/<branch_name>
git stash pop
Daha fazla bilgi için, stash ve diğer git komutlarını içeren bu kısa özete göz atın.
Sonuç
En iyi uygulama olmasa da, bazen kendimizi yerel dalımızı, yerel değişiklikleri atarak, uzak dalın içeriğiyle eşlemek istediğimiz bir durumda buluruz.
Bunun git pull --force kullanılarak yapıldığına dair bir yanılgı vardır. Bu yanlıştır; çünkü git pull --force, git fetch --force ve git merge'ü birleştirir. Dolayısıyla, yerel değişiklikleri üzerine yazmak yerine, onları uzak değişikliklerle birleştirmeye çalışır.
Yerel değişiklikleri uzak deponun içeriğiyle ezmenin doğru yolu şudur:
git fetch
git reset --hard origin/<branch_name>
git reset komutu dikkatle kullanılmalıdır; çünkü commit edilmiş olsalar bile yerel değişiklikleri silecektir. Yerel commit'lerimiz vardı ve bir yedek dal oluşturduysak, onları git cherry-pick ile geri getirebiliriz. Commit etmediysek ve yerel çalışmamızı geçici olarak kaydetmek istiyorsak, resetlemeden önce git stash kullanabilir, ardından değişikliklerimizi geri getirmek için git stash pop çalıştırabiliriz.

