memeriksa riwayat file yang dihapus

160

Jika saya menghapus file di Subversion, bagaimana saya bisa melihat riwayat dan isinya? Jika saya mencoba melakukan svn catatau svn logpada file yang tidak ada, itu mengeluh bahwa file tersebut tidak ada.

Juga, jika saya ingin menghidupkan kembali file, haruskah saya svn addmengembalikannya?

(Saya bertanya secara khusus tentang Subversi, tetapi saya juga ingin mendengar tentang bagaimana Bazaar, Mercurial, dan Git menangani kasus ini juga.)

Benjamin Peterson
sumber

Jawaban:

84

Untuk mendapatkan log dari file yang dihapus, gunakan

svn log -r lastrevisionthefileexisted

Jika Anda ingin menghidupkan kembali file dan menyimpan riwayat versinya, gunakan

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

Jika Anda hanya ingin konten file tetapi tidak berversi (misalnya, untuk pemeriksaan cepat), gunakan

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

Bagaimanapun, JANGAN gunakan 'svn up' untuk mendapatkan kembali file yang dihapus!

Stefan
sumber
2
Anda juga dapat membuka kembali file dengan melakukan penggabungan terbalik dari revisi di mana Anda menghapusnya. Ini adalah prosedur yang direkomendasikan dalam dokumen SVN. Sedangkan untuk menggunakan "svn up", ini bukan masalah "jangan lakukan itu" sebagaimana "tidak akan melakukan apa yang Anda inginkan".
rmeador
5
Bagaimana saya bisa melihat seluruh riwayat file?
Benjamin Peterson
71
Sederhana: perlihatkan log untuk folder induk dengan sakelar '-v': Anda akan mendapatkan setiap entri daftar jalur yang diubah. Temukan satu dengan 'D' di depan dan nama file Anda dihapus. Itulah revisi tempat file terhapus.
Stefan
8
Tampaknya ini tidak berfungsi untuk file yang dihapus. Jika saya mencoba ini, saya mendapatkan pesan kesalahan ini: svn cat [url] /trunk/include/syeka/poster_funk.incl.php -r 50> out.txt svn: '/ admintools /! Svn / bc / 131 / trunk / sertakan / syeka / poster_funk.incl.php 'path tidak ditemukan Lihat tanggapan @Bert Huijben lebih jauh di utas ini untuk solusi yang berfungsi.
Keith Palmer Jr
2
Jika saya memiliki repo dengan 100.000 komitmen, "lastrevisionthefileexisted" tidak mudah ditemukan!
Jon Watte
151

Ketika Anda ingin melihat file-file lama Anda harus benar-benar mengetahui perbedaan antara:

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

dan

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

Versi pertama melihat path yang sekarang tersedia sebagai http: // server / svn / project / file dan mengambil file itu seperti dalam revisi 1234. (Jadi sintaks ini tidak berfungsi setelah file dihapus).

Sintaks kedua mendapatkan file yang tersedia sebagai http: // server / svn / project / file dalam revisi 1234. Jadi sintaks ini TIDAK bekerja pada file yang dihapus.

Anda bahkan dapat menggabungkan metode ini untuk mengambil file yang tersedia di revisi 2345 sebagai http: // server / svn / project / file tetapi dengan konten seperti di 1234 dengan:

svn cat http://server/svn/project/file@2345 -r 1234
Bert Huijben
sumber
7
Gah terima kasih! Respons teratas saat ini di utas ini tidak menyebutkan ini, ini hebat!
Keith Palmer Jr
Ini masih gagal untuk saya kecuali saya menggunakan jalur absolut, karena klien svn lokal saya memberikan kesalahan ketika tidak dapat menyelesaikan ./local/fileketika ./localdirektori tidak ada. Ini mungkin bukan masalah untuk versi SVN yang lebih baru.
Derrick Rice
2
@DerrickRice: Dalam hal ini, ^notasi menjadi berguna: mengacu pada akar repositori, sehingga Anda dapat mengatakan svn cat ^/local/file@REV(tergantung pada jarak antara akar repositori dan URL).
musiphil
Prinsip ini sangat bagus. Untuk folder saya menerima yang berikut:svn: E200009: Could not cat all targets because some targets are directories
Barney
Ini jawaban terbaik. Memiliki suara tertinggi juga.
Felipe Alvarez
94

Pertama, cari nomor revisi tempat file terhapus:

svn log -v > log.txt

Kemudian lihat log.txt (bukan guru SVN, jadi saya tidak tahu cara yang lebih baik) untuk baris dengan

D <deleted file>

dan lihat revisi mana itu. Kemudian, seperti pada jawaban lain, hidupkan kembali file menggunakan revisi sebelumnya.

