การตรวจสอบประวัติของไฟล์ที่ถูกลบ


160

หากฉันลบไฟล์ในการโค่นล้มฉันจะดูประวัติและเนื้อหาได้อย่างไร ถ้าฉันพยายามที่จะทำsvn catหรือsvn logบนไฟล์ที่ไม่มีอยู่ก็บ่นว่าไฟล์ไม่มีอยู่

นอกจากนี้หากฉันต้องการที่จะกู้คืนไฟล์ฉันควรsvn addจะกลับมา?

(ฉันถามเฉพาะเกี่ยวกับการโค่นล้ม แต่ฉันก็อยากจะได้ยินเกี่ยวกับวิธีที่ Bazaar, Mercurial และ Git จัดการกับกรณีนี้ด้วย)

คำตอบ:


84

ในการรับบันทึกของไฟล์ที่ลบให้ใช้

svn log -r lastrevisionthefileexisted

หากคุณต้องการกู้คืนไฟล์และเก็บประวัติเวอร์ชันให้ใช้

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

หากคุณต้องการเนื้อหาไฟล์ แต่ไม่ผ่านการทดสอบ (เช่นสำหรับการตรวจสอบอย่างรวดเร็ว) ให้ใช้

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

ไม่ว่าในกรณีใดห้ามใช้ 'svn up' เพื่อลบไฟล์กลับคืน!


2
นอกจากนี้คุณยังสามารถแก้ไขไฟล์อีกครั้งโดยทำการย้อนกลับผสานของการแก้ไขที่คุณลบออก นี่เป็นขั้นตอนที่แนะนำในเอกสาร SVN สำหรับการใช้ "svn up" ไม่ใช่เรื่องของ "อย่าทำ" เพราะมันคือ "มันจะไม่ทำในสิ่งที่คุณต้องการให้ทำ"
rmeador

5
ฉันจะดูประวัติทั้งหมดของไฟล์ได้อย่างไร
เบนจามินปีเตอร์สัน

71
ง่าย ๆ : แสดงล็อกสำหรับโฟลเดอร์พาเรนต์ด้วยสวิตช์ '-v': คุณจะได้รับรายการพา ธ ที่เปลี่ยนแปลงทุกรายการ ค้นหาไฟล์ที่มี 'D' ด้านหน้าและชื่อไฟล์ที่คุณลบ นั่นคือการแก้ไขที่ไฟล์ถูกลบ
สเตฟาน

8
ดูเหมือนว่านี่จะใช้ไม่ได้กับไฟล์ที่ถูกลบ หากฉันลองทำสิ่งนี้ฉันได้รับข้อความแสดงข้อผิดพลาดนี้: 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 'ไม่พบเส้นทางดูคำตอบของ @Bert Huijben เพิ่มเติมในหัวข้อนี้เพื่อดูวิธีการทำงาน
Keith Palmer Jr.

2
ถ้าฉันมี repo ที่มีการทำสัญญา 100,000 รายการ "lastrevisionthefileexisted" ไม่ใช่เรื่องง่ายที่จะหา!
Jon Watte

151

เมื่อคุณต้องการดูไฟล์เก่าคุณควรทราบถึงความแตกต่างระหว่าง:

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

และ

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

เวอร์ชันแรกดูที่พา ธ ที่พร้อมใช้งานในขณะนี้เป็นhttp: // server / svn / project / fileและดึงไฟล์นั้นในรูปแบบที่ถูกแก้ไขใน 1234 (ดังนั้นไวยากรณ์นี้จึงไม่ทำงานหลังจากลบไฟล์)

ไวยากรณ์ที่สองได้รับแฟ้มที่ใช้ได้ในฐานะที่http: // เซิร์ฟเวอร์ / SVN / โครงการ / ไฟล์ในการแก้ไข 1234 ดังนั้นรูปแบบนี้ไมทำงานในไฟล์ที่ถูกลบ

คุณสามารถรวมวิธีการเหล่านี้เพื่อดึงไฟล์ที่มีอยู่ในรุ่น 2345 เป็นhttp: // server / svn / project / file แต่มีเนื้อหาเหมือนใน 1234 ด้วย:

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

7
Gah ขอบคุณ! คำตอบยอดนิยมปัจจุบันในหัวข้อนี้ไม่ได้พูดถึงเรื่องนี้นี่เป็นสิ่งที่ยอดเยี่ยม!
Keith Palmer Jr.

สิ่งนี้ยังคงล้มเหลวสำหรับฉันยกเว้นว่าฉันใช้เส้นทางสัมบูรณ์เนื่องจากไคลเอ็นต์ svn ท้องถิ่นของฉันแสดงข้อผิดพลาดเมื่อไม่สามารถแก้ไขได้./local/fileเมื่อไม่มี./localไดเรกทอรีอยู่ นี่อาจไม่เป็นปัญหาสำหรับ SVN เวอร์ชันที่ใหม่กว่า
ปั้นจั่นข้าว

