kiểm tra lịch sử của tập tin bị xóa


158

Nếu tôi xóa một tệp trong Subversion, làm thế nào tôi có thể xem lịch sử và nội dung của nó? Nếu tôi cố gắng thực hiện svn cathoặc svn logtrên một tệp không tồn tại, nó sẽ phàn nàn rằng tệp đó không tồn tại.

Ngoài ra, nếu tôi muốn phục hồi lại tập tin, tôi có svn addnên quay lại không?

(Tôi đã hỏi cụ thể về Subversion, nhưng tôi cũng muốn nghe về cách Bazaar, Mercurial và Git xử lý trường hợp này.)

Câu trả lời:


85

Để lấy nhật ký của một tập tin bị xóa, sử dụng

svn log -r lastrevisionthefileexisted

Nếu bạn muốn phục hồi tệp và giữ lịch sử phiên bản của nó, hãy sử dụng

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

Nếu bạn chỉ muốn nội dung tệp nhưng không được đảo ngược (ví dụ: để kiểm tra nhanh), hãy sử dụng

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

Trong mọi trường hợp, KHÔNG sử dụng 'svn up' để lấy lại tệp đã bị xóa!


2
Bạn cũng có thể đánh giá lại tệp bằng cách thực hiện hợp nhất ngược lại bản sửa đổi mà bạn đã xóa nó. Đây là thủ tục được đề xuất trong các tài liệu SVN. Đối với việc sử dụng "svn up", đó không phải là vấn đề "không làm điều đó" vì nó "sẽ không làm những gì bạn muốn nó làm".
rmeador

5
Làm thế nào tôi có thể xem toàn bộ lịch sử của tập tin?
Benjamin Peterson

71
Đơn giản: hiển thị nhật ký cho thư mục mẹ bằng công tắc '-v': bạn sẽ nhận được cho mỗi mục nhập một danh sách các đường dẫn đã thay đổi. Tìm một cái có chữ 'D' ở phía trước và tên của tệp đã xóa của bạn. Đó là bản sửa đổi nơi tập tin bị xóa.
Stefan

7
Điều này dường như không hoạt động cho các tập tin bị xóa. Nếu tôi thử điều này, tôi nhận được thông báo lỗi này: svn cat [url] /trunk/include/syeka/poster_funk.incl.php -r 50> out.txt svn: '/ admintools /! Svn / bc / 131 / trunk / bao gồm / syeka / poster_funk.incl.php 'không tìm thấy đường dẫn Xem phản hồi của @Bert Huijben về chủ đề này để biết giải pháp hoạt động.
Keith Palmer Jr.

2
Nếu tôi có một repo với 100.000 lần cam kết, "lastrevisionthefileexisted" không dễ tìm!
Jon Watte

151

Khi bạn muốn xem các tập tin cũ, bạn thực sự nên biết sự khác biệt giữa:

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

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

Phiên bản đầu tiên xem đường dẫn hiện có sẵn dưới dạng http: // server / svn / project / file và truy xuất tệp đó như trong phiên bản 1234. (Vì vậy cú pháp này không hoạt động sau khi xóa tệp).

Cú pháp thứ hai lấy tệp có sẵn dưới dạng http: // server / svn / project / file trong phiên bản 1234. Vì vậy, cú pháp này KHÔNG hoạt động trên các tệp bị xóa.

Bạn thậm chí có thể kết hợp các phương thức này để truy xuất một tệp có sẵn trong phiên bản 2345 dưới dạng http: // server / svn / project / tệp nhưng với nội dung như trong 1234 với:

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

7
Gah, cảm ơn! Phản hồi hàng đầu hiện tại trong chủ đề này không đề cập đến điều này, điều này là tuyệt vời!
Keith Palmer Jr.

Điều này vẫn thất bại đối với tôi trừ khi tôi sử dụng các đường dẫn tuyệt đối, vì máy khách svn cục bộ của tôi đã báo lỗi khi không thể giải quyết ./local/filekhi ./localthư mục không tồn tại. Đây có thể không phải là vấn đề đối với các phiên bản mới hơn của SVN.
Derrick Rice

