Git pull'i her çekişte her şeyin üzerine yazmaya nasıl zorlarım?


203

Normalde çeken ve iten üç geliştirici deposuna sahip bir MERKEZ çıplak havuz var.

Ayrıca CENTRAL bare repo çeken diğer iki havuz var: biri canlı sunucu, diğeri test / sahne sunucusu - her biri kendi ilgili şubesinden çekiyor.

Senaryo şudur: post-updateTest ve canlı depolara otomatik olarak erişen ve her birinde bir çekme komutu çalıştıran CENTRAL repo'da bir kanca komut dosyası var . Bu, hangi şubenin yeni taahhütlere sahip olduğuna bağlı olarak hem test hem de canlı sunucuları günceller. Tüm bunlar harika çalışıyor.

Sorun şudur: Acil durumlarda dosyaların sunucuda doğrudan güncellenebileceği (ftp veya herhangi bir yöntemle) zamanlar olabilir ve birleştirme / üzerine yazma çakışmaları olacağından, CENTRAL güncelleme sonrası komut dosyası başarısız olur. Bu senaryodan kaçınmanın bir yolu yoktur ve kaçınılmazdır.

Ne olmasını istediğim şudur: Canlı ve test sitelerinden çekmenin her zaman çekilişin üzerine yazılmasını / birleştirilmesini istiyorum. Her zaman. Bu depolar, geliştirme amaçlı olmadıkları için yalnızca çekilebilir olacaktır.

Tüm araştırmalarımda, her zaman yerel dosyaların üzerine yazmaya zorlamak için iyi bir çözüm bulamıyorum . Bu mümkün mü? Eğer öyleyse büyük bir gelişme senaryosu oluşturacaktır.


1
Aşağıda 'az önce getirdiğiniz şeye sıfırlama' cevabını oylamış olsam da, gerçek probleminizin çözümünün bant dışı değişiklikler yapmamak olduğunu düşünüyorum. Ne kadar acil olursa olsun, değişiklikler her zaman sürüm kontrolünden geçmelidir . Operatörler dışında hiç kimse çalışan sitelere doğrudan erişemez (ör. Geliştiriciler değil). Sürüm kontrolünü tutarlı bir şekilde kullanmak, değişikliklerin ne zaman yapıldığını, bunları kimin yaptığını ve onlarla çalışmak için daha iyi araçları kaydettiğiniz anlamına gelir. Gerçek bir faydası olmadan neden yıkın?
Phil Miller

1
@Novelocrat doğru, ne dediğini anlıyorum. Ne yazık ki, birisinin doğrudan sunucuya dosya yükleyebileceği birkaç senaryo vardır. Bu durumda depoları yeniden eşitlemek için birkaç komut çalıştırmam gerekir. Daha önce dosyaları depodan sunucuya taşımak için bir FTP komut dosyası kullanıyorduk. Yukarıda önerilen yöntem, geçmişte çok iyi çalışan FTP adımını ortadan kaldıracaktır.
bmilesp

3
Bu nedenle, kullanıcıların sunucuya doğrudan erişmesine izin vermeyin. FTP ve SSH erişimini kilitleyin veya onlara hesap verilemez değişiklikler yapmak için tetikleneceklerini söyleyin. Bu tür pratiklerin devam etmesine izin vermek sadece uzun vadede sizi ve ekibinizi incitir.
Phil Miller

Yanıtlar:


510

Gerçekten bunu yapmanın ideal yolu hiç kullanmak değil pull, fetchve reset:

git fetch origin master
git reset --hard FETCH_HEAD
git clean -df

( masterTakip etmek istediğiniz dalı değiştirmek .)

pulldeğişikliklerin bir şekilde bir araya getirilmesi, resetbasitçe yerel kopyanızın belirli bir işlemle eşleşmesi için tasarlanmıştır.

cleanSisteminizin ihtiyaçlarına bağlı olarak biraz farklı seçenekler düşünmek isteyebilirsiniz .


3
@ user730569 reset --hard, çalışma dizininin (ve geçerli dalın) durumunu belirli bir taahhüdün durumuna uyan bir duruma zorlamak için kullanılan bir komuttur.
Amber

25
FETCH_HEADfetchgetirilen ref'yi temsil etmek için tarafından otomatik olarak oluşturulan bir referanstır . Birleştirilmiş değil, sadece bir getirme yaptığınızda doğrudan üzerine yazılıyor. cleantarafından izlenmeyen dosyaları kaldıran bir komuttur git, -dfbayraklar dizinleri ( -d) kaldırmasını ve aslında remove ( ) işlemini yapmasını söyler -f.
Amber

4
bunun için neden bir anahtar kelime yok? Buna çekmekten çok daha sık ihtiyacım var.
Wolfgang Fahl

15
Kullanmadan git clean -dnönce kullanmak isteyebilirsiniz, git clean -dfböylece hangi dosyaların / klasörlerin silineceğini göreceksiniz. git clean -dfbir yedeğiniz varsa geri alınabilir
Ibrahim Lawal

1
@NickMiddleweek git clean -dfGitignored dosyaları da kaldıracağımdan endişelendim , ancak olmayacak. git clean --help"Normalde, yalnızca Git tarafından bilinmeyen dosyalar kaldırılır, ancak -x seçeneği belirtilirse, yok sayılan dosyalar da kaldırılır. Bu, örneğin tüm yapı ürünlerini kaldırmak için yararlı olabilir."
nickang


6

Bir komutta nasıl yapılacağından emin değilim ama şöyle bir şey yapabilirsiniz:

git reset --hard
git pull

ya da

git stash
git pull

Tek bir komut çalıştırmak için: git reset --hard && git pull. Alternatif olarak, ama daha iyi değil git reset --hard; git pull. Kullanımı &&İlk komut başarılı ise sadece ikinci komutu çalıştırır. ;ilk komutun çıkış kodundan bağımsız olarak çalışacaktır.
mazunki

5

Şubenin bir kopyasını çekmek ve başlangıç ​​noktasından yerel dosyaların üzerine yazmaya zorlamak için:

git reset --hard origin/current_branch

Mevcut tüm işler kaybolacak ve daha sonra başlangıç ​​şubesiyle aynı olacak


5
git reset --hard HEAD
git fetch --all
git reset --hard origin/your_branch

2

Her şeyi temiz silmek için kancayı değiştirebilirsiniz.

# Danger! Wipes local data!

# Remove all local changes to tracked files
git reset --hard HEAD

# Remove all untracked files and directories
git clean -dfx

git pull ...

2
x ne yapar? lütfen anahtarları açıklayın
Steve K

2
X tüm izlenmemiş dosyaları kaldırmak gerekiyor, sanırım. Manpage-konuşmasında söylemek zor, bu yüzden SO var.
JosephK

2
@JosephK: Bu yanlış. Temel amacı git cleanzaten "İzlenmemiş dosyaları çalışma ağacından kaldır" (sayfanın üst kısmı). Normalde bu, yok sayılan dosyaları içermez, ancak yok sayılan dosyaları da dahil etmeyi -xsöyler git clean(ancak bu -eseçenek tarafından yok sayılan dosyaları etkilemez ).
Dietrich Epp

2

Son çekme / klondan bu yana yerel değişiklikleri henüz yapmadıysanız, şunları kullanabilirsiniz:

git checkout *
git pull

checkoutson yerel taahhüt ile yerel değişikliklerinizi temizleyecek pullve uzak depoya sincronize edecek

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.