Có cách nào để Cam kết tự động cam kết trong Git bằng khóa GPG không?


213

Có cách nào dễ dàng để làm cho Git luôn ký mỗi cam kết hoặc thẻ được tạo không?

Tôi đã thử nó với một cái gì đó như:

bí danh commit = commit -S

Nhưng điều đó đã không làm nên chuyện.

Tôi không muốn cài đặt một chương trình khác để thực hiện điều này. Có thể làm được một cách dễ dàng?

Chỉ là một câu hỏi phụ, có thể các cam kết không nên được ký, chỉ các thẻ mà tôi không bao giờ tạo, khi tôi gửi các cam kết duy nhất cho một dự án như Homebrew, v.v.


8
Lý do bí danh của bạn đã làm việc là vì bạn không thể bí danh cho một lệnh đã tồn tại. (liên quan: stackoverflow.com/questions/5875275/git-commit-v-by-default stackoverflow.com/questions/2500586/... stackoverflow.com/questions/1278296/... )
Dan D.

2
Chỉ để biết thông tin: Viết lại tất cả các cam kết sẽ được đẩy để ký chúng: git filter-branch -f --commit-filter 'git commit-tree -S "$@"' HEAD@{u}..HEAD(Tôi không có nghĩa là bạn nên sử dụng điều này).
Vi.

Câu trả lời:


275

Lưu ý: nếu bạn không muốn thêm -Stoàn bộ thời gian để đảm bảo rằng các cam kết của bạn đã được ký, thì có một đề xuất (chi nhánh ' pu' bây giờ, tháng 12 năm 2013, vì vậy không có gì đảm bảo nó sẽ được phát hành git) để thêm cấu hình sẽ chăm sóc tùy chọn đó cho bạn.
Cập nhật tháng 5 năm 2014: đó là trong Git 2.0 (sau khi được gửi lại trong loạt bản vá này )

Xem cam kết 2af2ef3 của Nicolas Vigier (boklm) :

Thêm commit.gpgsigntùy chọn để ký tất cả các cam kết

Nếu bạn muốn GPG ký tất cả các cam kết của mình, bạn phải thêm -Stùy chọn mọi lúc.
Các commit.gpgsigntùy chọn cấu hình cho phép đăng ký tất cả các cam kết tự động.

commit.gpgsign

Boolean để xác định xem tất cả các cam kết có nên được ký GPG hay không.
Sử dụng tùy chọn này khi thực hiện các thao tác như rebase có thể dẫn đến một số lượng lớn các cam kết được ký kết. Có thể thuận tiện khi sử dụng một tác nhân để tránh nhập cụm mật khẩu GPG của bạn nhiều lần.


Cấu hình đó thường được đặt cho mỗi repo (bạn không cần phải ký các repos cục bộ thử nghiệm riêng tư của mình):

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

Bạn sẽ kết hợp điều đó với việc user.signingKeyđược sử dụng làm cài đặt chung (khóa duy nhất được sử dụng cho tất cả repo nơi bạn muốn ký cam kết)

git config --global user.signingkey F2C7AB29

user.signingKeyđã được giới thiệu trong git 1.5.0 (tháng 1 năm 2007) với cam kết d67778e :

Không nên có một yêu cầu là tôi sử dụng cùng một dạng tên của mình trong kho git và khóa gpg của tôi.
Hơn nữa tôi có thể có nhiều khóa trong khóa của mình và có thể muốn sử dụng một khóa không khớp với địa chỉ tôi sử dụng trong tin nhắn cam kết.

Bản vá này thêm một mục cấu hình " user.signingKey", nếu có, sẽ được chuyển đến công tắc "-u" cho gpg, cho phép ghi đè khóa ký thẻ.

Điều này được thi hành với cam kết aba9119 (git 1.5.3.2) để bắt trường hợp Nếu người dùng đã định cấu hình sai user.signingKeytrong họ .git/confighoặc chỉ không có bất kỳ khóa bí mật nào trong khóa của họ.

Ghi chú:


Điều đó thật tuyệt. Có một cách dễ dàng trên github làm một cái gì đó như git mô tả mà không cần phải tải xuống repo lỗ?

13
Bạn không cần phải ký các repos thử nghiệm riêng tư của mình ... nhưng tại sao bạn lại không?
Andy Hayden

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

Thay thế 9E08524833CB3038FDE385C54C0AFCCFED5CDE14 bằng ID khóa của bạn. Hãy nhớ rằng: Không bao giờ nên sử dụng ID ngắn .

CẬP NHẬT: Mỗi lần chỉnh sửa git mới , tất cả các khóa cấu hình phải ở trong camelCase.


Bạn vừa sao chép và dán nó từ câu trả lời của VonC ?
Robbie Averill

19
Không. Như bạn có thể thấy trong lịch sử phiên bản, ai đó đã thêm ví dụ của tôi vào câu trả lời của anh ấy. ED5CDE14 là khóa cá nhân của riêng tôi. Nhưng không có vấn đề.
Felipe

