Cách sửa đổi một số cam kết trong Git để thay đổi tác giả


180

Tôi đã thực hiện một loạt các cam kết trong Git và bây giờ tôi nhận ra rằng tôi đã quên đặt chính xác tên người dùng và thuộc tính email người dùng (máy mới). Tôi chưa đẩy các cam kết này vào kho lưu trữ của mình, vậy làm cách nào tôi có thể sửa các cam kết này trước khi tôi làm như vậy (chỉ có 3 cam kết mới nhất trên nhánh chính)?

Tôi đã nhìn git resetgit commit -C <id> --reset-author, nhưng tôi không nghĩ mình đang đi đúng hướng.


1
Một lý do khác mà bạn có thể muốn thay đổi thuộc tính email là lỗi github này: remote: error: GH007: Your push would publish a private email address.... `! [bị từ chối] master -> master (bị từ chối do hạn chế quyền riêng tư của email) `.
craq

Câu trả lời:


232

Rebase / sửa đổi có vẻ không hiệu quả, khi bạn có sức mạnh của nhánh lọc trong tầm tay:

git filter-branch --env-filter 'if [ "$GIT_AUTHOR_EMAIL" = "incorrect@email" ]; then
     GIT_AUTHOR_EMAIL=correct@email;
     GIT_AUTHOR_NAME="Correct Name";
     GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL;
     GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; fi' -- --all

(phân chia qua các dòng cho rõ ràng, nhưng không cần thiết)

Hãy chắc chắn kiểm tra kết quả khi bạn hoàn thành, để đảm bảo rằng bạn đã không thay đổi bất cứ điều gì bạn không có ý định!


tâm trí giải thích điều này nhiều hơn một chút? không chắc chắn nhánh lọc là gì
max pleaner

1
@maxpleaner git filter-branch --helpkhá đơn giản :)
alediaferia 10/07/2015

3
xem thêm help.github.com/articles/changing-author-info , mà cũng cho biết thêm --tag-name-filter catvào filter-branchđể thẻ di chuyển đến lịch sử mới. Nó cũng sử dụng --branches --tagsthay vì --all, chỉ viết lại lịch sử chi nhánh và thẻ và để lại refsmột mình (mặc dù điều đó có thể không tạo ra nhiều sự khác biệt trừ khi bạn đang sử dụng git-notes)
Tobias Kienzler

12
để thực hiện điều này chỉ trong hai lần xác nhận cuối cùng, tôi đã thay thế -- --allbằngHEAD~1..HEAD
nmz787

1
@ nmz787 Có bao nhiêu nhật ký được hiển thị nếu bạn làm git log HEAD~2..HEAD?
Jona

148

Cách tiếp cận rebase tương tác khá hay khi được sử dụng cùng với exec. Bạn có thể chạy bất kỳ lệnh shell nào đối với một cam kết cụ thể hoặc tất cả các xác nhận trong rebase.

Đầu tiên thiết lập cài đặt tác giả git của bạn

git config --global user.name "John Doe"
git config --global user.email johndoe@example.com

Sau đó, để thiết lập lại tác giả cho tất cả các cam kết sau SHA đã cho

git rebase -i YOUR_SHA -x "git commit --amend --reset-author -CHEAD"

Điều này sẽ bật lên trình soạn thảo của bạn để xác nhận những thay đổi. Tất cả những gì bạn cần làm ở đây là lưu và thoát và nó sẽ đi qua từng cam kết và chạy lệnh được chỉ định trong cờ -x.

Nhận xét của mỗi @ Dave bên dưới, bạn cũng có thể thay đổi tác giả trong khi duy trì dấu thời gian ban đầu bằng:

git rebase -i YOUR_SHA -x "git commit --amend --author 'New Name <new_address@example.com>' -CHEAD"

3
Cảm ơn bạn đã giới thiệu cho tôi tùy chọn -x. Nó thật tuyệt vời! đối với tùy chọn -i, tôi đã sử dụng HEAD ~ 4 để sửa địa chỉ email của mình trên 4 lần xác nhận gần nhất. làm việc như người ở.
Brad Hein

2
Điều này đơn giản hơn nhiều so với việc filter-branchbạn chỉ muốn sửa các cam kết cuối cùng của mình :). Tuy nhiên, lưu ý rằng điều này thay đổi dấu thời gian của các xác nhận.
luator

