มีวิธีการ "เซ็นสัญญาอัตโนมัติ" ใน Git ด้วยรหัส GPG หรือไม่?


213

มีวิธีง่ายๆในการทำให้ Git ลงนามในแต่ละการกระทำหรือแท็กที่สร้างหรือไม่

ฉันลองกับสิ่งที่ชอบ:

นามแฝงกระทำ = commit -S

แต่นั่นไม่ได้ทำเคล็ดลับ

ฉันไม่ต้องการติดตั้งโปรแกรมอื่นเพื่อให้สิ่งนี้เกิดขึ้น มันเป็นไปได้อย่างง่ายดาย?

แค่คำถามข้างหนึ่งอาจไม่ควรเซ็นสัญญา แต่มีเพียงแท็กที่ฉันไม่เคยสร้างเพราะฉันส่งคอมมิทเดียวสำหรับโครงการเช่น Homebrew ฯลฯ


8
สาเหตุที่นามแฝงของคุณทำงานได้เนื่องจากคุณไม่สามารถใช้นามแฝงผ่านคำสั่งที่มีอยู่แล้วได้ (ที่เกี่ยวข้อง: stackoverflow.com/questions/5875275/git-commit-v-by-default stackoverflow.com/questions/2500586/... stackoverflow.com/questions/1278296/... )
แดน D.

2
เพียงเพื่อรับทราบข้อมูล: เขียนซ้ำทุกข้อผูกพันที่จะผลักดันให้ลงชื่อ: git filter-branch -f --commit-filter 'git commit-tree -S "$@"' HEAD@{u}..HEAD(ฉันไม่ได้หมายความว่าคุณควรใช้สิ่งนี้)
วิ

คำตอบ:


275

หมายเหตุ: หากคุณไม่ต้องการเพิ่ม-Sตลอดเวลาเพื่อให้แน่ใจว่าคุณได้ลงนามในสัญญาแล้วจะมีข้อเสนอ (สาขา ' pu' สำหรับตอนนี้ธันวาคม 2013 ดังนั้นจึงไม่มีการรับประกันว่าจะนำไปสู่การปล่อยคอมไพล์) เพื่อเพิ่ม config ซึ่งจะดูแลตัวเลือกนั้นสำหรับคุณ
อัปเดตพฤษภาคม 2557: อยู่ใน Git 2.0 (หลังจากส่งในชุดข้อมูลแก้ไขนี้ )

ดูคอมมิชชัน 2af2ef3โดยNicolas Vigier (boklm) :

เพิ่มcommit.gpgsignตัวเลือกเพื่อลงนามผูกพันทั้งหมด

ถ้าคุณต้องการที่จะลงนามในสัญญาทั้งหมดของคุณคุณจะต้องเพิ่ม-Sตัวเลือกตลอดเวลา ตัวเลือกการตั้งค่าจะช่วยให้การลงนามกระทำทั้งหมดโดยอัตโนมัติ
commit.gpgsign

commit.gpgsign

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


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

cd /path/to/repo/needing/gpg/signature
git config commit.gpgsign true

คุณจะรวมสิ่งนั้นกับuser.signingKeyใช้เป็นการตั้งค่าส่วนกลาง (คีย์เฉพาะที่ใช้สำหรับ repo ทั้งหมดที่คุณต้องการเซ็นสัญญา)

git config --global user.signingkey F2C7AB29

user.signingKeyได้รับการแนะนำใน git 1.5.0 (2007. ม.ค. ) ด้วยความมุ่งมั่น d67778e :

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

โปรแกรมแก้ไขนี้จะเพิ่มรายการการกำหนดค่า " user.signingKey" ซึ่งหากมีจะถูกส่งผ่านไปยังสวิตช์ "-u" สำหรับ gpg เพื่อให้สามารถแทนที่คีย์การเซ็นชื่อแท็กได้

