Kayıttaki bir dosyadaki değişiklikleri geri alma


Yanıtlar:


222

Bunu yapmanın en temiz yolu burada anlatılıyor

git show some_commit_sha1 -- some_file.c | git apply -R

VonC'nin yanıtına benzer ancak git showve kullanılıyor git apply.


10
Güzel yapılmış. Komut dosyası çözümü bunun için gereğinden fazla. Neden sadece git revert sha-1 dosya adı olamıyor?
— Mark Edington

16
Bu, fatal: unrecognized input
— Mac'imde

1
@MerhawiFissehaye: Bence git checkout, commit'de olanı duruma geri döndürmek için değişiklikleri tekrar geri döndürecektir. 'Git add dosya adı yaptım; git commit --amend 'dosyayı commit'den kaldırmak için.
— ViFI

3
Sadece bir ipucu, -3yama başarısız olduğunda üç yollu birleştirme için neredeyse her zaman bayrağını git uygulamasına eklemem gerekiyor, çünkü genellikle zamanında bir değişikliği biraz düzeltiyorum.
— angularsen

2
Belki çoğu kişi için açıktır, ancak varsa dosyanın yolunusome_file.c içerdiğinden emin olun , aksi takdirde hiçbir şeyi sessizce
— yamamazsınız

35

Kaydetme geçmişini değiştirmenin uygun olduğunu varsayarsak, işte önceki bir kaydetmede tek bir dosyadaki değişiklikleri geri almak için bir iş akışı:

Örneğin, badfile.txtkaydetmede 1 dosyadaki ( ) değişiklikleri geri almak istiyorsunuz aaa222:

aaa333 Good commit
aaa222 Problem commit containing badfile.txt
aaa111 Base commit

Temel taahhütte yeniden ödeme yapın, sorun taahhüdünü değiştirin ve devam edin.

1) Etkileşimli yeniden tabanı başlatın:

git rebase -i aaa111

2) sorunu işaretleyin değiştirerek editörü düzenlemek için taahhüt picketmek e(düzenlemek için):

e aaa222
pick aaa333

3) Bozuk dosyadaki değişiklikleri geri alın:

git show -- badfile.txt | git apply -R

4) Değişiklikleri ekleyin ve taahhüdü değiştirin:

git add badfile.txt
git commit --amend

5) Rebase'i tamamlayın:

git rebase --continue

Bunun git geçmişini düzenleyebileceğinizi varsaydığını belirtmek isterim. Yukarıdaki bazı yanıtlar, her zaman mümkün / izin verilmeyen, geçmişi düzenlemeden belirli değişikliği tersine çeviren yeni bir kesinleştirme oluşturur.
— angularsen

Fantastik. Bu tam olarak aradığım şeydi. Bu fikre zaten sahiptim, ancak etkileşimli yeniden tabanlama yaparken dosyaların editdeğişmiş olarak gösterilmediği konusunda kafam karıştı . Ama git show -- badfile.txt | git apply -Rihtiyacım olan cevabı verdi <3
— mraxus

bunu anlarsam, apply -R o dosyadaki commit'i kaldırıp onu orijinal değiştirilmiş durumuna geri döndürür mü?
— DaImTo

19

git revert bir kaydetme içindeki tüm dosya içeriği içindir.

Tek bir dosya için komut dosyasını yazabilirsiniz :

#!/bin/bash

function output_help {
    echo "usage: git-revert-single-file <sha1> <file>"
}

sha1=$1
file=$2

if [[ $sha1 ]]; then
git diff $sha1..$sha1^ -- $file | patch -p1
else
output_help
fi