2
@DerrickRice: Trong trường hợp đó, ^ký hiệu trở nên tiện dụng: nó đề cập đến thư mục gốc của kho lưu trữ, do đó bạn có thể nói svn cat ^/local/file@REV(tùy thuộc vào khoảng cách giữa gốc kho lưu trữ và URL).
musiphil

Điều này hoạt động tuyệt vời về nguyên tắc. Đối với các thư mục tôi nhận được như sau:svn: E200009: Could not cat all targets because some targets are directories
Barney

Đây là câu trả lời tốt nhất. Có số phiếu cao nhất, quá.
Felipe Alvarez

94

Đầu tiên, tìm số sửa đổi trong đó tệp đã bị xóa:

svn log -v > log.txt

Sau đó tìm trong log.txt (không phải là một chuyên gia về SVN, vì vậy tôi không biết cách nào tốt hơn) cho một dòng với

D <deleted file>

và xem bản sửa đổi nào Sau đó, như trong các câu trả lời khác, phục hồi tệp bằng cách sửa đổi trước đó.


22
đăng nhập svn -v | grep D "file.name"
abatishchev

18
+1 vì là người đầu tiên trả lời đúng câu hỏi. Bạn không thể xem nội dung nếu bạn không biết bản sửa đổi trước khi nó bị xóa.
Cerin

8
@abatishchev điều này có được danh sách các tệp đã bị xóa, nhưng loại bỏ thông tin sửa đổi, vì vậy nó không hữu ích. Ngoài ra, nó sẽ chậm nếu bạn đang làm việc với một kho lưu trữ lớn / cũ với nhiều lịch sử thay đổi.
tchen

4
Tốt, tuyệt vời với sự cải thiện của @ abatishchev. tchen: dễ dàng sửa bằng cách sử dụng đối số -B50 hoặc hơn để grep, xem câu trả lời của tôi.
Jonas Byström

2
Một cách khác để hạn chế đầu ra svn log -v cho các kho rất lớn / cũ là tùy chọn -l. Vì vậy, bạn có thể sử dụng svn log -v -l 100 | grep D "file.name"
mindmatters

27

Nó không có gì đặc biệt trong git. Nếu bạn biết tên của tệp, bạn có thể tìm ra thay đổi đã xóa tệp đó bằng nhật ký:

git log -n 1 -- filename

Sau đó, bạn có thể sử dụng cam kết đó để có được tệp như nó đã tồn tại trước khi xóa.

git checkout [last_revision]^ filename

Thí dụ:

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

Lưu ý rằng điều này không thực sự đưa tập tin trở lại trong kiểm soát sửa đổi. Nó chỉ đơn giản là thả tập tin khi nó tồn tại ở trạng thái cuối cùng vào vị trí hiện tại. Sau đó, bạn có thể thêm nó hoặc chỉ kiểm tra nó hoặc bất cứ điều gì từ thời điểm đó.


6
Câu trả lời tuyệt vời. Vấn đề duy nhất là câu hỏi là về svn!
JohnK

16

Một giải pháp chỉ sử dụng GUI:

Nếu bạn biết tên của tệp, nhưng không biết số sửa đổi cuối cùng hoặc thậm chí đường dẫn của tệp :

  1. Từ Trình duyệt Repo thực hiện "Hiển thị nhật ký" trên thư mục gốc
  2. Nhấn "Hiển thị tất cả" (ở dưới cùng của hộp thoại nhật ký)
  3. Nhập tên tệp vào hộp văn bản Bộ lọc (ở đầu hộp thoại nhật ký)

Điều này sau đó sẽ chỉ hiển thị những sửa đổi trong đó tệp đã được thêm / sửa đổi / xóa. Đây là lịch sử của tập tin.