2
@DerrickRice: ในกรณีนั้น^สัญกรณ์เป็นประโยชน์: มันหมายถึงรูทของที่เก็บดังนั้นคุณสามารถพูดได้svn cat ^/local/file@REV(ขึ้นอยู่กับระยะห่างระหว่างรูทของที่เก็บและ URL)
musiphil

หลักการนี้ใช้งานได้ดีมาก สำหรับโฟลเดอร์ที่ฉันได้รับดังต่อไปนี้:svn: E200009: Could not cat all targets because some targets are directories
Barney

นี่คือคำตอบที่ดีที่สุด มีคะแนนโหวตสูงสุดด้วย
Felipe Alvarez

94

ก่อนอื่นให้ค้นหาหมายเลขการแก้ไขที่ไฟล์ถูกลบ:

svn log -v > log.txt

จากนั้นดูใน log.txt (ไม่ใช่กูรู SVN ดังนั้นฉันไม่รู้วิธีที่ดีกว่า) เพื่อหาบรรทัด

D <deleted file>

และดูว่ามีการแก้ไขใด จากนั้นในคำตอบอื่น ๆ ให้เรียกคืนไฟล์อีกครั้งโดยใช้การแก้ไขก่อนหน้า


22
svn log -v | grep D "file.name"
abatishchev

18
+1 สำหรับการเป็นคนแรกที่ตอบคำถามได้อย่างถูกต้อง คุณไม่สามารถดูเนื้อหาหากคุณไม่ทราบการแก้ไขก่อนที่จะถูกลบ
Cerin

8
@abatishchev สิ่งนี้ได้รับรายชื่อของไฟล์ที่ถูกลบ แต่ทิ้งข้อมูลการแก้ไขดังนั้นจึงไม่มีประโยชน์ นอกจากนี้ยังช้าถ้าคุณทำงานกับที่เก็บขนาดใหญ่ / เก่าที่มีประวัติการเปลี่ยนแปลงมากมาย
tchen

4
ดีมากพร้อมการปรับปรุงของ @ abatishchev tchen: แก้ไขได้อย่างง่ายดายโดยใช้อาร์กิวเมนต์ -B50 หรือมากกว่านั้นเพื่อ grep ดูคำตอบของฉัน
Jonas Byström

2
อีกวิธีที่ดีในการ จำกัด เอาต์พุต svn log -v สำหรับที่เก็บขนาดใหญ่ / เก่าคือตัวเลือก -l ดังนั้นคุณสามารถใช้ svn log -v -l 100 | grep D "file.name"
mindmatters

27

มันไม่มีอะไรพิเศษเป็นพิเศษในคอมไพล์ หากคุณรู้ชื่อของไฟล์คุณสามารถค้นหาการเปลี่ยนแปลงที่ลบออกด้วยบันทึก:

git log -n 1 -- filename

จากนั้นคุณสามารถใช้การส่งข้อมูลเพื่อรับไฟล์ตามที่มีอยู่ก่อนการลบ

git checkout [last_revision]^ filename

ตัวอย่าง:

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

โปรดทราบว่านี่ไม่ได้ทำให้ไฟล์กลับมาอยู่ในการควบคุมการแก้ไข มันเพียงหยดไฟล์ตามที่มีอยู่ในสถานะสุดท้ายลงในตำแหน่งปัจจุบัน จากนั้นคุณสามารถเพิ่มหรือตรวจสอบหรือจากจุดนั้น


6
คำตอบที่ยอดเยี่ยม ปัญหาเดียวก็คือคำถามนี้เกี่ยวกับ svn!
JohnK

16

วิธีแก้ปัญหาที่ใช้เฉพาะ GUI:

หากคุณรู้จักชื่อไฟล์ แต่ไม่ทราบหมายเลขการแก้ไขล่าสุดหรือแม้แต่เส้นทาง:

  1. จาก Repo Browser ทำ "Show log" บนรูท
  2. กด "แสดงทั้งหมด" (ที่ด้านล่างของกล่องโต้ตอบบันทึก)
  3. พิมพ์ชื่อไฟล์ลงในกล่องข้อความตัวกรอง (ที่ด้านบนของกล่องโต้ตอบบันทึก)

จากนั้นจะแสดงเฉพาะการแก้ไขที่ไฟล์ถูกเพิ่ม / แก้ไข / ลบ นี่คือประวัติของไฟล์

