วิธีชำระเงินใน Git ตามวันที่?


314

ฉันกำลังทำงานกับการถดถอยในซอร์สโค้ด ฉันต้องการบอก Git: "ชำระเงินแหล่งที่มาตามวันที่ / เวลาที่กำหนดพารามิเตอร์" เป็นไปได้ไหม

ฉันมีการเปลี่ยนแปลงเป็นระยะในมุมมองปัจจุบันของฉันที่ฉันไม่ต้องการสูญเสีย เป็นการดีที่ฉันต้องการสลับไปมาระหว่างแหล่งที่มาปัจจุบันและบางรุ่นที่ฉันสนใจตามวันที่ก่อนหน้า


9
ในกรณีที่คุณไม่รู้เกี่ยวกับมันgis bisectนั้นยอดเยี่ยมมากสำหรับการค้นหาการถดถอย ฉันจะบอกว่าใช้ไวยากรณ์ {1 ปีที่แล้ว} อย่าง Andy พูดเพื่อค้นหาความมุ่งมั่นที่รู้จักกันดีจากนั้นใช้มันเป็นgit bisect goodจุดเริ่มต้นของคุณ
MatrixFrog

tagsฉันรู้สึกเหมือนเป็นกรณีการใช้งานที่ดีนี้
Jess

คำตอบ:


365

เพื่อให้การเปลี่ยนแปลงปัจจุบันของคุณ

คุณสามารถทำให้งานของคุณสะดุดโดยไม่ต้องไปทำอะไรกับgit stashมัน คุณต้องการใช้git stash popเพื่อรับคืน หรือคุณสามารถ (ตามที่carleetoกล่าว) git commitไปยังสาขาแยก

ชำระเงินตามวันที่โดยใช้การแยกวิเคราะห์

คุณสามารถชำระเงินการส่งมอบตามวันที่ระบุโดยใช้rev-parseสิ่งนี้:

git checkout 'master@{1979-02-26 18:30:00}'

git-rev-parseรายละเอียดเพิ่มเติมเกี่ยวกับตัวเลือกที่สามารถพบได้ใน

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

ชำระเงินตามวันที่โดยใช้รายการ rev

ตัวเลือกอื่น ๆ ซึ่งไม่ได้ใช้ reflog คือการใช้rev-listเพื่อรับการกระทำ ณ เวลาใดเวลาหนึ่งด้วย:

git checkout `git rev-list -n 1 --first-parent --before="2009-07-27 13:37" master`

จดบันทึก--first-parentหากคุณต้องการให้มีเพียงประวัติของคุณเท่านั้นและไม่ใช่เวอร์ชันที่รวมเข้าด้วยกัน นั่นคือสิ่งที่คุณมักต้องการ


2
@ Rocky คุณช่วยให้รายละเอียดเพิ่มเติม Rocky ได้ไหม? คุณกำลังป้อนอะไรในบรรทัดคำสั่งและทำไมคุณถึงบอกว่ามันไม่ทำงาน คุณได้รับข้อความแสดงข้อผิดพลาดหรือไม่?
Andy

8
@Rocky: ปัญหาคือพารามิเตอร์จะต้องอยู่ในเครื่องหมายคำพูดมิฉะนั้น bash จะแยกอาร์กิวเมนต์ที่ช่องว่างออก ลองgit co 'master@{2 days ago}'ดู
Mark Wilden

13
หมายเหตุ: ขึ้นอยู่กับว่าคุณย้อนกลับไปนานแค่ไหนสิ่งนี้อาจไม่ทำงานเนื่องจากใช้การอ้างอิงใหม่ (ซึ่งจะหมดอายุหลังจากผ่านไประยะหนึ่ง) คุณจะเห็น 'คำเตือน: เข้าสู่ระบบสำหรับ' ต้นแบบ 'เท่านั้นกลับไปที่ ... ' ทางออกของร็อคกี้จะทำงานตลอดเวลา git checkoutgit rev-list -n 1 --before="2009-07-27 13:37" master
Mark Nadig

3
ฉันแก้ไขคำตอบของคุณเนื่องจาก backticks เลิกใช้และอ่านยาก subshells $(...)เป็นที่ต้องการ
Amedee Van Gasse

1
@ แอนดี้สุขสันต์วันเกิด 40 ปีแอนดี้! (สมมติว่านั่นคือสิ่งที่ 1979-02-26 หมายถึง :))
David Blevins