นี้จะถูกบังคับใช้กับการกระทำ aba9119 (คอมไพล์ 1.5.3.2) เพื่อจับกรณีที่หากผู้ใช้มี misconfigured user.signingKeyในของพวกเขา.git/configหรือเพียงแค่ไม่ได้มีกุญแจลับใด ๆ บนพวงกุญแจของพวกเขา

หมายเหตุ:


มันเจ๋งจริงๆ มีวิธีง่าย ๆ ในการที่ github ทำบางสิ่งบางอย่างเช่น git อธิบายโดยไม่ต้องดาวน์โหลด repo รู?

13
คุณไม่จำเป็นต้องลงนาม repos ทดลองส่วนตัวของคุณ ... แต่ทำไมคุณไม่?
Andy Hayden

168
git config --global user.signingKey 9E08524833CB3038FDE385C54C0AFCCFED5CDE14
git config --global commit.gpgSign true

แทนที่ 9E08524833CB3038FDE385C54C0AFCCFED5CDE14 ด้วยรหัสคีย์ของคุณ โปรดจำไว้ว่ามันไม่เป็นความคิดที่ดีที่จะใช้รหัสสั้น

อัปเดต:ตามคำสั่ง git ใหม่คีย์การกำหนดค่าทั้งหมดควรอยู่ใน camelCase


คุณเพิ่งคัดลอกและวางจากคำตอบของ VonCหรือไม่
Robbie Averill

19
ไม่อย่างที่คุณเห็นในประวัติการพิมพ์บางคนได้เพิ่มตัวอย่างของฉันในคำตอบของเขา ED5CDE14 เป็นรหัสส่วนตัวของฉันเอง แต่ไม่มีปัญหา
เฟลิเป้

7
แปลกประหลาด ฉันจะกลับการเปลี่ยนแปลงในวันพรุ่งนี้เพราะมันดูไม่ดีสำหรับคุณ
Robbie Averill

คุณจะพบ ID การเซ็นชื่อที่สำคัญของคุณได้อย่างไร นอกจากนี้การมีคีย์ GPG เพียงคีย์เดียวสำหรับ repos คอมไพล์ของฉันก็ไม่ดีเช่นกัน? เพราะฉันชอบที่จะไม่ต้องจัดการกับ 4 คีย์ต่างในโครงการที่เชื่อมโยงกัน
MarcusJ