mjy
sumber
22
svn log -v | grep D "file.name"
abatishchev
18
+1 karena menjadi orang pertama yang menjawab pertanyaan dengan benar. Anda tidak dapat melihat kontennya jika Anda tidak tahu revisi sebelum dihapus.
Cerin
8
@abatishchev ini memperoleh daftar file yang dihapus, tetapi membuang info revisi, jadi itu tidak berguna. Juga lambat jika Anda bekerja dengan repositori besar / lama dengan banyak perubahan sejarah.
tchen
4
Bagus, bagus dengan peningkatan @ abatishchev. tchen: mudah diperbaiki menggunakan argumen -B50 atau lebih untuk grep, lihat jawaban saya.
Jonas Byström
2
Cara lain yang baik untuk membatasi keluaran svn log -v untuk repositori yang sangat besar / lama adalah opsi -l. Jadi Anda bisa menggunakan svn log -v -l 100 | grep D "file.name"
mindmatters
27

Tidak ada yang istimewa di git. Jika Anda tahu nama file, Anda bisa mengetahui perubahan yang menghapusnya dengan log:

git log -n 1 -- filename

Kemudian Anda bisa menggunakan komit itu untuk mendapatkan file seperti yang ada sebelum penghapusan.

git checkout [last_revision]^ filename

Contoh:

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 <[email protected]>
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

Perhatikan bahwa ini sebenarnya tidak mengembalikan file ke kontrol revisi. Itu hanya menjatuhkan file seperti yang ada di keadaan terakhirnya ke lokasi saat ini. Anda kemudian dapat menambahkannya atau hanya memeriksanya atau apa pun dari titik itu.

Dustin
sumber
6
Jawaban yang bagus Satu-satunya masalah adalah pertanyaannya adalah tentang svn!
JohnK
16

Solusi hanya menggunakan GUI:

Jika Anda tahu nama file, tetapi tidak tahu nomor revisi terakhirnya atau bahkan jalurnya:

  1. Dari Repo Browser lakukan "Tampilkan log" pada root
  2. Tekan "Show All" (di bagian bawah dialog log)
  3. Ketikkan nama file ke dalam kotak teks Filter (di bagian atas dialog log)

Ini kemudian akan menunjukkan hanya revisi-revisi di mana file ditambahkan / dimodifikasi / dihapus. Ini adalah riwayat file Anda.

Perhatikan bahwa jika file itu dihapus dengan menghapus salah satu folder induknya, itu tidak akan memiliki entri 'dihapus' di log (dan solusi mjy tidak akan berfungsi). Dalam hal ini, entri terbaru dalam log yang difilter akan sesuai dengan kontennya saat dihapus.

Mark Foreman
sumber
Brute force tidak selalu omong kosong. Terutama pada repo besar.
Jonas Byström
+1 untuk solusi UI saja. Baris perintah memang hebat, dan semuanya, tetapi itu tidak selalu merupakan jawaban terbaik tanpa kecuali. Terutama ketika Anda bekerja di lingkungan yang tidak Anda kontrol, dan tidak memiliki akses baris perintah yang mudah ke SVN.
Mir
Harap dicatat bahwa jawaban di atas dimaksudkan untuk GUI TortoiseSVN.
Georg Muehlenberg
13
svn log -v | grep -B50 YourDeletedFileName

Akan memberi Anda jalan dan revisi. In git (juga memeriksa untuk penggantian nama):

git log --diff-filter=DR --name-only | grep -B50 YourDeletedFileName
Jonas Byström
sumber
Apa yang dilakukan -B50? Saya bisa mendapatkan daftar file menggunakan svn log dan grep cukup mudah menggunakan tips di sini, tapi saya sepertinya tidak bisa mendapatkan angka revisi ditampilkan dengan mudah, karena mereka ditampilkan pada baris yang berbeda. Saya mencoba hal B50 dan sepertinya itu tidak berhasil bagi saya.
cedd
Ini menghasilkan garis matematika dan 50 garis di atas kalau-kalau ada orang lain yang membaca ini.
cedd
8

Selain jawaban Dustin, jika Anda hanya ingin memeriksa isinya, dan tidak memeriksanya, dalam contohnya Anda dapat melakukannya:

$ git show 8d4a1f^:slosh.tac

the: memisahkan revisi dan jalur dalam revisi itu, secara efektif meminta jalur tertentu pada revisi tertentu.

Pieter
sumber
Ah, benar sekali. Dulu saya melakukannya dengan cara yang sangat, sangat sulit. :)
Dustin
8

Gunakan perintah ini:

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

Ini akan mendaftar semua revisi yang pernah menghapus file yang cocok dengan pola. Artinya, jika Anda sedang mencari file README, maka semua /src/README, /src/README.firstdan /some/deeply/hidden/directory/READMENOTakan ditemukan dan terdaftar.

Jika nama file Anda mengandung garis miring (jalur), titik, atau karakter regex khusus lainnya, jangan lupa untuk menghindarinya untuk menghindari ketidaksesuaian atau kesalahan.

