it-swarm-vi.tech

Làm cách nào để chỉnh sửa lịch sử của git để sửa địa chỉ email / tên không chính xác

Khi tôi bắt đầu sử dụng git, tôi chỉ thực hiện git init Và bắt đầu gọi addcommit. Bây giờ tôi bắt đầu chú ý và tôi có thể thấy rằng các cam kết của tôi đang hiển thị dưới dạng [email protected], Chứ không phải là địa chỉ tôi muốn. Nó xuất hiện như thể cài đặt GIT_AUTHOR_EMAILGIT_COMMITTER_EMAIL Sẽ làm những gì tôi muốn, nhưng tôi vẫn có những cam kết cũ với địa chỉ email/tên sai. Làm thế nào tôi có thể sửa các cam kết cũ?

76
Chas. Owens

Bạn có thể quay lại và sửa tất cả các cam kết của mình bằng một cuộc gọi đến chi nhánh bộ lọc git. Điều này có tác dụng tương tự như rebase, nhưng bạn chỉ cần thực hiện một lệnh để sửa tất cả lịch sử của mình, thay vì sửa từng cam kết riêng lẻ.

Bạn có thể sửa tất cả các email sai bằng lệnh này:

git filter-branch --env-filter '
    oldname="(old name)"
    oldemail="(old email)"
    newname="(new name)"
    newemail="(new email)"
    [ "$GIT_AUTHOR_EMAIL"="$oldemail" ] && GIT_AUTHOR_EMAIL="$newemail"
    [ "$GIT_COMMITTER_EMAIL"="$oldemail" ] && GIT_COMMITTER_EMAIL="$newemail"
    [ "$GIT_AUTHOR_NAME"="$oldname" ] && GIT_AUTHOR_NAME="$newname"
    [ "$GIT_COMMITTER_NAME"="$oldname" ] && GIT_COMMITTER_NAME="$newname"
    ' HEAD

Thêm thông tin có sẵn từ git docs

82
andy

Lệnh nhánh lọc của Git rất mạnh, nhưng thật khó sử dụng cho bất kỳ thứ gì không tầm thường, chẳng hạn, nếu bạn có nhiều hơn một tác giả để sửa.

Đây là một giải pháp thay thế mà tôi thấy hữu ích, sử dụng tính năng .mailmap được mô tả trong trang chủ git-shortlog. Điều này cung cấp một cơ chế ánh xạ tác giả mà chúng ta có thể sử dụng với cơ sở định dạng của git log. Chúng ta có thể sử dụng nó để tạo các lệnh để chọn và sửa đổi sửa đổi một chuỗi các cam kết được đặt tên.

Ví dụ: giả sử bạn muốn sửa quyền tác giả trên một chi nhánh $ CHI NHÁNH, bắt đầu từ một cam kết $ START.

Bạn cần tạo một tệp .mailmap trong thư mục trên cùng của kho lưu trữ để ánh xạ tên tác giả hiện có thành tên chính xác. Bạn có thể nhận được một danh sách các tên tác giả hiện có với:

git shortlog -se

Bạn cần kết thúc với một tệp .mailmap như thế này (giả sử):

You <[email protected]>   [email protected]
You <[email protected]>   [email protected]

Bây giờ bạn có thể sử dụng tính năng định dạng của nhật ký git để tạo các lệnh để viết lại $ BRANCH thành $ BRANCH2.

git checkout -b $BRANCH2 $START
git log --reverse --pretty=format:"cherry-pick %H; commit --amend --author='%aN <%aE>' -C %H" $START..$BRANCH | sh - 

Lệnh đầu tiên tạo ra một nhánh trống mới mọc lên từ cam kết $ START. Đối với mỗi cam kết giữa $ START và sau đó là kết thúc $ BRANCH, lệnh thứ hai cherry chọn cam kết ban đầu vào cuối chi nhánh hiện tại $ BRANCH2 và sửa đổi nó để đặt chính xác cho tác giả.

Điều này cũng thường được áp dụng - hãy đặt cái này trong ~/.gitconfig:

[alias]
    # git reauthor $START..$END
    reauthor = !sh -c 'eval `git log --reverse --topo-order --pretty=format:\"git cherry-pick %H &&  git commit --amend -C %H --author=\\\"%aN <%aE>\\\" && \" $0 ` "echo success" '

Vì vậy, khi bạn cần sửa các tác giả, bây giờ bạn chỉ cần tạo một .mapfile và làm:

git checkout -b $BRANCH2 $START
git reauthor $START..$BRANCH

Tham chiếu nhánh gốc có thể được gán lại cho cái mới và cái mới bị xóa:

git checkout $BRANCH
git reset --hard $BRANCH2 # be careful with this command
git branch -d $BRANCH2
28
wu-lee

Kết hợp câu trả lời từ Làm cách nào để sửa lỗi siêu dữ liệu trên lần xác nhận đầu tiên trong git?

### Fix the first commit ###    
# create a temporary tag for the root-most commit so we can reference it
git tag root `git rev-list HEAD | tail -1`
# check it out on its own temporary branch
git checkout -b new-root root
# amend the commit
git commit --amend --author "Foo [email protected]"
# (or if you've set the proper git **config** values)
git commit --amend -C HEAD --reset-author
# now you've changed the commit message, so checkout the original branch again
git checkout @{-1}
# and rebase it onto your new root commit
git rebase --onto new-root root
### Fix the rest of the commits ###
git rebase -i root
# edit the file to read "edit <commit number> for each entry
# amend the commit
git commit --amend --author "Foo [email protected]"
# (or if you've set the proper git **config** values)
git commit --amend -C HEAD --reset-author
# move to the next commit
git rebase --continue    
# continue running the last two commands until you see
# Successfully rebased and updated refs/heads/master.
### Clean up ###
# nuke the temporary branch we created
git branch -d new-root
# nuke the temporary tag we created
git tag -d root
9
Chas. Owens

Để làm theo câu trả lời của jedberg: Bạn có thể sử dụng rebase -i và chọn chỉnh sửa các cam kết trong câu hỏi. Nếu bạn dùng git commit --amend --author <AUTHOR DETAILS> và sau đó git rebase continue bạn có thể đi qua và sửa chữa lịch sử.

5
Chealion