Pertanyaan Bagaimana cara mengubah penulis komit untuk satu komitmen tertentu?


Saya ingin mengubah penulis satu komit spesifik dalam sejarah. Ini bukan komitmen terakhir.

Saya tahu tentang pertanyaan ini - Bagaimana cara mengubah penulis komit di git?

Tapi saya sedang memikirkan sesuatu, di mana saya mengidentifikasi komit dengan hash atau hash pendek.


1380
2018-06-15 04:00


asal


Jawaban:


Rebase interaktif dari titik sebelumnya dalam sejarah daripada komitmen yang perlu Anda ubah (git rebase -i <earliercommit>). Di daftar komit yang sedang diubah, ubah teks dari pick untuk edit di samping hash yang ingin Anda modifikasi. Kemudian ketika git meminta Anda untuk mengubah commit, gunakan ini:

git commit --amend --author="Author Name <email@address.com>"

Misalnya, jika sejarah komitmen Anda A-B-C-D-E-F dengan F sebagai HEAD, dan Anda ingin mengubah penulis C dan D, maka Anda akan ...

  1. Menentukan git rebase -i B (di sini adalah contoh dari apa yang akan Anda lihat setelah mengeksekusi git rebase -i B perintah)
    • jika Anda perlu mengedit A, gunakan git rebase -i --root
  2. ubah garis untuk keduanya C dan D dari pick untuk edit
  3. Setelah rebase dimulai, pertama-tama akan berhenti C
  4. Anda akan melakukannya git commit --amend --author="Author Name <email@address.com>"
  5. Kemudian git rebase --continue
  6. Itu akan berhenti lagi di D
  7. Maka Anda akan melakukannya git commit --amend --author="Author Name <email@address.com>" lagi
  8. git rebase --continue
  9. Rebase akan selesai.

2315
2018-06-15 04:31



Itu jawaban yang diterima untuk pertanyaan ini adalah penggunaan rebase interaktif yang sangat cerdas, tetapi sayangnya menunjukkan konflik jika komit yang kita coba ubah penulis digunakan untuk berada di cabang yang kemudian digabungkan. Lebih umum, tidak berfungsi saat menangani berantakan sejarah.

Karena saya khawatir tentang menjalankan skrip yang bergantung pada pengaturan dan unsetting variabel lingkungan untuk menulis ulang sejarah git, saya menulis jawaban baru berdasarkan posting ini yang mirip dengan jawaban ini tetapi lebih lengkap.

Berikut ini diuji dan berfungsi, tidak seperti jawaban yang ditautkan. Asumsikan kejelasan eksposisi itu 03f482d6 adalah komit yang penulisnya kami coba ganti, dan 42627abe adalah komitmen dengan penulis baru.

  1. Periksa komitmen yang kami coba ubah.

    git checkout 03f482d6
    
  2. Buat penulis berubah.

    git commit --amend --author "New Author Name <New Author Email>"
    

    Sekarang kita memiliki komitmen baru dengan hash yang diasumsikan 42627abe.

  3. Periksa cabang asli.

  4. Ganti commit lama dengan yang baru secara lokal.

    git replace 03f482d6 42627abe
    
  5. Tulis ulang semua komitmen di masa mendatang berdasarkan penggantian.

    git filter-branch -- --all
    
  6. Hapus pengganti untuk kebersihan.

    git replace -d 03f482d6
    
  7. Dorong sejarah baru (gunakan hanya - kekuatan jika yang di bawah gagal, dan hanya setelah memeriksa kewarasan dengan git log dan / atau git diff).

    git push --force-with-lease
    

Daripada 4-6 Anda dapat langsung melakukan rebase ke commit baru:

git rebase -i 42627abe

311
2018-03-04 02:11



Dokumentasi Github berisi skrip yang menggantikan info komuter untuk semua commit di cabang.

#!/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

128
2018-06-09 16:02



Anda dapat mengubah penulis commit terakhir menggunakan perintah di bawah ini.

git commit --amend --author="Author Name <email@address.com>"

Namun, jika Anda ingin mengubah lebih dari satu nama pengarang komit, itu sedikit rumit. Anda perlu memulai rebase interaktif lalu menandai commit sebagai edit kemudian ammend mereka satu per satu dan selesai.

Mulai rebase dengan git rebase -i. Ini akan menunjukkan sesuatu seperti ini kepada Anda.

https://monosnap.com/file/G7sdn66k7JWpT91uiOUAQWMhPrMQVT.png

Mengubah pick kata kunci untuk edit untuk komit Anda ingin mengubah nama penulis.

https://monosnap.com/file/dsq0AfopQMVskBNknz6GZZwlWGVwWU.png

Kemudian tutup editor. Untuk pemula, tekan Escape lalu ketikkan :wq dan tekan Enter.

Maka Anda akan melihat terminal Anda seperti tidak ada yang terjadi. Sebenarnya Anda berada di tengah-tengah rebase interaktif. Sekarang saatnya untuk mengubah nama penulis komit Anda menggunakan perintah di atas. Ini akan membuka editor lagi. Berhenti dan lanjutkan rebase dengan git rebase --continue. Ulangi hal yang sama untuk jumlah commit yang ingin Anda edit. Anda dapat memastikan bahwa rebase interaktif selesai ketika Anda mendapatkan No rebase in progress? pesan.