7
Kỳ quái. Tôi sẽ hoàn nguyên thay đổi vào ngày mai vì nó có vẻ tệ cho bạn
Robbie Averill

Làm thế nào để bạn tìm thấy ID ký chính của bạn? Ngoài ra, có phải chỉ có 1 khóa GPG cho tất cả các repo git của tôi không? bởi vì tôi không muốn phải xử lý 4 khóa khác trong các dự án được kết nối đẹp.
MarcusJ

1
Điều này có thể giúp người dùng Linux: Để đôi khi nó hoạt động (ví dụ trên Vim, sử dụng khóa được lưu trong thẻ thông minh yêu cầu nhập mã PIN), tôi đã phải chỉnh sửa ~/.gnupg/gpg-agent.confvà thêm pinentry-program /usr/bin/pinentry-gtk-2(theo hướng dẫn này wiki.archlinux.org/ index.php / GnuPG # pinentry )
iakovos Gurulian 6/2/2017

49

Chỉnh sửa: Tính đến Git phiên bản 1.7.9, có thể ký cam kết Git ( git commit -S). Cập nhật câu trả lời một chút để phản ánh điều này.

Tiêu đề câu hỏi là:

Có cách nào để Cam kết tự động cam kết trong Git bằng khóa GPG không?

Câu trả lời ngắn: có, nhưng đừng làm điều đó.

Giải quyết lỗi đánh máy trong câu hỏi: git commit -skhông ký cam kết. Thay vào đó, từ man git-committrang:

-s, --signoff
Thêm dòng đã ký bởi người ủy quyền ở cuối thông báo nhật ký cam kết.

Điều này cung cấp một đầu ra nhật ký tương tự như sau:


± $ 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 

Lưu ý bit "Đã ký tắt: ..."; được tạo bởi -scờ trên git-commit.

Trích dẫn email thông báo phát hành :

  • "Git commit" đã học "-S" cho GPG - ký cam kết; điều này có thể được hiển thị với tùy chọn "--show-chữ ký" thành "git log".

Vì vậy, có, bạn có thể ký cam kết. Tuy nhiên, cá nhân tôi kêu gọi thận trọng với tùy chọn này; tự động ký cam kết là vô nghĩa, xem bên dưới:

Chỉ là một câu hỏi phụ, có thể các cam kết không nên được ký, chỉ các thẻ mà tôi không bao giờ tạo, khi tôi gửi các cam kết duy nhất.

Đúng rồi. Cam kết không được ký kết; thẻ là. Lý do cho điều này có thể được tìm thấy trong tin nhắn này bởi Linus Torvalds , đoạn cuối cùng trong đó nói:

Ký mỗi cam kết là hoàn toàn ngu ngốc. Nó chỉ có nghĩa là bạn tự động hóa nó, và bạn làm cho chữ ký có giá trị ít hơn. Nó cũng không thêm bất kỳ giá trị thực nào, vì cách thức hoạt động của chuỗi DAG của SHA1, bạn chỉ cần một chữ ký để làm cho tất cả các cam kết có thể đạt được từ đó. Vì vậy, ký mỗi cam kết chỉ đơn giản là thiếu điểm.

Tôi khuyến khích duyệt qua tin nhắn được liên kết, điều này làm rõ lý do tại sao việc ký cam kết tự động không phải là một ý tưởng tốt theo cách tốt hơn nhiều so với tôi có thể.

Tuy nhiên , nếu bạn muốn tự động ký một thẻ , bạn sẽ có thể làm điều đó bằng cách gói git-tag -[s|u]bí danh; nếu bạn định làm điều đó, có lẽ bạn muốn thiết lập id khóa của mình trong tệp ~/.gitconfigcụ thể của dự án .git/config. Thông tin thêm về quá trình đó có thể được nhìn thấy trong cuốn sách cộng đồng git . Ký thẻ là vô cùng hữu ích hơn so với ký mỗi cam kết bạn thực hiện.


74
"Ký mỗi cam kết là hoàn toàn ngu ngốc." -> Cách nào tốt hơn để bảo đảm các cam kết khi có một nhà phát triển "chuột" thích đẩy các cam kết với tác giả và ủy viên giả mạo? Trừ khi có một số phép thuật hook trên máy chủ, anh ta có thể hướng git blameđến bất cứ ai anh ta muốn.
Vi.

11
0. một bài viết , 1. "là đủ để ký tất cả chúng" -> Cách nói "Tôi cho rằng đây thực sự là khác biệt của tôi (nhưng không chắc chắn về bất kỳ cam kết nào trước đó và tiếp theo). Tôi muốn đặt chữ ký vào cam kết của mình mà không xác nhận bất cứ điều gì về các cam kết tôi đã lấy từ máy chủ trung tâm / bất cứ điều gì. 2. Trong môi trường không tin cậy, vẫn cần có một công cụ đáng tin cậy để tìm ra ai là người có tội. Nếu máy chủ kiểm tra rằng tất cả các cam kết đều được ký bằng khóa email của người giao dịch, đó là khó giả mạo một cam kết (nếu bạn bảo mật máy tính của mình tốt).
Vi.

9
Ký một cam kết là đủ nếu mã không bao giờ thay đổi. Khi bạn thêm nhiều xác nhận, bạn sẽ cần thêm chữ ký. Việc ký một thẻ là đánh dấu mọi thứ LỚN hơn cam kết đó. Nếu bạn cần xác minh chi tiết tốt vì các cam kết đang đến, sẽ hợp lý khi ký từng cam kết. Nếu không, bạn sẽ phải sử dụng rất nhiều thẻ, điều này sẽ làm lộn xộn repo. Trên repos git từ xa được xác thực, bạn phải cung cấp mật khẩu hoặc khóa ssh mỗi khi bạn nhấn một cam kết, không chỉ khi bạn ấn thẻ. Đây là một tình huống tương tự.
Hans-Christoph Steiner

22
Tôi cảm thấy như Linus là thiếu điểm. Anh ta dường như có một trường hợp sử dụng hoàn toàn khác cho các cam kết đã ký trong tâm trí so với OP trong luồng đó. (Xác minh tính toàn vẹn của toàn bộ dự án, so với xác minh quyền tác giả của một cam kết duy nhất.)
Ajedi32

9
-1 cho "Có, nhưng đừng làm điều đó." Câu trả lời chỉ nên là "CÓ". Ký cam kết chứng minh tác giả, một cái gì đó có thể được nói dối trong cam kết.
Urda

6

Để thực hiện tự động ký công việc trước phiên bản git 2.0, bạn sẽ phải thêm bí danh git cho cam kết.

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

0

Bạn cần làm rõ rằng nếu bạn ký một cam kết hoặc thẻ, điều đó không có nghĩa là bạn chấp thuận toàn bộ lịch sử. Trong trường hợp cam kết, bạn chỉ ký thay đổi trong tay và trong trường hợp thẻ, tốt .. bạn cần xác định ý của bạn với nó. Bạn có thể đã lấy một thay đổi tuyên bố đó là từ bạn nhưng không phải (vì ai đó đã đẩy nó vào điều khiển từ xa của bạn). Hoặc đó là một thay đổi bạn không muốn tham gia, nhưng bạn vừa ký thẻ.

Trong các dự án OSS điển hình, điều này có thể ít phổ biến hơn, nhưng trong kịch bản doanh nghiệp nơi bạn chỉ chạm vào mã mỗi lần và sau đó bạn không đọc toàn bộ lịch sử, nó có thể không được chú ý.

Ký cam kết là một vấn đề nếu họ sẽ bị từ chối hoặc chọn anh đào cho các phụ huynh khác. Nhưng sẽ tốt hơn nếu một cam kết được sửa đổi có thể trỏ đến cam kết "gốc" thực sự xác minh.


3
Nổi loạn giống như nói dối. Nó nên được sử dụng quá ít. Một điều khác là cam kết với một chữ ký là mã "ký tắt", vì vậy hãy chắc chắn rằng đó là một) không chống CYA và b) không lãng phí nỗ lực.