โปรดทราบว่าหากไฟล์ถูกลบโดยการลบหนึ่งในโฟลเดอร์พาเรนต์ไฟล์นั้นจะไม่มีรายการ 'ถูกลบ' ในบันทึก (และวิธีการแก้ปัญหาของ mjy จะไม่ทำงาน) ในกรณีนี้รายการล่าสุดในบันทึกการกรองจะสอดคล้องกับเนื้อหาที่ถูกลบ


แรงเดรัจฉานไม่ได้เป็นอึ โดยเฉพาะอย่างยิ่งไม่ได้อยู่ใน repos ใหญ่
Jonas Byström

+1 สำหรับการแก้ปัญหาเฉพาะ UI บรรทัดคำสั่งนั้นยอดเยี่ยมและทั้งหมด แต่ก็ไม่ใช่คำตอบที่ดีที่สุดเสมอไปโดยไม่มีข้อยกเว้น โดยเฉพาะอย่างยิ่งเมื่อคุณทำงานในสภาพแวดล้อมที่คุณไม่ได้ควบคุมและไม่สามารถเข้าถึงบรรทัดคำสั่งที่ง่ายต่อ SVN
เมียร์

โปรดทราบว่าคำตอบข้างต้นมีไว้สำหรับ TortoiseSVN GUI
Georg Muehlenberg

13
svn log -v | grep -B50 YourDeletedFileName

คุณจะได้รับเส้นทางและการแก้ไข ในคอมไพล์ (ตรวจสอบการเปลี่ยนชื่อด้วย):

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

-B50 ทำอะไรได้บ้าง? ฉันสามารถรับรายการไฟล์โดยใช้บันทึก svn และ grep ได้อย่างง่ายดายโดยใช้เคล็ดลับที่นี่ แต่ดูเหมือนว่าฉันไม่สามารถรับหมายเลขการแก้ไขที่แสดงได้อย่างง่ายดายเลยเนื่องจากเป็นการแสดงในบรรทัดอื่น ฉันลองสิ่ง B50 และดูเหมือนว่าจะไม่ได้ผลที่น่าอัศจรรย์สำหรับฉัน
cedd

มันส่งออกสาย mathced และ 50 บรรทัดด้านบนว่าในกรณีที่คนอื่นอ่านข้อความนี้
cedd

8

นอกเหนือจากคำตอบของ Dustin หากคุณต้องการตรวจสอบเนื้อหาและไม่ลองดูในตัวอย่างของเขาคุณสามารถทำได้:

$ git show 8d4a1f^:slosh.tac

: แยกการแก้ไขและเส้นทางในการแก้ไขนั้นอย่างมีประสิทธิภาพขอเส้นทางที่เฉพาะเจาะจงในการแก้ไขที่เฉพาะเจาะจง


อาจริงมาก ฉันเคยทำแบบนั้นจริงๆยากจริงๆ :)
ดัสติน

8

ใช้คำสั่งนี้:

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

นี่จะแสดงรายการการแก้ไขทั้งหมดที่เคยลบไฟล์ใด ๆ ที่ตรงกับรูปแบบ นั่นคือถ้าคุณกำลังค้นหาสำหรับไฟล์ README แล้วทั้งหมดของ/src/README, /src/README.firstและ/some/deeply/hidden/directory/READMENOTจะพบและจดทะเบียน

หากชื่อไฟล์ของคุณมีเครื่องหมายสแลช (พา ธ ) จุดหรืออักขระ regex พิเศษอื่น ๆ อย่าลืมหลีกเลี่ยงพวกเขาเพื่อหลีกเลี่ยงการจับคู่ที่ไม่ตรงกันหรือข้อผิดพลาด


7

หากคุณไม่ทราบเส้นทางไปยังไฟล์ที่ถูกลบปรากฎว่าคุณสามารถค้นหาได้ในsvn logคำสั่งall-too-heavy-heavy :

svn log --search <deleted_file_or_pattern> -v

คำสั่งอาจใช้การตอกย้ำเซิร์ฟเวอร์เท่าที่จะทำได้โดยไม่มีตัวเลือกการค้นหา แต่อย่างน้อยทรัพยากรส่วนที่เหลือ (รวมถึงลูกตาของคุณ) จะได้รับการบรรเทาเนื่องจากจะบอกให้คุณทราบว่าไฟล์ใดถูกลบทิ้ง จากนั้นคุณสามารถทำตามคำแนะนำอื่น ๆ (ส่วนใหญ่ใช้svn logคำสั่งเดียวกันแต่มีอยู่แล้วในเส้นทางที่กำหนด)


