Sự khác biệt giữa tác giả và người đi làm trong Git?


235

Tôi đang cố gắng để thực hiện một cam kết như

git commit --author="John Doe <john@doe.com>" -m "<the usual commit message>"

trong đó John Doe là một số người dùng mà tôi muốn thực hiện cam kết.

Nó xuất hiện tất cả ngay trong git log. Tuy nhiên, khi tôi thực hiện gitk, tên tác giả là chính xác, nhưng tên người gửi được chọn từ cài đặt cấu hình git toàn cầu của tôi (và do đó được đặt thành tên / email của tôi).

Câu hỏi

  1. Sự khác biệt giữa hai (committer vs tác giả) là gì?

  2. Tôi có nên thiết lập committer cho người dùng khác không?

  3. Nếu có, làm thế nào?




Git committer được đặt trong tệp .gitconfig. Nếu bạn - tác giả giống như tên .gitconfig, bạn chỉ nhận được tác giả trong thông điệp cam kết. Nếu chúng khác nhau, bạn nhận được cả hai.
poGUIst

Câu trả lời:


214

Người đăng ban đầu hỏi:

Sự khác biệt giữa hai (Committer vs tác giả) là gì?

Tác giả là người ban đầu viết mã. Mặt khác, người ủy quyền được coi là người đã thực hiện mã thay mặt cho tác giả ban đầu. Điều này rất quan trọng trong Git vì Git cho phép bạn viết lại lịch sử hoặc áp dụng các bản vá thay cho người khác. Các miễn phí trực tuyến Pro Git cuốn sách giải thích nó như thế này:

Bạn có thể tự hỏi sự khác biệt giữa tác giả và người đi làm . Các tác giả là người ban đầu đã viết các bản vá, trong khi có duyên là người cuối cùng áp dụng các bản vá. Vì vậy, nếu bạn gửi một bản vá cho một dự án và một trong những thành viên cốt lõi áp dụng bản vá đó, cả hai bạn đều nhận được tín dụng - bạn là tác giả và thành viên cốt lõi là người đi làm.

Người đăng ban đầu hỏi:

Tôi có nên thiết lập committer cho người dùng khác không?

Không, nếu bạn muốn trung thực, bạn không nên đặt committer cho tác giả, trừ khi tác giả và committer thực sự là cùng một người.


1
Tôi vẫn còn bối rối về điều này. Tôi đã có điều này xảy ra, và trong trường hợp của tôi, theo như tôi biết, không có bản vá hoặc lịch sử viết lại nào xảy ra (trừ khi một số lệnh git tạo và áp dụng các bản vá, một cách ngẫu nhiên, "dưới mui xe"). Đây có phải là 2 cách duy nhất để điều này xảy ra không?
chăn bò

2
Ngoài ra, gọi tác giả là "người đã viết mã" không có ý nghĩa gì. Làm thế nào git biết ai đã viết nó? Khi bạn thiết lập git config uservà sau đó git addgit commit, sau đó git sẽ biết ai đã thêm và người cam kết, nhưng nó vẫn sẽ không biết ai đã viết nó.
chăn bò

1
@cowlinator Nó không biết ai đã viết mã. Đó là lý do tại sao bạn phải nói với nó, nếu đó không phải là bạn. Hãy nhớ rằng hệ thống kiểm soát phiên bản phân tán trước đó trước khi git được phát minh đã gửi ~ ~ Linus ~ ~ email bảo trì dự án với các bản vá để áp dụng. Chức năng này là có vì vậy ~ ~ Linus ~ ~ người bảo trì có thể áp dụng bản vá của bạn trong khi vẫn ghi có cho bạn theo cách 'chính thức', thay vì chỉ quảng cáo trong thông điệp cam kết.
Vụ kiện của Quỹ Monica

92

Danh sách gửi thư + git format-patch+ git applycó thể tạo tác giả! = Committer

Trong các dự án như nhân Linux, nơi các bản vá là:

tạo ra một cam kết mới với tác giả và người đi làm khác nhau:

  • tác giả là người đã viết bản vá
  • người giao dịch là người duy trì dự án và là người hợp nhất bản vá

Xem ví dụ bản vá được chọn ngẫu nhiên này và cam kết tương ứng:

Các giao diện web Git như GitHub và GitLab có thể hoặc không thể tạo tác giả! = Committer