Lưu ý rằng nếu tệp đã bị xóa bằng cách xóa một trong các thư mục mẹ của nó, nó sẽ không có mục 'xóa' trong nhật ký (và vì vậy giải pháp của mjy sẽ không hoạt động). Trong trường hợp này, mục nhập gần đây nhất của nó trong nhật ký được lọc sẽ tương ứng với nội dung của nó khi xóa.


Lực lượng vũ phu không phải lúc nào cũng là cứt. Đặc biệt không phải trên repos lớn.
Jonas Byström

+1 cho giải pháp chỉ dành cho UI. Dòng lệnh là tuyệt vời, và tất cả, nhưng nó không phải luôn luôn là câu trả lời tốt nhất mà không có ngoại lệ. Đặc biệt là khi bạn làm việc trong môi trường bạn không kiểm soát và không có quyền truy cập dòng lệnh dễ dàng vào SVN.
Mir

Xin lưu ý rằng câu trả lời trên có nghĩa là cho GUI TortoiseSVN.
Georg Muehlenberg

13
svn log -v | grep -B50 YourDeletedFileName

Sẽ giúp bạn có đường dẫn và sửa đổi. Trong git (cũng kiểm tra đổi tên):

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

-B50 làm gì? Tôi có thể nhận được danh sách các tệp bằng svn log và grep khá dễ dàng bằng các mẹo ở đây, nhưng dường như tôi không thể có được các số sửa đổi được hiển thị một cách dễ dàng, vì chúng được hiển thị trên một dòng khác. Tôi đã thử điều B50 và nó dường như không hoạt động tuyệt vời đối với tôi.
cedd

Nó xuất ra dòng toán và 50 dòng ở trên trong trường hợp bất kỳ ai khác đang đọc này.
cedd

8

Ngoài câu trả lời của Dustin, nếu bạn chỉ muốn kiểm tra nội dung và không kiểm tra nó, trong ví dụ của anh ấy, bạn có thể làm:

$ git show 8d4a1f^:slosh.tac

the: tách một bản sửa đổi và một đường dẫn trong bản sửa đổi đó, yêu cầu một cách hiệu quả một đường dẫn cụ thể tại một bản sửa đổi cụ thể.


À, rất đúng. Tôi đã từng làm điều đó một cách thực sự, thực sự khó khăn. :)
Dustin

8

Sử dụng lệnh này:

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

Điều này sẽ liệt kê tất cả các sửa đổi đã từng xóa bất kỳ tệp nào phù hợp với mẫu. Nghĩa là, nếu bạn đang tìm kiếm tập tin README, sau đó tất cả /src/README, /src/README.first/some/deeply/hidden/directory/READMENOTsẽ được tìm thấy và được liệt kê.

Nếu tên tệp của bạn chứa dấu gạch chéo (đường dẫn), dấu chấm hoặc ký tự regex đặc biệt khác, đừng quên thoát chúng để tránh không khớp hoặc lỗi.


7

Nếu bạn không biết đường dẫn đến tệp đã bị xóa, hóa ra bạn có thể tìm kiếm nó trong svn loglệnh quá nặng :

svn log --search <deleted_file_or_pattern> -v

Lệnh này có thể gây nhiễu cho máy chủ nhiều như không có tùy chọn tìm kiếm, nhưng ít nhất phần còn lại của các tài nguyên liên quan (bao gồm nhãn cầu của bạn) sẽ được giải tỏa, vì điều đó sẽ cho bạn biết bản sửa đổi nào đã bị xóa. Sau đó, bạn có thể làm theo các mẹo khác (chủ yếu sử dụng cùng một svn loglệnh, nhưng đã có trên một đường dẫn xác định).