( Smtlaissezfaire'den git-shell-scripts yardımcı programlarından )


Not:

Mevcut değişikliğinizi henüz yapmadıysanız burada başka bir yol açıklanmaktadır .

git checkout -- filename

git checkout bir dosya için bazı seçeneklere sahiptir, dosyayı HEAD'den değiştirerek, değişikliğinizin üzerine yazabilirsiniz.


Dropped.on.Caprica bahseder yorumlarda :

Git'e bir takma ad ekleyebilirsiniz, böylece git revert-file <hash> <file-loc>belirli bir dosyanın geri alınmasını sağlayabilirsiniz . Bu özü
görün .

[alias]
  revert-file = !sh /home/some-user/git-file-revert.sh

Sadece buradaki tartışmaya eklemek için git'e bir takma ad ekleyebilirsiniz, böylece git revert-file <hash> <file-loc>bu belirli dosyanın geri alınmasını sağlayabilirsiniz . Bu cevabı kaldırdım (doğru çalışması için birkaç düzenleme yapmam gerekse de). .gitconfigDüzenlediğim betiğimin
— AlbertEngelB

@ Dropped.on.Caprica iyi bir nokta. Daha fazla görünürlük için cevaba ekledim.
— VonC

12

Sadece bu --no-commitseçeneği kullanırdım git-revertve sonra endeksten geri alınmasını istemediğiniz dosyaları nihayet taahhüt etmeden önce kaldırırdım. Aşağıda, en son ikinci işlemede yalnızca foo.c'ye yapılan değişikliklerin nasıl kolayca geri döndürüleceğini gösteren bir örnek verilmiştir:

$ git revert --no-commit HEAD~1
$ git reset HEAD
$ git add foo.c
$ git commit -m "Reverting recent change to foo.c"
$ git reset --hard HEAD

İlki git-resettüm dosyaları "aşamaları kaldırır", böylece daha sonra geri alınmasını istediğimiz tek dosyayı geri ekleyebiliriz. Son git-reset --hardkalan dosyadan, saklamak istemediğimiz geri dönüşlerden kurtulur.


9

Çok daha basit:

git reset HEAD^ path/to/file/to/revert

sonra

git commit --amend   

ve sonra

git push -f

dosya gitti ve işlem hash, mesaj vb. aynı.


Tamlık için bir git checkout -- path/to/file/to/revertadıma ihtiyacınız var mı? Ayrıca, hash'in daha sonra aynı olduğu doğru değil, değil mi? Son cümle şu gibi bir şey olarak daha iyi olabilir: "Sonuç, son işlemin, yalnızca geri alınan dosyadaki değişiklikleri içermemesi bakımından farklılık gösteren yeni bir kayıtla değiştirilmesidir."
— Kevin

@Kevin muhtemelen haklısın. Bu son satırı iki kez kontrol etmem gerekecek, ancak buna birkaç yıl önce dönüp baktığımda commit hash'in değişmemesi beni şaşırtacak.
— Forrest

6
git reset HEAD^ path/to/file/to/revert/in/commit

Yukarıdaki komut dosyayı kesinleştirme dışında alacak, ancak içeriye yansıtacaktır git status.

git checkout path/to/file/to/revert/in/commit

Yukarıdaki komut değişiklikleri geri alır (sonuç olarak HEAD ile aynı dosyayı alırsınız).

git commit

(Taahhüdü --amenddeğiştirmek için geçin.)

git push

Bununla, önceden kaydetmede bulunan dosya kaldırılır ve geri döndürülür.

Yukarıdaki adımlar, commit yapılan şubeden takip edilmelidir.


5

Bu prosedürü takip edebilirsiniz:

  1. git revert -n <*commit*>( -ntüm değişiklikleri geri alın, ancak bunları uygulamayın)
  2. git add <*filename*> (geri döndürmek ve uygulamak istediğiniz dosyaların adı)
  3. git commit -m 'reverted message' (geri almak için bir mesaj ekleyin)
  4. taahhüt ettikten sonra diğer dosya değişikliklerini atın, böylece dosyalar geri dönmeden önce yaptığınız değişikliklerle güncel kalır

1

Bir dosyadaki değişiklikleri son kaydetmenizden sıfırlamak isterseniz, genellikle kullandığım şey budur. Bunun en basit çözüm olduğunu düşünüyorum.

Lütfen dosyanın hazırlık alanına ekleneceğini unutmayın.

git checkout <prev_commit_hash> -- <path_to_your_file>

Umarım yardımcı olur :)

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.