24
Để thay đổi tác giả nhưng duy trì dấu thời gian ban đầu, hãy sử dụnggit rebase -i YOUR_SHA -x "git commit --amend --author 'New Name <new_address@example.com>' -CHEAD"
Dave

2
@Connor git logcũng cho thấy quyền tác giả cũ đối với tôi, nhưng trạng thái git đã xác định chính xác các cam kết mới và sau khi đẩy mạnh chúng như tôi dự định.
Dan M.

6
Để rebase tất cả các cam kết bao gồm cả việc sử dụng root: git rebase -i --root …thay vì chuyển SHA.
gfullam

80

Để thay đổi tác giả chỉ cho lần cam kết cuối cùng:

git commit --amend --author 'Author Name <author.name@mail.com>' --no-edit

Giả sử bạn chỉ muốn thay đổi tác giả cho N lần xác nhận cuối cùng:

git rebase -i HEAD~4 -x "git commit --amend --author 'Author Name <author.name@mail.com>' --no-edit"

GHI CHÚ

  • những --no-editlàm cho lá cờ bảo git commit --amendkhông yêu cầu xác nhận thêm
  • Khi bạn sử dụng git rebase -i, bạn có thể chọn thủ công các thay đổi nơi tác giả,

tập tin bạn chỉnh sửa sẽ trông như thế này:

pick 897fe9e simplify code a little
pick abb60f9 add new feature
exec git commit --amend --author 'Author Name <author.name@mail.com>' --no-edit
pick dc18f70 bugfix

1
cho tất cả các cam kết từ gốc. git rebase -i --root UPTO_COMMIT_SHA -x "git commit --amend - Tác giả 'NEW_CHANGE' --no-edit"
Ashish Negi

1
Tôi khuyên bạn nên thêm tùy chọn --rebase-merges(ngắn -r), để giữ nguyên cấu trúc liên kết của chi nhánh nếu nó có chứa một số kết hợp.
donquixote

4

Đây phương pháp đã được ghi nhận bởi github cho mục đích này rất. Các bước là:

  1. Mở thiết bị đầu cuối và tạo một bản sao trần của repo của bạn
git clone --bare https://github.com/user/repo.git
cd repo
  1. Chỉnh sửa kịch bản sau (thay thế OLD_EMAIL, CORRECT_EMAILCORRECT_NAME)
#!/bin/sh

git filter-branch --env-filter '
OLD_EMAIL="your-old-email@example.com"
CORRECT_NAME="Your Correct Name"
CORRECT_EMAIL="your-correct-email@example.com"
if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_COMMITTER_NAME="$CORRECT_NAME"
    export GIT_COMMITTER_EMAIL="$CORRECT_EMAIL"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_AUTHOR_NAME="$CORRECT_NAME"
    export GIT_AUTHOR_EMAIL="$CORRECT_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags
  1. Sao chép / dán tập lệnh vào thiết bị đầu cuối của bạn và nhấn enter để chạy nó.
  2. Đẩy các thay đổi của bạn với git push --force --tags origin 'refs/heads/*'và bạn đã hoàn tất!

Tôi đã làm theo các hướng dẫn tương tự trên GitHub mà bạn đã tham chiếu và GitHub trông ngay bây giờ. Tuy nhiên, tôi là người mới sử dụng Git và không biết cách đồng bộ hóa repo cục bộ của mình sau đó. Khi tôi kéo, tôi nhận được cùng một lỗi "từ chối hợp nhất lịch sử không liên quan" được đề cập trong một câu trả lời khác. Tôi nghĩ rằng tôi cần phải chống lại lịch sử cam kết mới đó, nhưng tôi rất trân trọng các bước cụ thể hơn.
ban hành

@enigment nếu bạn hài lòng với repo như trên github, bạn có thể xóa (hoặc có thể di chuyển đến một vị trí khác) thư mục bạn có cục bộ và chỉ cần sao chép từ github
stevec

Cảm ơn, tôi biết, nhưng đó không giống như cách GitHub / Git thành ngữ.
ban hành


0

Nếu bạn cảm thấy không an toàn về việc gỡ lỗi và sửa đổi, bạn có thể làm theo cách này. Đồng thời, bạn cũng sẽ thiết lập cấu hình chung mà bạn có thể phải làm bằng mọi cách.

git reset HEAD~ (hoàn tác cam kết cuối cùng)

git config --global user.name "Your Name"

git config --global user.email you@example.com

git commit -m "message"

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.