svn log --search _test2.php -v... svn: tùy chọn không hợp lệ: - tìm kiếm ... :(
thinsoldier

5

Các poster đã thực sự hỏi 3 câu hỏi ở đây:

  1. Làm cách nào để xem lịch sử của một tệp đã bị xóa trong Subversion?
  2. Làm cách nào để xem nội dung của tệp bị xóa trong Subversion?
  3. Làm cách nào để tôi phục hồi tệp bị xóa trong Subversion?

Tất cả các câu trả lời tôi thấy ở đây là cho câu hỏi 2 và 3.

Câu trả lời cho câu hỏi 1 là:

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

Bạn vẫn cần lấy số sửa đổi khi tệp tồn tại lần cuối, được trả lời rõ ràng bởi những người khác ở đây.


4

Ah, vì tôi đang học sử dụng Bazaar, đó là thứ tôi đã thử. Nếu không thành công, có vẻ như bạn không thể đăng nhập và chú thích các tệp đã bị xóa hiện tại ... :-(

Đã thử:

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

nhưng tò mò (và may mắn thay) tôi có thể làm:

> bzr cat -r 3 Stuff/ErrorParser.hta

và:

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

và như được đề xuất trong lỗi trên:

> bzr log -v | grep -B 1 ErrorParser

(điều chỉnh -B( --before-context) tham số khi cần).


1

Bạn sẽ cần phải xác định một sửa đổi.

svn log -r <revision> <deleted file>

1
Điều này cho một lỗi. Ví dụ: svn log -r 37.428 svn.example.com/deletedfile.java svn: '/!svn/bc/98571/deletedfile.java' con đường không tìm thấy
Jeremy

Bạn có chắc chắn nó tồn tại ở phiên bản đó? Bạn phải xác định một bản sửa đổi trong đó tệp thực sự tồn tại.
Jack M.

Xem câu trả lời của Bert Huijben cho sự khác biệt kỳ lạ giữa -r37428 và thêm @ 37428 vào URL SVN.
dubek

1

Nếu bạn muốn xem lịch sử của một tập tin trước khi nó được đổi tên, thì như đã đề cập trong một nhận xét ở đây, bạn có thể sử dụng

git log --follow -- current_file_name

1

Tôi muốn một câu trả lời, bản thân mình. Hãy thử làm như sau để đầu ra chỉ xóa từ 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 } }'

Điều này lọc đầu ra nhật ký thông qua awk . awk đệm mỗi dòng sửa đổi mà nó tìm thấy, chỉ xuất ra khi bản ghi xóa được tìm thấy. Mỗi sửa đổi chỉ là đầu ra một lần, do đó, nhiều lần xóa trong một sửa đổi được nhóm lại với nhau (như trong tiêu chuẩnsvn log đầu ra ).

Bạn có thể chỉ định a --limitđể giảm số lượng hồ sơ trả lại. Bạn cũng có thể loại bỏ --stop-on-copy, khi cần thiết.

Tôi biết có những phàn nàn về hiệu quả của việc phân tích toàn bộ nhật ký. Tôi nghĩ rằng đây là một giải pháp tốt hơn grep và -Btùy chọn "cast a wide net" của nó . Tôi không biết nếu nó hiệu quả hơn, nhưng tôi không thể nghĩ ra một giải pháp thay thế svn log. Nó tương tự như câu trả lời của @Alexander Amelkin, nhưng không cần một cái tên cụ thể. Đó cũng là kịch bản awk đầu tiên của tôi , vì vậy nó có thể là độc đáo.


1

Giả sử tệp của bạn được đặt tên là ~ / src / a / b / c / remove.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

đầu ra mẫu, tìm thấy nó tại 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

sao chép nó trở lại phiên bản trước (90439 = 90440-1)

svn cp URL_of_deleted.file@90439 .

0

Bạn có thể tìm thấy bản sửa đổi cuối cùng cung cấp tệp bằng cách tìm kiếm nhị phân. Tôi đã tạo một /bin/bashkịch bản đơn giản cho việc này:

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ôi đã viết một tập lệnh php sao chép nhật ký svn của tất cả các kho lưu trữ của tôi vào cơ sở dữ liệu mysql. Bây giờ tôi có thể thực hiện tìm kiếm toàn văn trên nhận xét hoặc tên của tệp.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.