Vì Git (Hub | Lab) giữ cả kho lưu trữ ngược dòng và ngã ba trên cùng một máy, chúng có thể tự động làm bất cứ điều gì bạn có thể làm tại địa phương, bao gồm cả:

  • Tạo một cam kết hợp nhất.

    Không tạo tác giả! = Committer.

    Giữ nguyên SHA hoặc cam kết mới và tạo ra một cam kết mới:

    * Merge commit (committer == author == project maintainer)
    |\
    | * Feature commit (committer == author == contributor)
    |/
    * Old master (random committer and author)
    

    Trong lịch sử, đây là phương pháp có sẵn đầu tiên trên GitHub.

    Tại địa phương, điều này được thực hiện với git merge --no-ff.

    Điều này tạo ra hai cam kết cho mỗi yêu cầu kéo và giữ một ngã ba trong lịch sử git.

  • nổi loạn trên đỉnh master

    GitHub cũng hack các cam kết để đặt committer == bất cứ ai nhấn nút hợp nhất. Điều này không bắt buộc và thậm chí không được thực hiện theo mặc định tại địa phương git rebase, nhưng nó mang lại trách nhiệm cho người duy trì dự án.

    Cây git bây giờ trông như:

    * Feature commit (committer == maintainer, author == contributor)
    |
    * Old master (random committer and author)    
    

    đó là chính xác như của các git applybản vá email.

Trên GitHub hiện tại:

  • bạn chọn phương thức khi hợp nhất thông qua menu thả xuống trên nút hợp nhất
  • phương thức có thể được bật hoặc tắt trên cài đặt repo của chủ sở hữu

https://help.github.com/articles/about-merge-methods-on-github/

Làm thế nào để thiết lập committer của một cam kết mới?

Điều tốt nhất tôi có thể tìm thấy là sử dụng các biến môi trường để ghi đè lên committer:

GIT_COMMITTER_NAME='a' GIT_COMMITTER_EMAIL='a' git commit --author 'a <a>'

Làm thế nào để có được cam kết và ngày cam kết của một cam kết nhất định?

Chỉ có dữ liệu tác giả hiển thị theo mặc định trên git log.

Để xem ngày bắt đầu, bạn có thể:

  • định dạng nhật ký cụ thể cho điều đó:

    git log --pretty='%cn %cd' -n1 HEAD
    

    ở đâu cncdđứng cho Committer NameCommitter Date

  • sử dụng fullerđịnh dạng được xác định trước:

    git log --format=fuller
    

    Xem thêm: Cách định cấu hình 'nhật ký git' để hiển thị 'ngày cam kết'

  • ở mức thấp và hiển thị toàn bộ dữ liệu cam kết:

    git cat-file -p HEAD
    

Làm cách nào để đặt ngày bắt đầu của một cam kết mới?

git commit --date chỉ đặt ngày tác giả: đối với ngày giao dịch, điều tốt nhất tôi có thể tìm thấy là với biến môi trường:

GIT_COMMITTER_DATE='2000-01-01T00:00:00+0000' git commit --date='2000-01-01T00:00:00+0000'

Xem thêm: Sự khác biệt giữa tác giả và người đi làm trong Git là gì?

Làm thế nào Git lưu trữ tác giả vs committer trong nội bộ?

Xem: Định dạng tệp của đối tượng cam kết git là gì?

Về cơ bản, cam kết là một tệp văn bản và nó chứa hai trường được phân tách bằng dòng:

author {author_name} <{author_email}> {author_date_seconds} {author_date_timezone}
committer {committer_name} <{committer_email}> {committer_date_seconds} {committer_date_timezone}

Điều này làm rõ rằng cả hai là hai mục nhập dữ liệu hoàn toàn độc lập trong đối tượng cam kết.


1
Lưu ý rằng ngay cả khi GIT_COMMITTER_*ghi đè, git vẫn sẽ từ chối thực hiện cam kết nếu bạn chưa đặt một bộ chuyển đổi mặc định bằng cách sử dụng git config.
adelphus

1
@adelphus trên Git 2.5, nó hoạt động nếu bạn đặt cả haiGIT_{COMMITTER,AUTHOR}_EMAIL
Ciro Santilli 郝海东 冠状 病 六四 事件

3

@Ciro Santilli 心 心đề xuất sử dụng

GIT_COMMITTER_NAME='a' GIT_COMMITTER_EMAIL='a' git commit --author 'a <a>'

Để tránh lặp lại tên và email, bạn có thể sử dụng lại chúng

GIT_COMMITTER_NAME='a'; GIT_COMMITTER_EMAIL='a'; git commit --author "$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"

đầu tiên đặt các biến trong các lệnh riêng biệt, sau đó sử dụng chúng cho git commitcuộc gọi (lưu ý dấu ngoặc đơn).

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.