git selective bir dosyadan yerel değişiklikleri geri alma


149

Bir svn repo izleyen benim git repo tek bir dosyada bir dizi düzenleme yaptık.

Şimdi bu değişiklikleri geri almak istiyorum (svn revert gibi), ancak dosyanın yalnızca bir kısmı.

Dosyadaki diffs'leri görüntülemek, istemediğim değişiklikleri atmak (geri almak) ve istediğim değişiklikleri korumak istiyorum.

git add -i 

komutunun bunu yapmak için bir seçeneği var gibi görünüyor ama bunu henüz sahneye koymak istemiyorum.

Yanıtlar:


91

Bunu doğrudan ile yapabilirsiniz git checkout -p. Bkz Daniel Stutzbach cevabını aşağıda.


Eski cevap (daha önce checkout -ptanıtıldı):

Bunu şu şekilde yapabilirsiniz:

git add -i

(saklamak istediğiniz yakışıklıları seçin)

git commit -m "tmp"

Şimdi sadece tutmak istediğiniz değişikliklerle bir taahhüdünüz var ve geri kalanı da değişmemiş.

git reset --hard HEAD

Bu noktada, taahhüt edilmemiş değişiklikler atıldı, bu nedenle temiz bir çalışma dizininiz var ve değişiklikleri üstte tutmak istediğiniz değişiklikler var.

git reset --mixed HEAD^

Bu, son taahhüdü ('tmp') kaldırır, ancak çalışma dizininizdeki değişiklikleri etiketsiz tutar.

EDIT: hazırlama alanını temizlemek için, --softile değiştirilir --mixed.


bu, saklamak istediğim değişiklikleri yapacaktır değil mi? Bu değişiklikleri henüz yapmak istemiyorum. mm taahhütleri çok ciddiye alıyorum. Belki de yerel bir repo olduğu için şimdi rahatlamalıyım. btw git reset --soft HEAD ^ ne yapar?
Pradeep

"git reset --soft HEAD ^", çalışma dizinini ve dizinini olduğu gibi tutması ve geçerli dalı bir taahhüt geri taşır.
Jakub Narębski

Teşekkürler Jakub. Paolo neden kafasına yumuşak bir sıfırlama gerekiyor? kısmi taahhüt ve kesin sıfırlama yeterli olmalı, bazı değişiklikleri tutmak ve diğerlerini atmak değil mi?
Pradeep

1
Daniel'in aşağıdaki cevabı çok basit ve bunu yapmanın doğru yolu gibi görünüyor.
Umang

309

Bunu en basit şekilde yapabileceğinize inanıyorum:

git checkout -p <optional filename(s)>

Manpage'den:

   −p, −−patch
       Interactively select hunks in the difference between the <tree−ish>
       (or the index, if unspecified) and the working tree. The chosen
       hunks are then applied in reverse to the working tree (and if a
       <tree−ish> was specified, the index).
       This means that you can use git checkout −p to selectively discard
       edits from your current working tree.

1
Ayrıca, bunu seçici bir şekilde yapmak istemiyorsanız, değişiklikleri silmek için "git checkout - <file> ..." kullanabilirsiniz.
db42

Dizinlerle ilgileniyor mu?
bbum

1
Değişiklikler silinirken bu benim için çok başarısız görünüyor ("hata: yama başarısız <dosya>", "hata: <dosya> yama geçerli değil"). Garip abir şekilde, tüm dosyayı silmek için yama modunda seçeneği kullanırken bu hataları alacağım , ancak git checkout -- <file>beklendiği gibi çalışıyor. Nedenini bilen var mı?
chrnola

Dosya zaten eklenmiş olsaydı birkaç kez bu hatayı aldım ve bu nedenle etkileşimli yama geçerli dosyanın uygulanan yamaları ile güncel değildi. Bir hunk'ı yanlışlıkla iki kez atarsam, kaynak ağacı gibi bir gui aracı kullanılırken oldu. İkinci kez bu hatayı üretir.
phyatt

3

Sen çalıştırabilir git diffçıkan fark tasarruf, düzenleme bu değişiklikleri kaldırmak için, dosya üzerinde yapmak yoluyla, ardından kaydetmek istediğiniz çalıştırmak patch -Rkalan diffs geri almak.

git diff file.txt> patch.tmp
# düzenlemek patch.tmp tutmak istediğiniz iri parça kaldırmak için
yama -R <yama.tmp

