silinmiş dosyanın geçmişini inceleme


160

Subversion'da bir dosyayı silersem, geçmişine ve içeriğine nasıl bakabilirim? Varolmayan bir dosyada svn catveya yapmaya çalışırsam svn log, dosyanın mevcut olmadığından şikayet eder.

Ayrıca, dosyayı yeniden canlandırmak istersem, sadece svn addgeri mi?

(Özellikle Subversion hakkında sordum, ancak aynı zamanda Bazaar, Mercurial ve Git'in bu davayı nasıl ele aldığını da duymak isterim.)

Yanıtlar:


84

Silinen bir dosyanın günlüğünü almak için şunu kullanın:

svn log -r lastrevisionthefileexisted

Dosyayı yeniden diriltmek ve sürüm geçmişini korumak istiyorsanız şunu kullanın:

svn copy url/of/file@lastrevisionthefileexisted -r lastrevisionthefileexisted path/to/workingcopy/file

Yalnızca dosya içeriğini istiyor, ancak sürüm değiştirilmemişse (örn. Hızlı inceleme için),

svn cat url/of/file@lastrevisionthefileexisted -r latrevisionthefileexisted > file

Her durumda, silinen bir dosyayı geri almak için 'svn up' kullanmayın!


2
Ayrıca, sildiğiniz revizyonun ters bir birleşimini yaparak dosyayı yeniden düzenleyebilirsiniz. Bu, SVN belgelerinde önerilen prosedürdür. "Svn up" kullanmaya gelince, "yapma" istediği gibi olmayacak "gibi bir" yapma "meselesi değildir.
rmeador

5
Yine de dosyanın tüm geçmişini nasıl görebilirim?
Benjamin Peterson

71
Basit: '-v' anahtarıyla bir üst klasörün günlüğünü göster: her giriş için değiştirilen yolların bir listesini alırsınız. Önünde 'D' olanı ve silinen dosyanızın adını bulun. Dosyanın silindiği revizyon budur.
Stefan

8
Silinen dosyalar için bu işe yaramıyor gibi görünüyor. Bunu denersem şu hata iletisini alıyorum: svn cat [url] /trunk/include/syeka/poster_funk.incl.php -r 50> out.txt svn: '/ admintools /! Svn / bc / 131 / trunk / include / syeka / poster_funk.incl.php 'yolu bulunamadı Çalışma çözümü için @Bert Huijben'in bu iş parçacığının aşağısına verdiği yanıta bakın.
Keith Palmer Jr.8

2
100.000 taahhüt içeren bir repo'm varsa, "lastrevisionthefileexisted" bulmak kolay değildir!
Jon Watte

151

Eski dosyalara bakmak istediğinizde aralarındaki farkı gerçekten bilmelisiniz:

svn cat http://server/svn/project/file -r 1234

ve

svn cat http://server/svn/project/file@1234

Olduğu yolda ilk sürümü görünüyor artık olarak mevcut http: // sunucu / svn / proje / dosya ve alır bu dosya (bu sözdizimi yapar Yani revizyon 1234 yılında olduğu gibi değil silme bir dosyaya sonra işi).

İkinci sözdizimi , revizyon 1234'te http: // server / svn / project / file olarak bulunan dosyayı alır . Bu sözdizimi , silinen dosyalar üzerinde çalışır.

Bu yöntemleri, 2345 revizyonunda bulunan bir dosyayı http: // server / svn / project / file olarak ancak 1234'teki içeriklerle birlikte almak için birleştirebilirsiniz:

svn cat http://server/svn/project/file@2345 -r 1234

7
Gah, teşekkürler! Bu konudaki mevcut en iyi yanıt bundan bahsetmiyor, bu harika!
Keith Palmer Jr.8

Ben mutlak yolları kullanılan sürece benim yerel istemcileri bu yapamaz gidermek için bir hata veriyordu çünkü bu hala benim için başarısız dizini mevcut değildi. Bu, SVN'nin daha yeni sürümleri için bir sorun olmayabilir. ./local/file./local
Derrick Rice

2
@DerrickRice: Bu durumda, ^gösterim kullanışlı olur: depo kökü anlamına gelir, böylece söyleyebilirsiniz svn cat ^/local/file@REV(depo kökü ve URL arasındaki mesafeye bağlı olarak).
musiphil

Bu prensipte harika çalışıyor. Klasörler için aşağıdakileri alıyorum:svn: E200009: Could not cat all targets because some targets are directories
Barney

Bu en iyi cevap. En yüksek oyu da alır.
Felipe Alvarez

94

İlk olarak, dosyanın silindiği düzeltme numarasını bulun:

svn log -v > log.txt

Sonra bir satır için log.txt (bir SVN guru değil, bu yüzden daha iyi bir yol bilmiyorum) bakın

D <deleted file>

ve hangi revizyon olduğunu görün. Ardından, diğer yanıtlarda olduğu gibi, önceki düzeltmeyi kullanarak dosyayı yeniden gönderin.


22
svn günlüğü -v | grep D "file.name"
abatishchev

18
Soruyu doğru cevaplayan ilk kişi olduğu için +1. Düzeltmeyi silinmeden önce bilmiyorsanız, içeriğe bakamazsınız.
Cerin

8
@abatishchev, silinen dosyaların listesini alır, ancak düzeltme bilgilerini atar, bu nedenle yararlı değildir. Ayrıca, çok fazla değişiklik geçmişine sahip büyük / eski bir havuzla çalışıyorsanız yavaştır.
Tchen

4
@ Abatishchev'in gelişimi ile iyi, harika. tchen: grep için -B50 ya da benzeri bir argüman kullanılarak kolayca düzeltildi, cevabımı görün.
Jonas Byström

2
Çok büyük / eski depolar için svn log -v çıktısını sınırlamanın başka bir iyi yolu -l seçeneğidir. Böylece svn log -v -l 100 kullanabilirsiniz | grep D "file.name"
mindmatters

27

Git'te özellikle özel bir şey yok. Dosyanın adını biliyorsanız, günlükle kaldıran değişikliği öğrenebilirsiniz:

git log -n 1 -- filename

Ardından, dosyayı silmeden önce olduğu gibi almak için bu taahhüdü kullanabilirsiniz.

git checkout [last_revision]^ filename

Misal:

dhcp-120:/tmp/slosh 587% ls -l slosh.tac
ls: slosh.tac: No such file or directory
dhcp-120:/tmp/slosh 588% git log -n 1 -- slosh.tac
commit 8d4a1f1a94e4aa37c1cb9d329a140d08eec1b587
Author: Dustin Sallings <dustin@spy.net>
Date:   Mon Dec 15 11:25:00 2008 -0800

    Get rid of a .conf and replace it with .tac.
dhcp-120:/tmp/slosh 589% git checkout 8d4a1f^ slosh.tac
dhcp-120:/tmp/slosh 590% ll slosh.tac
-rw-------  1 dustin  wheel  822 Dec 30 12:52 slosh.tac

Bunun dosyayı revizyon denetimine geri koymadığını unutmayın. Dosyayı son durumunda olduğu gibi geçerli konuma bırakır. Daha sonra ekleyebilir veya sadece ya da o noktadan herhangi birini inceleyebilirsiniz.


6
Harika cevap. Tek sorun, sorunun svn ile ilgili olmasıdır!
JohnK

16

Yalnızca GUI kullanan bir çözüm:

Dosyanın adını biliyorsanız, ancak son düzeltme numarasını veya hatta yolunu bilmiyorsanız :

  1. Repo Tarayıcıdan kökte bir "Günlüğü göster"
  2. "Tümünü Göster" i tıklayın (günlük iletişim kutusunun altında)
  3. Filtre metin kutusuna dosya adını yazın (günlük iletişim kutusunun üstünde)

Bu daha sonra yalnızca dosyanın eklendiği / değiştirildiği / silindiği düzeltmeleri gösterir. Bu, dosya geçmişiniz.

Dosya üst klasörlerinden biri silinerek silinmişse, günlükte 'silinmiş' bir girişin olmayacağını (ve mjy'nin çözümünün çalışmayacağını) unutmayın. Bu durumda, filtrelenmiş günlükteki en son girişi, silinme sırasındaki içeriğine karşılık gelir.


Kaba kuvvet her zaman bir bok değildir. Özellikle büyük depolarda değil.
Jonas Byström

Yalnızca kullanıcı arayüzü çözümü için +1. Komut satırı harika ve hepsi, ama istisnasız her zaman en iyi cevap değil. Özellikle bir ortamda çalışırken kontrol etmiyorsunuz ve SVN'ye komut satırına kolay erişiminiz yok.
Mir

Yukarıdaki yanıtın TortoiseSVN GUI için verildiğini lütfen unutmayın.
Georg Muehlenberg

13
svn log -v | grep -B50 YourDeletedFileName

Size yol ve düzeltme getirecek. Git'te (ayrıca yeniden adlandırmaları kontrol eder):

git log --diff-filter=DR --name-only | grep -B50 YourDeletedFileName

-B50 ne yapar? Svn log ve grep kullanarak buradaki ipuçlarını kullanarak dosyaların listesini alabilirim, ancak revizyon numaralarını farklı bir satırda görüntülendikleri gibi kolayca gösteremiyorum. B50 şeyi denedim ve bu benim için inanılmaz işe yaramadı.
cedd

Başka birisinin bunu okuması durumunda, matematik çizgisini ve 50 çizgiyi çıkarır.
cedd

8

Dustin'in cevabına ek olarak, sadece içeriği incelemek ve kontrol etmek istemiyorsanız, örneğinde şunları yapabilirsiniz:

$ git show 8d4a1f^:slosh.tac

the: bir revizyonu ve o revizyondaki bir yolu ayırır ve etkili bir şekilde belirli bir revizyonda belirli bir yol ister.


Ah, çok doğru. Bunu gerçekten çok zor bir şekilde yapardım. :)
Dustin

8

Bu komutu kullanın:

svn log -v | awk '/^r[0-9]+/ { rev = $1; }; / D .*filename_escaped_for_regex/ { print rev" "$2; };'

Bu, kalıpla eşleşen tüm dosyaları silen tüm düzeltmeleri listeler. Yani, README dosyasını arıyorsanız, o zaman tüm/src/README , /src/README.firstve /some/deeply/hidden/directory/READMENOTbulundu ve listelenir.

Dosya adınız eğik çizgiler (yol), noktalar veya diğer özel normal ifade karakterleri içeriyorsa, uyumsuzluk veya hatalardan kaçınmak için bunlardan kaçmayı unutmayın.


7

Silinen dosyanın yolunu bilmiyorsanız , aksi takdirde çok ağır komutta arayabilirsinizsvn log :

svn log --search <deleted_file_or_pattern> -v

Komut muhtemelen sunucuyu arama seçeneği olmadan olduğu gibi dövüyor, ancak en azından ilgili kaynaklar (göz küreleriniz dahil) geri kalanı rahatlatılır, çünkü bu dosyanın hangi revizyonda silindiğini söyleyecektir. Ardından, diğer ipuçlarını takip edebilirsiniz (çoğunlukla aynı svn logkomutu kullanarak , ancak zaten tanımlanmış bir yolda).


svn log --search _test2.php -v... svn: geçersiz seçenek: --arama ... :(
thinsoldier

5

Poster aslında 3 soru sordu:

  1. Subversion'da silinen bir dosyanın geçmişine nasıl bakarım?
  2. Subversion'da silinen bir dosyanın içeriğine nasıl bakarım?
  3. Subversion'da silinen bir dosyayı nasıl yeniden canlandırabilirim?

Burada gördüğüm tüm cevaplar 2. ve 3. sorular içindir.

1. soruya verilen cevap:

svn log http://server/svn/project/file@1234

Dosyanın en son ne zaman mevcut olduğu için düzeltme numarasını almanız gerekir; bu, burada başkaları tarafından açıkça yanıtlanır.


4

Ah, çarşıyı kullanmayı öğrendiğim için denediğim bir şey. Başarılı olmazsa, kaldırılan dosyaları günlüğe kaydedemez ve ek açıklama ekleyemezsiniz şu anda ekleyemezsiniz ... :-(

Denenmiş:

> bzr log -r 3 Stuff/ErrorParser.hta
bzr: ERROR: Path does not have any revision history: Stuff/ErrorParser.hta

ama merakla (ve neyse ki) yapabilirim:

> bzr cat -r 3 Stuff/ErrorParser.hta

ve:

> bzr diff -r 2..3 Stuff/ErrorParser.hta

ve yukarıdaki hatada önerildiği gibi:

> bzr log -v | grep -B 1 ErrorParser

(ayarlayın -B( --before-contextgerektiğinde) parametresi).


1

Bir düzeltme belirtmeniz gerekir.

svn log -r <revision> <deleted file>

1
Bu bir hata verir. Örnek: svn log -r 37428 svn.example.com/deletedfile.java svn: '/!svn/bc/98571/deletedfile.java' yolu bulunamadı
Jeremy

Bu revizyonda var olduğundan emin misiniz? Dosyanın gerçekte var olduğu bir revizyon belirtmelisiniz.
Jack

-R37428 arasındaki garip farklılık ve SVN URL'sine @ 37428 eklenmesi için Bert Huijben'in cevabına bakın.
dubek

1

Yeniden adlandırılmadan önce bir dosyanın geçmişine bakmak istiyorsanız, burada bir yorumda belirtildiği gibi kullanabilirsiniz

git log --follow -- current_file_name

1

Bir cevap istedim, kendim. Yalnızca siler çıktısını almak için aşağıdakileri deneyin svn log.

svn log --stop-on-copy --verbose [--limit <limit>] <repo Url> | \
awk '{ if ($0 ~ /^r[0-9]+/) rev = $0 }
  { if ($0 ~ /^ D /) { if (rev != "") { print rev; rev = "" }; print $0 } }'

Bu, günlük çıktısını awk aracılığıyla filtreler . awk bulduğu her bir düzeltme satırını arabelleğe alır ve yalnızca silme kaydı bulunduğunda çıktı verir. Her revizyon yalnızca bir kez çıkarılır, bu nedenle bir revizyondaki birden fazla silme birlikte gruplanır (standartta olduğu gibi)svn log çıktıda olduğu gibi).

--limitDöndürülen kayıt miktarını azaltmak için bir belirtebilirsiniz . Ayrıca--stop-on-copy , gerektiği gibi .

Tüm günlüğü ayrıştırma etkinliği konusunda şikayetler olduğunu biliyorum. Ben bu grep ve onun "geniş bir net döküm" -Bseçeneği daha iyi bir çözüm olduğunu düşünüyorum . Daha verimli olup olmadığını bilmiyorum, ama bir alternatif düşünemiyorum svn log. @Alexander Amelkin'in cevabına benzer, ancak belirli bir isme ihtiyaç duymaz. Ayrıca benim ilk awk senaryom, bu yüzden alışılmadık olabilir.


1

Dosyanızın ~ / src / a / b / c / deleted.file olarak adlandırıldığını varsayın.

cd ~/src/a/b/c  # to the directory where you do the svn rm or svn mv command
#cd ~/src   # if you forget the correct directory, just to the root of repository
svn log -v | grep -w -B 9 deleted.file | head  # head show first 10 lines

örnek çıktı, r90440 bulundu

...
r90440 | user | 2017-02-03 11:55:09 +0800 (Fri, 03 Feb 2017) | 4 lines
Changed paths:
  M /src/a/b/c/foo
  M /src/a/b/c/bar
  D /src/a/b/c/deleted.file

önceki sürüme kopyala (90439 = 90440-1)

svn cp URL_of_deleted.file@90439 .

0

İkili aramayı kullanarak dosyayı sağlayan son düzeltmeyi bulabilirsiniz. Bunun için basit bir /bin/bashkomut dosyası oluşturdum :

function svnFindLast(){
 # The URL of the file to be found
 local URL="$1"
 # The SVN revision number which the file appears in (any rev where the file DOES exist)
 local r="$2"
 local R
 for i in $(seq 1 "${#URL}")
  do
   echo "checkingURL:'${URL:0:$i}'" >&2
   R="$(svn info --show-item revision "${URL:0:$i}" 2>/dev/null)"
   echo "R=$R" >&2
   [ -z "$R" ] || break
 done
 [ "$R" ] || {
  echo "It seems '$URL' is not in a valid SVN repository!" >&2
  return -1
 }
 while [ "$r" -ne "$R" -a "$(($r + 1))" -ne "$R" ]
 do
  T="$(($(($R + $r)) / 2))"
  if svn log "${URL}@${T}" >/dev/null 2>&1
   then
    r="$T"
    echo "r=$r" >&2
   else
    R="$T"
    echo "R=$R" >&2
  fi
 done
 echo "$r"
}

-1

Tüm depolarımın svn günlüğünü bir mysql veritabanına kopyalayan bir php betiği yazdım. Şimdi yorumlarımda veya dosya adlarında tam metin aramaları yapabilirim.

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.