1
สิ่งนี้อาจช่วยผู้ใช้ Linux: เพื่อให้สามารถใช้งานได้ในบางโอกาส (เช่นใน Vim โดยใช้กุญแจที่เก็บไว้ในสมาร์ทการ์ดที่ต้องใช้รหัส PIN) ฉันต้องแก้ไข~/.gnupg/gpg-agent.confและเพิ่มpinentry-program /usr/bin/pinentry-gtk-2(ทำตามคู่มือนี้wiki.archlinux.org/ index.php / GnuPG # pinentry )
iakovos Gurulian

49

แก้ไข: ในฐานะของ Git เวอร์ชัน 1.7.9, มันเป็นไปได้ที่จะลงนามกระทำ Git ( git commit -S) อัปเดตคำตอบเล็กน้อยเพื่อสะท้อนถึงสิ่งนี้

ชื่อคำถามคือ:

มีวิธีการ "เซ็นสัญญาอัตโนมัติ" ใน Git ด้วยรหัส GPG หรือไม่?

คำตอบสั้น ๆ : ใช่ แต่ไม่ทำ

การระบุคำที่พิมพ์ผิดในคำถาม: git commit -sไม่ได้ลงนามในการส่ง ค่อนข้างจากman git-commitหน้า:

-s,
- ลงชื่อออกจากเพิ่มบรรทัดที่ลงชื่อแล้วโดยคอมมิชชันในตอนท้ายของข้อความบันทึกการคอมมิต

สิ่งนี้ให้เอาต์พุตของบันทึกคล้ายกับตัวอย่างต่อไปนี้:


± $ git log                                                                                 [0:43:31]
commit 155deeaef1896c63519320c7cbaf4691355143f5
Author: User Name 
Date:   Mon Apr 16 00:43:27 2012 +0200

    Added .gitignore

    Signed-off-by: User Name 

หมายเหตุบิต "Signed-off-by: ... "; ที่ถูกสร้างขึ้นโดยธงบน-sgit-commit

การอ้างถึงอีเมลประกาศข่าวประชาสัมพันธ์ :

  • "git กระทำ" เรียนรู้ "-S" เพื่อ GPG-sign the commit; สิ่งนี้สามารถแสดงได้ด้วยตัวเลือก "--show-signature" ถึง "git log"

ใช่คุณสามารถเซ็นสัญญาได้ อย่างไรก็ตามฉันขอเตือนด้วยตัวเลือกนี้เป็นการส่วนตัว การลงนามโดยอัตโนมัตินั้นอยู่ถัดจากจุดว่างเปล่าดูด้านล่าง:

แค่คำถามข้างหนึ่งอาจไม่ควรเซ็นสัญญา แต่มีเพียงแท็กที่ฉันไม่เคยสร้างขณะส่งคอมมิทเดียว

ถูกต้อง. ความมุ่งมั่นไม่ได้ลงนาม; แท็กคือ เหตุผลสำหรับสิ่งนี้สามารถพบได้ในข้อความนี้โดยLinus Torvaldsย่อหน้าสุดท้ายที่กล่าวว่า:

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

ฉันขอแนะนำให้เรียกดูข้อความที่เชื่อมโยงซึ่งชี้แจงว่าทำไมการลงนามโดยอัตโนมัติไม่ใช่ความคิดที่ดีในทางที่ดีกว่าที่ฉันจะทำได้

อย่างไรก็ตามหากคุณต้องการเซ็นชื่อแท็กโดยอัตโนมัติคุณจะสามารถทำได้โดยการgit-tag -[s|u]ใส่ชื่อแทน หากคุณกำลังจะทำเช่นนั้นคุณอาจต้องการตั้งค่ารหัสคีย์ของคุณ~/.gitconfigหรือ.git/configไฟล์เฉพาะโครงการ ข้อมูลเพิ่มเติมเกี่ยวกับกระบวนการที่สามารถมองเห็นได้ในหนังสือคอมไพล์ชุมชน แท็กการเซ็นชื่อมีประโยชน์มากกว่าการลงชื่อแต่ละครั้งที่คุณส่งมอบ


74
"การลงนามแต่ละการกระทำนั้นโง่มาก" -> อะไรคือวิธีที่ดีกว่าในการรักษาความปลอดภัยเมื่อมีนักพัฒนา "หนู" ที่ชอบผลักดันให้กระทำกับผู้เขียนและผู้แกล้งทำ เว้นแต่จะมีเบ็ดวิเศษบางอย่างบนเซิร์ฟเวอร์เขาสามารถนำgit blameไปยังใครก็ตามที่เขาต้องการ
วิ

11
0. บทความ 1. "ก็เพียงพอแล้วที่จะลงนามทั้งหมดของพวกเขา" -> วิธีการบอก "ผมอ้างว่านี้เป็นจริงของฉัน . diff ( แต่ไม่แน่ใจเกี่ยวกับกระทำก่อนหน้านี้และเพิ่มเติมใด ๆ ) ฉันต้องการที่จะใส่ลายเซ็นบนของฉันกระทำ ฉันจะดึงข้อมูลจากเซิร์ฟเวอร์ส่วนกลาง / อะไรก็ตามโดยไม่ยุ่งเกี่ยวกับสิ่งใด 2. ในสภาพแวดล้อมที่ไม่น่าเชื่อถือควรมีเครื่องมือที่เชื่อถือได้เพื่อตรวจสอบว่าใครมีความผิดถ้าเซิร์ฟเวอร์ตรวจสอบว่าการกระทำทั้งหมดถูกเซ็นชื่อด้วยอีเมลสำคัญของผู้ส่ง ยากที่จะปลอมกระทำ (ถ้าคุณรักษาความปลอดภัยคอมพิวเตอร์ของคุณด้วย).
Vi.

9
การเซ็นชื่อหนึ่งคอมมิชชันก็เพียงพอแล้วหากโค้ดไม่เคยเปลี่ยนแปลง เมื่อคุณเพิ่มการผูกพันเพิ่มคุณจะต้องมีลายเซ็นที่มากขึ้น การเซ็นชื่อแท็กกำลังทำเครื่องหมายทุกสิ่งเกินกว่าที่กำหนดไว้ หากคุณต้องการการตรวจสอบที่ละเอียดยิ่งขึ้นเมื่อมีการส่งคำสั่ง ไม่เช่นนั้นคุณจะต้องใช้แท็กจำนวนมากซึ่งจะทำให้เกิดปัญหากับ repo ใน repos git ระยะไกลที่ผ่านการรับรองความถูกต้องคุณต้องให้รหัสผ่านหรือคีย์ ssh ทุกครั้งที่คุณส่งคำสั่งไม่เพียง แต่เมื่อคุณกดแท็ก นี่เป็นสถานการณ์ที่คล้ายกัน
Hans-Christoph Steiner

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

9
-1 สำหรับ "ใช่ แต่อย่าทำ" คำตอบควรเป็น "YES" ที่แบนออก การเซ็นสัญญากระทำให้ผู้เขียนพิสูจน์ได้ว่ามีอะไรบางอย่างที่สามารถโกหกในการกระทำ
Urda

6

ในการทำให้การลงชื่ออัตโนมัติทำงานก่อน git เวอร์ชัน 2.0 คุณจะต้องเพิ่มนามแฝง git เพื่อคอมมิท

# git config --global alias.commit commit -S
[alias]
    commit = commit -S

0

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

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

การเซ็นสัญญาเป็นปัญหาหากพวกเขาจะได้รับการปฏิเสธหรือรับเชอร์รี่กับผู้ปกครองคนอื่น ๆ แต่มันจะดีถ้าคอมมิชชันที่แก้ไขแล้วสามารถชี้ไปที่คอมมิชชันดั้งเดิมที่ยืนยันได้จริง


3
การหักกลับเป็นเหมือนการโกหก ควรใช้เท่าที่จำเป็น อีกสิ่งหนึ่งคือการยืนยันด้วยลายเซ็นคือรหัส "การลงชื่อออก" ดังนั้นให้แน่ใจอีกครั้งว่าเป็น) ไม่ใช่ anti-CYA และ b) ไม่ต้องเปลืองแรง