11
@Barry Hồi Rebasing giống như nói dối. Nó nên được sử dụng cực kỳ tiết kiệm - điều này không đúng. Các quy trình công việc dựa trên Rebase cũng có giá trị như các quy trình công việc dựa trên hợp nhất. Rebasing là cách quá mạnh mẽ để được sử dụng một cách tiết kiệm.
Lukas Juhrich

1
Khi sử dụng riêng với GitHub, đây không phải là vấn đề, các cam kết hợp nhất sẽ không được bạn ký, vì GitHub không hỗ trợ điều này. Ưu điểm của việc ký kết mọi cam kết (không hợp nhất) trong môi trường này, là điều rất rõ ràng khi một cam kết giả mạo được thêm vào thông qua PR vì nó sẽ không được ký bằng khóa GPG của bạn.
Arran Cudbard-Bell

3
"Thật nguy hiểm nếu bạn ký một cam kết hoặc thẻ (cả hai sẽ ký toàn bộ lịch sử) rằng bạn có thể đã rút ra một thay đổi tuyên bố đó là từ bạn" Nếu bạn chỉ ký một cam kết mặc dù tôi sẽ không hiểu đó là một cam kết chứng thực của mọi cam kết có thể truy cập từ bạn. Bạn không nhất thiết phải tuyên bố rằng những thay đổi trong quá khứ là hợp lệ hoặc được bạn chứng thực, chỉ có điều bạn đã tạo ra một cam kết dựa trên những thay đổi đó. (Mặc dù với một thẻ, tôi đồng ý rằng bạn thực sự đang đăng xuất trên tất cả các cam kết có thể truy cập bằng thẻ.)
Ajedi32

1
@ ArranCudbard-Bell Cũng giống như một bản cập nhật, các cam kết hợp nhất được ký bởi bạn nếu bạn đặt commit.gpgsignthành đúng theo đề xuất của @VonC
Jay
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.