มีวิธีในการคอมไพล์เพื่อรับวันที่ผลักดันสำหรับการกระทำที่กำหนดหรือไม่?


93

ฉันสงสัยว่ามีวิธีดูวันที่ผลักดันที่เกี่ยวข้องกับการคอมมิตแต่ละรายการในบันทึกคอมไพล์หรือไม่ หากเป็นไปไม่ได้มีวิธีดูการกระทำทั้งหมดภายใต้การผลักดันบางอย่างหรือไม่

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

คำตอบ:


77

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

# required for a bare repo
git config core.logAllRefUpdates true

git reflog --date=local master

ง่ายในที่สุด

คำเตือน: คุณอาจต้องการที่จะแทนที่ค่าเริ่มต้นของและgc.reflogExpire gc.reflogExpireUnreachableตรวจสอบgit help reflogรายละเอียดและทำความเข้าใจวิธีการทำงานและเหตุผล

ต้องเรียกใช้คำสั่งสองคำสั่งข้างต้นภายในโคลนที่คุณพุช หากเป็นไปไม่ได้การประมาณคือการเรียกใช้ในการโคลนถาวรอื่น:

git fetch               origin        # often and *regularly*
git reflog --date=local origin/master

อย่าลบโคลนถาวรนี้มิฉะนั้นคุณจะสูญเสียวันที่


2
ฉันต้องการเพิ่มว่าในกรณีของฉันฉันต้องทำgit reflog --date=local origin/master(หมายเหตุorigin/) เพื่อดูรายการพุช มิฉะนั้นจะกระทำเท่านั้นการชำระเงินและการดึงอยู่ในรายการ (ซึ่งมีประโยชน์เช่นกัน) อันที่จริงผมก็ชี้ให้โดย@ คำตอบของ
สนช.

@NIA: ต้นกำเนิด / ต้นแบบจะให้ข้อมูลโดยประมาณเท่านั้น ฉันได้อัปเดตคำตอบของฉันตามความคิดเห็นของคุณสิ่งนี้ชี้แจงหรือไม่
MarcH

37

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

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

ข่าวร้าย

น่าเสียดายที่ไม่มีวิธีต่อท้ายวันที่ในข้อความคอมมิต นั่นจะเปลี่ยนรหัสการคอมมิต (ซึ่งเป็นแฮช SHA1 ของเนื้อหา) ทำให้เกิดปัญหาทุกประเภท

ข่าวดี

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

คุณสามารถใช้คุณลักษณะบันทึกเพื่อแนบข้อความ "การคอมมิตนี้ได้รับเมื่อ [วันที่]" กับแต่ละคอมมิตตามที่ได้รับจากที่เก็บที่แบ่งใช้

ดูgit help notesรายละเอียด

วิธีบันทึกวันที่

นี่คือแนวทางที่ฉันแนะนำ:

  1. แก้ไขpost-receivehook บนที่เก็บที่แบ่งใช้ของคุณเพื่อเดินแต่ละคอมมิตที่เข้าถึงได้ใหม่สำหรับการอ้างอิงที่อัพเดต
  2. สำหรับการคอมมิตแต่ละครั้งให้ต่อท้ายบางสิ่งเช่น "[ผู้ใช้] ของ [repository_url] เพิ่มการคอมมิตนี้ใน [ref] เมื่อ [วันที่]" ลงในบันทึกของคอมมิต

    คุณอาจต้องการที่จะใช้บันทึก Ref อุทิศตนเพื่อจุดประสงค์นี้ (ชอบrefs/notes/received-on) refs/notes/commitsแทนการเริ่มต้น วิธีนี้จะป้องกันความขัดแย้งกับบันทึกย่อที่สร้างขึ้นเพื่อวัตถุประสงค์อื่น

  3. แก้ไขreceiveตะขอของคุณเพื่อปฏิเสธการอัปเดตการอ้างอิงบันทึกย่อของคุณ (เพื่อป้องกันไม่ให้ผู้ใช้ยุ่งกับโน้ตโดยไม่ตั้งใจหรือตั้งใจ)
  4. บอกให้ผู้ใช้ทุกคนรันคำสั่งต่อไปนี้จากภายในโครงสร้างการทำงาน:

    # Fetch all notes from the shared repository.
    # Assumes the shared repository remote is named 'origin'.
    git config --add remote.origin.fetch '+refs/notes/*:refs/remote-notes/origin/*'
    
    # Show all notes from the shared repository when running 'git log'
    git config --add notes.displayRef 'refs/remote-notes/origin/*'
    

    ขั้นตอนนี้จำเป็นเนื่องจาก Git ละเว้นการอ้างอิงที่ไม่ใช่สาขาและไม่ใช่แท็กในที่เก็บอัปสตรีมตามค่าเริ่มต้น