11
@Barry“ การรีสตาร์ตก็เหมือนการโกหก ควรใช้เท่าที่จำเป็นอย่างยิ่ง” - นี่ไม่จริง เวิร์กโฟลว์ที่ใช้การ Rebase นั้นใช้ได้เช่นเดียวกับเวิร์กโฟลว์ที่ใช้การผสาน การรีบูตเป็นวิธีที่มีประสิทธิภาพเกินกว่าที่จะใช้อย่าง จำกัด
Lukas Juhrich

1
เมื่อใช้สิ่งนี้โดยเฉพาะกับ GitHub ที่ไม่ใช่ปัญหาการกระทำที่ผสานจะไม่ได้รับการลงนามโดยคุณเนื่องจาก GitHub ไม่สนับสนุนสิ่งนี้ ข้อได้เปรียบของการเซ็นชื่อทุกครั้ง (ไม่รวม) กระทำในสภาพแวดล้อมนี้คือมันทำให้เห็นได้ชัดมากเมื่อเพิ่มการกระทำหลอกลวงถูกเพิ่มผ่านทาง PR เพราะมันจะไม่ได้รับการลงนามด้วยคีย์ GPG ของคุณ
Arran Cudbard-Bell

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

1
@ ArranCudbard-Bell เช่นเดียวกับการอัพเดตคอมมิชชันคอมมิชชันถูกลงชื่อโดยคุณถ้าคุณตั้งค่าcommit.gpgsignเป็นจริงตามที่แนะนำโดย @VonC
Jay
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.