svn log --search _test2.php -v... svn: ตัวเลือกที่ไม่ถูกต้อง: - ค้นหา ... :(
thinsoldier

5

ผู้โพสต์ได้ถามคำถาม 3 ข้อที่นี่:

  1. ฉันจะดูประวัติของไฟล์ที่ถูกลบในการโค่นล้มได้อย่างไร
  2. ฉันจะดูเนื้อหาของไฟล์ที่ถูกลบใน Subversion ได้อย่างไร
  3. ฉันจะกู้คืนไฟล์ที่ถูกลบใน Subversion ได้อย่างไร

คำตอบทั้งหมดที่ฉันเห็นที่นี่มีไว้สำหรับคำถามที่ 2 และ 3

คำตอบสำหรับคำถามที่ 1 คือ:

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

คุณยังต้องได้รับหมายเลขการแก้ไขเมื่อไฟล์มีอยู่ครั้งล่าสุดซึ่งคนอื่น ๆ ตอบไว้อย่างชัดเจนที่นี่


4

อาตั้งแต่ฉันเรียนรู้ที่จะใช้ Bazaar มันเป็นสิ่งที่ฉันพยายาม ไม่สำเร็จดูเหมือนว่าคุณจะไม่สามารถเข้าสู่ระบบและใส่คำอธิบายประกอบในไฟล์ที่ถูกลบในปัจจุบัน ... :-(

พยายาม:

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

แต่อยากรู้อยากเห็น (และโชคดี) ฉันสามารถทำ:

> bzr cat -r 3 Stuff/ErrorParser.hta

และ:

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

และตามที่แนะนำในข้อผิดพลาดด้านบน:

> bzr log -v | grep -B 1 ErrorParser

(ปรับพารามิเตอร์-B( --before-context) ตามต้องการ)


1

คุณจะต้องระบุการแก้ไข

svn log -r <revision> <deleted file>

1
สิ่งนี้ทำให้เกิดข้อผิดพลาด ตัวอย่าง: svn log -r 37428 svn.example.com/deletedfile.java svn: '/!svn/bc/98571/deletedfile.java' ไม่พบเส้นทาง
Jeremy

คุณแน่ใจหรือว่ามีอยู่ในการแก้ไขนี้ คุณต้องระบุการแก้ไขที่ไฟล์มีอยู่จริง
Jack M.

ดูคำตอบโดย Bert Huijben สำหรับความแตกต่างแปลก ๆ ระหว่าง -r37428 และเพิ่ม @ 37428 ใน URL SVN
dubek


1

ฉันต้องการคำตอบ 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 } }'

ซึ่งจะกรองเอาท์พุทล็อกผ่านawk awkบัฟเฟอร์บัฟเฟอร์แต่ละบรรทัดที่พบแก้ไขเอาต์พุตเฉพาะเมื่อพบระเบียนลบ การแก้ไขแต่ละครั้งจะถูกส่งออกเพียงครั้งเดียวดังนั้นการลบหลายรายการในการแก้ไขจะถูกจัดกลุ่มเข้าด้วยกัน (ตามมาตรฐานsvn logเอาต์พุต )

คุณสามารถระบุ a --limitเพื่อลดจำนวนระเบียนที่ส่งคืน นอกจากนี้คุณยังสามารถลบ--stop-on-copyได้ตามต้องการ

ฉันรู้ว่ามีข้อร้องเรียนเกี่ยวกับประสิทธิภาพของการแยกวิเคราะห์บันทึกทั้งหมด ฉันคิดว่านี่เป็นทางออกที่ดีกว่า grep และ-Bตัวเลือก"cast a wide net" ฉันไม่รู้ว่ามันมีประสิทธิภาพมากกว่านี้หรือไม่ แต่ฉันไม่สามารถคิดถึงทางเลือกอื่นsvn logได้ มันคล้ายกับคำตอบของ @Alexander Amelkin แต่ไม่ต้องการชื่อเฉพาะ มันเป็นสคริปต์awkแรกของฉันด้วยดังนั้นมันจึงอาจผิดปกติ


1

สมมติว่าไฟล์ของคุณมีชื่อเป็น ~ / 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

ตัวอย่างผลลัพธ์พบได้ที่ 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

คัดลอกกลับไปเป็นรุ่นก่อนหน้า (90439 = 90440-1)

svn cp URL_of_deleted.file@90439 .

0

คุณสามารถค้นหาการแก้ไขครั้งล่าสุดซึ่งให้ไฟล์โดยใช้การค้นหาแบบไบนารี ฉันได้สร้าง/bin/bashสคริปต์ง่าย ๆสำหรับสิ่งนี้:

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

ฉันเขียนสคริปต์ PHP ที่คัดลอกบันทึก svn ของที่เก็บข้อมูลทั้งหมดของฉันลงในฐานข้อมูล MySQL ตอนนี้ฉันสามารถค้นหาข้อความเต็มในความคิดเห็นหรือชื่อไฟล์ของฉัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.