Alexander Amelkin
sumber
7

Jika Anda tidak tahu jalur ke file yang dihapus, ternyata Anda dapat mencarinya di svn logperintah yang terlalu berat :

svn log --search <deleted_file_or_pattern> -v

Perintah ini mungkin memalu server seperti halnya tanpa opsi pencarian, tetapi setidaknya sisa sumber daya yang terlibat (termasuk bola mata Anda) akan agak lega, karena itu akan memberi tahu Anda di mana revisi file itu dihapus. Kemudian, Anda dapat mengikuti tips lainnya (terutama menggunakan svn logperintah yang sama , tetapi sudah di jalur yang ditentukan).

JMB
sumber
svn log --search _test2.php -v... svn: opsi tidak valid: --search ... :(
thinsoldier
5

Poster sebenarnya telah mengajukan 3 pertanyaan di sini:

  1. Bagaimana saya melihat riwayat file yang dihapus di Subversion?
  2. Bagaimana saya melihat isi file yang dihapus di Subversion?
  3. Bagaimana cara menghidupkan kembali file yang dihapus di Subversion?

Semua jawaban yang saya lihat di sini adalah untuk pertanyaan 2 dan 3.

Jawaban untuk pertanyaan 1 adalah:

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

Anda masih perlu mendapatkan nomor revisi ketika file terakhir ada, yang dijawab dengan jelas oleh orang lain di sini.

dekeguard
sumber
4

Ah, karena saya belajar menggunakan Bazaar, itu adalah sesuatu yang saya coba. Tanpa hasil, tampaknya Anda tidak dapat login dan membubuhi keterangan file yang dihapus saat ini ... :-(

Mencoba:

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

tapi anehnya (dan untungnya) saya bisa melakukan:

> bzr cat -r 3 Stuff/ErrorParser.hta

dan:

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

dan seperti yang disarankan dalam bug di atas:

> bzr log -v | grep -B 1 ErrorParser

(sesuaikan -B( --before-context) parameter sesuai kebutuhan).

PhiLho
sumber
1

Anda perlu menentukan revisi.

svn log -r <revision> <deleted file>
Jack M.
sumber
1
Ini memberikan kesalahan. Contoh: svn log -r 37428 svn.example.com/deletedfile.java svn: '/!svn/bc/98571/deletedfile.java' path tidak ditemukan
Jeremy
Apakah Anda yakin ada di revisi itu? Anda harus menentukan revisi di mana file itu sebenarnya ada.
Jack M.
Lihat jawaban oleh Bert Huijben untuk perbedaan aneh antara -r37428 dan menambahkan @ 37428 ke URL SVN.
dubek
1

Jika Anda ingin melihat riwayat file sebelum diubah namanya, maka seperti yang disebutkan dalam komentar di sini dapat Anda gunakan

git log --follow -- current_file_name
Andrew Grimm
sumber
1

Saya ingin jawaban, sendiri. Coba yang berikut untuk hanya mengeluarkan output dari 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 } }'

Ini menyaring keluaran log melalui awk . awk menyangga setiap baris revisi yang ditemukannya, mengeluarkannya hanya saat catatan penghapusan ditemukan. Setiap revisi hanya keluaran sekali, jadi banyak penghapusan dalam revisi dikelompokkan bersama (seperti dalam svn logoutput standar ).

Anda dapat menentukan a --limituntuk mengurangi jumlah catatan yang dikembalikan. Anda juga dapat menghapus --stop-on-copy, sesuai kebutuhan.

Saya tahu ada keluhan tentang efisiensi parsing seluruh log. Saya pikir ini adalah solusi yang lebih baik daripada grep dan -Bopsi "cast a wide net" . Saya tidak tahu apakah ini lebih efisien, tetapi saya tidak bisa memikirkan alternatifnya svn log. Ini mirip dengan jawaban @Alexander Amelkin, tetapi tidak perlu nama tertentu. Ini juga skrip awk pertama saya , jadi mungkin tidak konvensional.

nih tuh
sumber
1

Asumsikan file Anda bernama ~ / src / a / b / c / delete.file

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

keluaran sampel, menemukannya di r90440

...
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

salin kembali ke versi sebelumnya (90439 = 90440-1)

svn cp URL_of_deleted.file@90439 .
Daniel YC Lin
sumber
0

Anda dapat menemukan revisi terakhir yang menyediakan file menggunakan pencarian biner. Saya telah membuat /bin/bashskrip sederhana untuk ini:

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"
}
Sebo.PL
sumber
-1

Saya menulis naskah php yang menyalin log svn dari semua repositori saya ke dalam database mysql. Sekarang saya dapat melakukan pencarian teks lengkap pada komentar atau nama file saya.

lebih tebal
sumber