123

แอนดี้แก้ปัญหาไม่ได้สำหรับฉัน ที่นี่ฉันพบวิธีอื่น:

git checkout `git rev-list -n 1 --before="2009-07-27 13:37" master`

Git: ชำระเงินตามวันที่


3
เมื่อฉันรันคำสั่งด้านบนฉันจะได้รับerror: unknown switch `n'ความคิดวิธีการแก้ไขนี้
ทิม

15

ดูเหมือนว่าคุณต้องการบางสิ่งบางอย่างตามบรรทัดนี้: เช็คเอาต์ Git ตามวันที่

ในคำอื่น ๆ ที่คุณใช้rev-listในการค้นหาการกระทำและจากนั้นใช้เช็คเอาต์ที่จะได้รับมัน

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

แก้ไข: ลิงค์ไม่ทำงานดังนั้นนี่คือคำสั่ง:

git checkout `git rev-list -n 1 --before="2009-07-27 13:37" master`

2
ลิงค์ยอดเยี่ยม! ดังนั้นgit checkout branch@{date}หยุดการทำงานเมื่อ reflog หมดอายุ git checkout `git rev-list -n 1 --before="2009-07-27 13:37" master`แต่คุณสามารถใช้
cdunn2001


9

ในกรณีของฉัน-n 1ตัวเลือกไม่ทำงาน บน Windows ฉันพบว่าคำสั่งต่อไปนี้ทำงานได้ดี:

git rev-list -1 --before="2012-01-15 12:00" master

สิ่งนี้จะคืนค่า SHA ของการส่งมอบที่เหมาะสมสำหรับวันที่กำหนดจากนั้น:

git checkout SHA

4

git rev-parseโซลูชั่นที่นำเสนอโดย @Andy ทำงานได้ดีถ้าวันที่คุณสนใจเป็นวันที่ส่งมอบของ แต่ถ้าคุณต้องการที่จะเช็คเอาท์ขึ้นอยู่กับวันที่ผู้เขียน , rev-parseจะไม่ทำงานเพราะมันไม่ได้มีตัวเลือกที่จะใช้วันที่สำหรับการเลือกกระทำ คุณสามารถใช้สิ่งต่อไปนี้แทน

git checkout $(
  git log --reverse --author-date-order --pretty=format:'%ai %H' master |
  awk '{hash = $4} $1 >= "2016-04-12" {print hash; exit 0 }
)

(หากคุณต้องการระบุเวลาที่ใช้$1 >= "2016-04-12" && $2 >= "11:37"ในprkate awkด้วย)


3

ไปต่อกับrev-listตัวเลือกถ้าคุณต้องการที่จะหาผสานล่าสุดกระทำจากสาขาหลักของคุณลงในสาขาการผลิตของคุณ (เป็นตัวอย่างสมมุติอย่างหมดจด):

git checkout `git rev-list -n 1 --merges --first-parent --before="2012-01-01" production`

ฉันต้องการค้นหารหัสที่อยู่ในเซิร์ฟเวอร์ที่ใช้งานจริง ณ วันที่ระบุ พบว่ามันสำหรับฉัน


2

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

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

การใส่แท็กในการส่งข้อมูลหมายความว่าจะไม่สามารถเข้าถึงได้ไม่ว่าคุณจะทำอะไรกับสาขาหลังจากนั้น (ยกเว้นการลบแท็ก)


แม้ว่านี่จะไม่ได้ให้คำตอบที่ฉันต้องการ แต่ก็สมควรได้รับการกล่าวถึงที่ดีสำหรับการชี้ให้เห็นแง่มุมที่ไม่ได้กล่าวถึง นี่อาจเป็นสาเหตุของปัญหาที่ทำให้คุณไม่สามารถเข้าถึงเวอร์ชันที่ถูกต้องได้
manuelvigarcia

1
git rev-list -n 1 --before="2009-07-27 13:37" origin/master

ใช้สตริงที่พิมพ์ (เช่น XXXX) และทำ:

git checkout XXXX

2
นี่ไม่ใช่คำตอบ @bartoszkp ที่ซ้ำกันใช่หรือไม่ เพียงแค่เพิ่มการอ้างอิงถึงแหล่งกำเนิดควรมีความคิดเห็นเกี่ยวกับคำตอบอื่น ๆ ...
23432

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