60
2017-08-29 00:52



  • Setel ulang email Anda ke konfigurasi secara global:

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

  • Sekarang atur ulang penulis commit Anda tanpa perlu mengedit:

    git commit --amend --reset-author --no-edit


52
2018-04-05 12:44



Jawaban dalam pertanyaan yang Anda tautkan adalah jawaban yang baik dan mencakup situasi Anda (pertanyaan lain lebih umum karena melibatkan penulisan ulang beberapa commit).

Sebagai alasan untuk mencoba git filter-branch, Saya menulis naskah untuk menulis ulang Nama Penulis dan / atau Email Penulis untuk komitmen yang diberikan:

#!/bin/sh

#
# Change the author name and/or email of a single commit.
#
# change-author [-f] commit-to-change [branch-to-rewrite [new-name [new-email]]]
#
#     If -f is supplied it is passed to "git filter-branch".
#
#     If <branch-to-rewrite> is not provided or is empty HEAD will be used.
#     Use "--all" or a space separated list (e.g. "master next") to rewrite
#     multiple branches.
#
#     If <new-name> (or <new-email>) is not provided or is empty, the normal
#     user.name (user.email) Git configuration value will be used.
#

force=''
if test "x$1" = "x-f"; then
    force='-f'
    shift
fi

die() {
    printf '%s\n' "$@"
    exit 128
}
targ="$(git rev-parse --verify "$1" 2>/dev/null)" || die "$1 is not a commit"
br="${2:-HEAD}"

TARG_COMMIT="$targ"
TARG_NAME="${3-}"
TARG_EMAIL="${4-}"
export TARG_COMMIT TARG_NAME TARG_EMAIL

filt='

    if test "$GIT_COMMIT" = "$TARG_COMMIT"; then
        if test -n "$TARG_EMAIL"; then
            GIT_AUTHOR_EMAIL="$TARG_EMAIL"
            export GIT_AUTHOR_EMAIL
        else
            unset GIT_AUTHOR_EMAIL
        fi
        if test -n "$TARG_NAME"; then
            GIT_AUTHOR_NAME="$TARG_NAME"
            export GIT_AUTHOR_NAME
        else
            unset GIT_AUTHOR_NAME
        fi
    fi

'

git filter-branch $force --env-filter "$filt" -- $br

46
2018-06-15 05:24



Saat melakukan git rebase -i ada sedikit yang menarik di dokumen ini:

Jika Anda ingin melipat dua atau lebih commit menjadi satu, ganti perintah "pick" untuk komit kedua dan selanjutnya dengan "squash" atau "fixup". Jika komit memiliki penulis yang berbeda, komitmen terlipat akan dikaitkan dengan penulis komit pertama. Pesan komit yang disarankan untuk komitmen terlipat adalah gabungan dari pesan komit dari komit pertama dan dari yang memiliki "squash" perintah, tetapi menghilangkan pesan commit dari commit dengan "fixup" perintah.

  • Jika Anda memiliki riwayat A-B-C-D-E-F,
  • dan Anda ingin mengubah commit B dan D (= 2 commit),

maka Anda bisa melakukan:

  • git config user.name "Correct new name"
  • git config user.email "correct@new.email"
  • membuat commit kosong (satu untuk setiap commit):
    • Anda membutuhkan pesan untuk tujuan rebase
    • git commit --allow-empty -m "empty"
  • memulai operasi rebase
    • git rebase -i B^
    • B^ memilih induk dari B.
  • Anda akan ingin menempatkan satu komit kosong sebelum masing-masing berkomitmen untuk memodifikasi
  • Anda akan ingin berubah pick untuk squash untuk itu.

Contoh apa git rebase -i B^ akan memberimu:

pick sha-commit-B some message
pick sha-commit-C some message
pick sha-commit-D some message
pick sha-commit-E some message
pick sha-commit-F some message
# pick sha-commit-empty1 empty
# pick sha-commit-empty2 empty

ubah itu menjadi:

# change commit B's author
pick sha-commit-empty1 empty
squash sha-commit-B some message
# leave commit C alone
pick sha-commit-C some message
# change commit D's author
pick sha-commit-empty2 empty
squash sha-commit-D some message
# leave commit E-F alone
pick sha-commit-E some message
pick sha-commit-F some message

Ini akan meminta Anda untuk mengedit pesan:

# This is a combination of 2 commits.
# The first commit's message is:

empty

# This is the 2nd commit message:

...some useful commit message there...

dan Anda cukup menghapus beberapa baris pertama.


12
2017-08-28 01:03



Ada satu langkah tambahan untuk Jawaban Amber jika Anda menggunakan repositori terpusat:

git push -f untuk memaksa pembaruan repositori pusat.

Hati-hati karena tidak banyak orang yang bekerja di cabang yang sama karena dapat merusak konsistensi.


11
2017-12-20 15:06