ข้างต้นถือว่าการอ้างอิงเป็นขั้นสูงเท่านั้นไม่เคยลบหรือบังคับให้อัปเดต คุณอาจต้องการให้post-receivehook ต่อท้ายโน้ต "ลบออกเมื่อ [วันที่]" เพื่อจัดการกรณีเหล่านี้


ฉันใช้ความคิดของคุณในบล็อกของฉันmnaoumov.wordpress.com/2013/01/31/git-get-push-date
mnaoumov

8
git reflog show origin/master --pretty='%h %gd %gs %s' --date=iso

ดูเหมือนว่าจะทำงานได้ดีสำหรับฉัน วันที่ส่งคำสั่ง (% cd) ทำให้เข้าใจผิดเพราะไม่จำเป็นต้องตรงกับวันที่ส่ง อ็อพชัน --date = iso จะส่งออกวันที่พุช / ดึงข้อมูลดึงข้อมูลวันที่

หมายเหตุหากคุณดึงข้อมูลจากต้นทาง / ต้นแบบระบบจะพิมพ์วันที่ที่คุณดึงข้อมูลออกมา ไม่ใช่วันที่คนอื่นผลักดันการกระทำ

 - %h:  abrev. hash
 - %gd: human readable reflog selector
 - %gs: reflog subject
 - %s:  subject/commit message

โบนัส: แน่นอนคุณสามารถจัดรูปแบบได้สวยขึ้น จนถึงตอนนี้ฉันชอบการเข้ารหัสสีนี้ พิมพ์เยอะไปหน่อย สิ่งนี้จะส่งออก SHA เป็นสีแดงตัวเลือก reflog เป็นสีฟ้าและ reflog ขึ้นอยู่กับสีเขียว

git reflog show origin/master --pretty='format:%C(red)%h%Creset %C(cyan)%gd%Creset %C(green)%gs%Creset: %s' --date=iso

สวัสดี VC หมายความว่าหากผลลัพธ์ของคำสั่ง "reflog แสดงที่มา / ต้นแบบ --pretty = '% Cred% h% Creset -% C (สีเหลือง)% gd% Creset% Cblue (% gs)% Creset% s' - -date = iso "is" da4c192cd -origin / master @ {2019-02-07 08:13:40 +0100} (ดึง: กรอไปข้างหน้า) JIRA-2542 ปรับปรุงรายงานการทดสอบ "หมายความว่าเนื้อหาของ JIRA สาขาของฉัน -2542 ถูกรวมเข้ากับ origin / master ผ่าน fast-froward ที่ 2019-02-07 08:13:40?
Simon

สวัสดีไซม่อนใช่ คุณดึงคอมไพล์ในสาขาของคุณและรวมเข้ากับต้นทาง / มาสเตอร์ผ่านกรอไปข้างหน้าในเวลานั้น
VC

ใช้งานได้เฉพาะในพื้นที่เก็บข้อมูลของผู้เขียน ถ้าฉันโคลนที่เก็บค่าจะว่างเปล่า คุณไม่สามารถดูเวลาผลักดันของคนอื่นได้
ramwin

6

ลองดูที่git reflog show master. อาจไม่ใช่รูปแบบที่คุณต้องการ แต่ควรชี้ให้คุณไปในทิศทางที่ถูกต้อง

อีกแนวคิดหนึ่งคือการเรียกใช้สคริปต์ภายใน push hook