Yama dosyamda 2 iri parça vardı ve birini kaldırdım. Nedeni ne olduğundan emin değilim ama -R yaması bununla reddediliyor.
Pradeep

2
git diffTüm dosyayı değiştirilmiş olarak gösteren başka bir yorumda bahsediyorsunuz . Bu genellikle dosyayı daha önce olduğundan farklı satır sonları kullanarak kaydettiğinizde olur. Bu patch, yama dosyasının reddedilmesine de neden olur . Bu ne olmuş gibi görünüyor?
Greg Hewgill

Haklısın. yama komutunu her kullandığımda satır sonları değişiyor. Pencerelerde ve krem ​​/ vim kullanıyorum. Sanırım önce bunu halletmek gerekiyor.
Pradeep

Windows'ta düzeltme eki ile ilgili sorunu çözemedim. Bu işe yaradığından emin olmama rağmen Paolo'nun tarifini kullanmayı tercih ediyorum. Bu interaktif komutların sevgisi için git add -i kullanarak diffs ile çalışmak.
Pradeep

3

İstediğiniz gibi görünüyor

 git revert --no-commit $REVSISON 

Sonra kullanabilirsiniz

 git diff --cached

Taahhüt yapmadan önce hangi değişikliğin yapılacağını görmek için (geri döndürme, yalnızca geçmişte bir değişikliğin tersini kopyalayan ileriye doğru bir taahhüttür)

Saf bir Git deposuyla olsaydınız, hedeflerinize bağlı olarak, git rebase -ibeğenmediğiniz taahhüdüne geri dönmek ve taahhüdü geriye dönük olarak düzenlemek için muhtemelen hedeflemelerinizi düzenlemeyin, böylece beğenmediğiniz değişiklikler asla gerçekleşmezdi. , ancak bu genellikle yalnızca BİLİYORSANIZ bunu bir daha görmek istemeyeceğiniz içindir.


Bir önceki revizyona (bu doğru mu?) Bahsettiğiniz gibi geri döndüm ve şimdi git diff sadece tüm dosyayı değiştirilmiş olarak gösterir. Yaptığım düzenlemeleri göstermesi gerekiyor mu?
Pradeep

1

Soruyu yeniden okuduğunuzda, daha önce yapılmış olan değişiklikleri değil, çalışma ağacınızdaki değişiklikleri geri almak istediğiniz gibi görünüyor, ancak diğer cevapların bazıları, okumam yanlış gibi görünebilir. Açıklayabilir misin?

Değişiklikler yalnızca çalışma kopyanızdaysa, bunu yapmanın en kolay yolu, tutmak istediğiniz değişiklikleri düzenlemektir:

git add -i <file>

Ardından, dizin sürümünü kontrol ederek saklamak istemediğiniz değişiklikleri atın:

git checkout -- <file>

Ardından, henüz sahnelenmesini istemiyorsanız değişiklikleri iptal edin:

git reset -- <file>

Bu tarif yalnızca seçilen değişiklikleri dosyaya (veya belirttiğiniz dosyalara) döndürür ve daha sonra geri döndürülmesi gereken geçici bir taahhüt oluşturmaz.

Önceki işlemlerde yapılan değişikliklerin yalnızca bir kısmını seçmeli olarak uygulamak istiyorsanız, önce bir dosyayı daha önce kaydedilmiş bir duruma sıfırlayabilirsiniz:

git reset <commit_before_first_unwanted_change> -- <file>

Ardından git add -i <file>, tutmak istediğiniz git checkout -- <file>değişiklikleri düzenlemek, istenmeyen değişiklikleri atmak ve değişiklikleri git reset -- <file>'bozmak' için önceki tarifi takip edebilirsiniz .


0

Burada yanıtlarda açıklanan komut satırı seçenekleri, dosya bir ssh terminali üzerinden eriştiğim bir sunucudayken kullanışlıdır. Ancak, dosya yerel makinemde olduğunda aşağıdaki yolu tercih ederim:

Dosyayı netbeans düzenleyicisinde açın (git desteği ile birlikte gelir). Netbeans, öğelerin nerede silindiğini / eklendiğini / değiştirildiğini (sırasıyla) göstermek için satır numaralarına kırmızı / yeşil / mavi işaretler koyar.

Bu işaretlerden herhangi birine sağ tıklamak size bu değişikliği geri alma seçeneği sunar. Ayrıca, eski sürümü bir açılır pencerede görmek için kırmızı ve mavi işaretlere sağ tıklayabilirsiniz.

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.