ฉันคิดเกี่ยวกับการใช้ push hook แต่ดูเหมือนว่าจะเป็นความพยายามครั้งสุดท้าย ด้วยตะขอดูเหมือนว่าผู้ใช้ทุกคนจะต้องมีเบ็ดนั้นในที่เก็บแต่ละแห่ง คุณสามารถเจาะจงมากขึ้นเกี่ยวกับgit reflog show master? ฉันต้องการดูวันที่ผลักดันของการกระทำของผู้ใช้แต่ละคน
justkikuchi

git reflog แสดงลำดับของการเปลี่ยนแปลงใน repo ที่คุณเรียกใช้ฉันไม่แน่ใจว่ามีวิธีรับวันที่โดยตรงหรือไม่ แต่ใน.git/logs/refs/heads/masterนั้นจะแสดงการประทับเวลา
Karl Bielefeldt

3
ในฐานะที่เป็นตะขอมีได้รับตะขอที่ทำงานบนเครื่องที่คุณผลักดันไป เนื่องจากการพุชมีความเกี่ยวข้องเฉพาะเมื่อเทียบกับ repo ที่เฉพาะเจาะจงฉันจึงถือว่าคุณมี repo ที่ "มีความสุข" ที่คุณต้องการเรียกใช้ เช่นเดียวกันgit reflogสำหรับเรื่องนั้น
Karl Bielefeldt

5

คำตอบเกี่ยวกับการตรวจสอบ reflog บนรีโมทนี้อาจช่วยได้ ( https://stackoverflow.com/a/8791295/336905 ) โดยให้ข้อมูลว่าสาขาใดถูกผลักผ่านแม้ว่าจะไม่ได้แสดงว่ามีการผลักดันการคอมมิตใด แต่คุณ สามารถเชื่อมโยงข้ามกันได้โดยการค้นหาการผลักดันถัดไปหลังจากวันที่กระทำในระบบ ไม่พิสูจน์คนโง่ แต่มีประโยชน์หากคุณยังไม่ได้ใช้คำแนะนำบันทึกย่อที่ยอดเยี่ยมจาก @RichardHansen ที่โพสต์ไว้ก่อนหน้านี้


1
ด้วยหมายเหตุว่า reflog ของorigin/branchจะแสดงเฉพาะการเปลี่ยนแปลงที่เกิดขึ้นในเครื่องปัจจุบันเท่านั้นสิ่งนี้มีประโยชน์มาก! สำหรับการใช้งานแบบวันต่อวันฉันไม่ต้องการใช้ตะขอใด ๆ ดังนั้นสำหรับคำถามง่ายๆ"อืมเมื่อฉันผลักดันข้อตกลงนั้นเมื่อสัปดาห์ที่แล้ว?" - ใช้งานได้ดี
สนช.

4

คุณยังสามารถดูเวลาแก้ไขไฟล์ของไฟล์อ็อบเจ็กต์คอมมิตในไดเร็กทอรี "อ็อบเจ็กต์" ในที่เก็บ git บนเซิร์ฟเวอร์เอง


3

ทำไม Git AuthorDate จึงแตกต่างจาก CommitDate

  • AuthorDate คือเมื่อสร้างคอมมิตครั้งแรก
  • CommitDate คือเมื่อการคอมมิตถูกแก้ไขครั้งล่าสุด (เช่น rebase)

คุณสามารถรับสิ่งเหล่านี้ด้วย--prettyตัวเลือกการจัดรูปแบบ:

       o    %cd: committer date
       o    %cD: committer date, RFC2822 style
       o    %cr: committer date, relative
       o    %ct: committer date, UNIX timestamp
       o    %ci: committer date, ISO 8601 format

ดังนั้นถ้าคุณและนักพัฒนาอื่น ๆ ที่ทำgit rebaseก่อนที่git pushคุณจะจบลงด้วยการกระทำวันที่เป็นวันหลังจากวันที่ผู้เขียน

คำสั่งนี้แสดงวันที่กระทำ: git log --pretty=fuller


1

ฉันเดาว่าคุณสามารถใช้สัญกรณ์ถัดไปเพื่อรับวันที่ผลักดัน: git log -g --date = local

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