Git, เขียนชื่อผู้ใช้และอีเมลก่อนหน้า


170

ฉันได้ทำคอมมิชชันให้กับโปรเจ็กต์ใน Github แต่ฉันรู้ว่าฉันไม่ได้ตั้งค่าอีเมลที่ถูกต้องและชื่อเต็มของคอมมิทเตอร์บนคอมพิวเตอร์ที่ฉันใช้งานอยู่ในขณะนี้เพื่อสร้างคอมมิทของฉัน ไม่ได้อยู่ที่นั่น

ฉันจะเขียนอีเมลและชื่อผู้ใช้ที่ผ่านมาทั้งหมดได้อย่างไร


9
ความเป็นไปได้ที่ซ้ำกันของฉันจะเปลี่ยนผู้แต่งคอมมิทได้อย่างไร?
givanse

ฉันพบสิ่งนี้หลังจากเปลี่ยนที่อยู่อีเมลในบัญชี GitHub ของฉัน นอกเหนือจากการผลักดันการเปลี่ยนรหัสจาก repo git ท้องถิ่นโดยใช้บรรทัดคำสั่ง git (ไม่ใช่เดสก์ท็อป GitHub) ฉันยังแก้ไขข้อความและไฟล์ที่จัดการโดยตรงจาก repo git ระยะไกลโดยใช้ GitHub เว็บอินเตอร์เฟส ที่อยู่อีเมลใหม่แพร่กระจายเฉพาะการกระทำที่เกิดขึ้นจากการกระทำครั้งหลังไม่ใช่ที่อยู่อีเมลเดิม
Robert John

คำตอบ:


243

คุณสามารถเพิ่มนามแฝงนี้:

git config alias.change-commits '!'"f() { VAR=\$1; OLD=\$2; NEW=\$3; shift 3; git filter-branch --env-filter \"if [[ \\\"\$\`echo \$VAR\`\\\" = '\$OLD' ]]; then export \$VAR='\$NEW'; fi\" \$@; }; f "

วิธีเปลี่ยนชื่อผู้แต่ง:

git change-commits GIT_AUTHOR_NAME "old name" "new name"

หรืออีเมลเฉพาะ 10 ข้อหลังล่าสุด:

git change-commits GIT_AUTHOR_EMAIL "old@email.com" "new@email.com" HEAD~10..HEAD

Alias:

change-commits="!f() { VAR=$1; OLD=$2; NEW=$3; shift 3; git filter-branch --env-filter \"if [[ \\\"$`echo $VAR`\\\" = '$OLD' ]]; then export $VAR='$NEW'; fi\" \$@; }; f "

ที่มา: https://github.com/brauliobo/gitconfig/blob/master/configs/.gitconfig


13
รวมgit change-commits GIT_COMMITTER_EMAIL "old@example.com" "new@example.com"ถึงการเปลี่ยนอีเมลของผู้ส่ง
เร

19
คงที่สำหรับ "eval: [[: ไม่พบ" บนอูบุนตูและเพิ่มการยืนยันchange-commits = "!f() { VAR1=$1; VAR='$'$1; OLD=$2; NEW=$3; echo \"Are you sure for replace $VAR $OLD => $NEW ?(Y/N)\";read OK;if [ \"$OK\" = 'Y' ] ; then shift 3; git filter-branch --env-filter \"if [ \\\"${VAR}\\\" = '$OLD' ]; then export $VAR1='$NEW';echo 'to $NEW'; fi\" $@; fi;}; f "
qxo

9
git: 'change-commits' ไม่ใช่คำสั่ง git ดู 'git --help' หมายถึงคุณยังไม่ได้เพิ่มนามแฝงในการกำหนดค่า git ของคุณ เช่น git config -e
Wayne

2
นี่เป็นการทำซ้ำของการกระทำทั้งหมดกับอีเมลที่ฉันต้องการเปลี่ยนแปลง ดูเหมือนจะไม่เขียนประวัติใหม่ @Olivier Verdier แก้ปัญหาให้ฉันได้ไหม
Jake Wilson

6
ทำสองครั้งในแถวที่มีอินพุตแตกต่างกันนำไปสู่:Cannot create a new backup. A previous backup already exists in refs/original/
theonlygusti

97

วิธีแก้ปัญหามีอยู่แล้ว: เปลี่ยนชื่อผู้แต่งและผู้สื่อสารและอีเมลของคอมมิทหลายรายการใน Git

กล่าวคือ

git filter-branch -f --env-filter \
"GIT_AUTHOR_NAME='Newname'; GIT_AUTHOR_EMAIL='newemail'; \
GIT_COMMITTER_NAME='committed-name'; GIT_COMMITTER_EMAIL='committed-email';" HEAD

4
สิ่งนี้จะไม่เปลี่ยนชื่อผู้แต่งสำหรับการกระทำทั้งหมด (ประวัติทั้งหมด) ของสาขาหรือไม่
hasen

2
ใช่ว่าจะเปลี่ยนทั้งหมดมุ่งมั่นที่จะเป็นข้อมูลผู้เขียนใหม่
eWall

9
โปรดทำเครื่องหมายคำถามซ้ำซ้อนแทนที่จะคัดลอกคำตอบ
givanse

2
จะทำอย่างไรถ้าฉันไม่ได้ระบุชื่อเก่าหรืออีเมลเก่า git พูดว่า "เปล่า ident <> ไม่อนุญาต"
Griffan

ฉันรันคำสั่งนี้และตอนนี้ repo ของฉันจะไม่ผลักหรือดึงจากเซิร์ฟเวอร์ git
พระเยซู H

46

หากคุณได้ผลักดันบางส่วนของการกระทำของคุณไปยังที่เก็บสาธารณะคุณไม่ต้องการที่จะทำเช่นนี้หรือมันจะทำให้รุ่นอื่นของประวัติต้นแบบที่คนอื่นอาจใช้ "อย่าข้ามลำธาร ... มันจะไม่ดี ... "

ที่กล่าวว่าหากเป็นเพียงข้อผูกพันที่คุณทำกับที่เก็บข้อมูลในพื้นที่ของคุณหมายความว่าแก้ไขก่อนที่จะส่งไปยังเซิร์ฟเวอร์ คุณสามารถใช้git filter-branchคำสั่งพร้อม--commit-filterตัวเลือกดังนั้นมันจะแก้ไขเฉพาะการกระทำที่ตรงกับข้อมูลที่ไม่ถูกต้องของคุณเช่นนี้

git filter-branch --commit-filter '
      if [ "$GIT_AUTHOR_EMAIL" = "wrong_email@wrong_host.local" ];
      then
              GIT_AUTHOR_NAME="Your Name Here (In Lights)";
              GIT_AUTHOR_EMAIL="correct_email@correct_host.com";
              git commit-tree "$@";
      else
              git commit-tree "$@";
      fi' HEAD

5
มันใช้งานได้ดีในขณะที่คำตอบที่ทำเครื่องหมายเป็นสีเขียวไม่ได้
jmary

หลังจากนั้นอาจต้องการล้างข้อมูลสำรองด้วยgit update-ref -d refs/original/refs/heads/masterดูที่ < stackoverflow.com/a/7654880/333403 >
cknoll

FYI: หากคุณมีชื่อ / อีเมลที่ไม่ถูกต้องหลายรายการคุณอาจต้องเรียกใช้หลายครั้ง หากสิ่งนั้นเกิดขึ้นมันจะส่งเสียงครวญครางคุณโดยมีข้อผิดพลาดนี้: A previous backup already exists in refs/original/ในกรณีนั้นให้เรียกใช้ใหม่พร้อมกับอีเมลใหม่และเพิ่มตัวเลือก-fก่อนหน้า - คอมมิชชันตัวกรอง ใช้ดุลยพินิจของคุณเอง มัก-fเป็นสิ่งอันตรายที่ต้องทำโดยไม่รู้ว่ากำลังทำอะไรอยู่
Chuck

19

หลังจากใช้คำตอบของ Olivier Verdier:

git filter-branch -f --env-filter \
"GIT_AUTHOR_NAME='Newname'; GIT_AUTHOR_EMAIL='newemail'; \
GIT_COMMITTER_NAME='committed-name'; GIT_COMMITTER_EMAIL='committed-email';" HEAD

... เพื่อพุชประวัติการเปลี่ยนแปลงบนที่เก็บต้นฉบับใช้:

git push origin +yourbranch

คำสั่งดังกล่าว (หมายเหตุบวก) กองกำลังเขียนประวัติบน repo เดิมเช่นกัน ใช้ด้วยความระมัดระวัง!


ได้ผลสำหรับฉันแล้วเขียนประวัติต้นกำเนิดอย่างถูกต้องอีกด้วย
Xeverous

10
สิ่งนี้จะต้องเขียนความมุ่งมั่นทั้งหมด - ไม่ว่าใครจะเป็นคนเขียนมัน ใช้ด้วยความระมัดระวัง
Bhavin Doshi

14

https://help.github.com/articles/changing-author-info/

#!/bin/sh

git filter-branch --env-filter '

OLD_EMAIL="oldEmail@xxx-MacBook-Pro.local"
CORRECT_NAME="yourName"
CORRECT_EMAIL="yourEmail"

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

ทั้งหมดนี้ใช้ได้สำหรับฉัน หลังจากกด git ตรวจสอบให้แน่ใจว่าได้เห็นการอัพเดตบนเว็บพอร์ทัลของ git หากการกระทำนั้นยังไม่ได้เชื่อมโยงกับบัญชีของฉันแสดงภาพขนาดย่อเริ่มต้นถัดจากการส่งและไม่ได้แสดงในแผนภูมิลำดับเวลาการมีส่วนร่วมของฉันไปที่ URL การกระทำและผนวก. แพทช์ที่ส่วนท้ายของ URL และยืนยันชื่อ และอีเมลถูกต้อง


ในขณะที่สิ่งนี้อาจตอบคำถามในทางทฤษฎีมันก็ควรที่จะรวมส่วนสำคัญของคำตอบที่นี่และให้ลิงค์สำหรับการอ้างอิง
jhpratt

1
นี่เป็นเพียงการเขียนใหม่ทุกสาขา
Bruno Zell

6

สำหรับผู้ที่ต้องการรุ่นวางคัดลอกง่าย (นอกเหนือจากการปรับปรุงอีเมลและชื่อ):

git config alias.change-commits '!'"f() { VAR=\$1; OLD=\$2; NEW=\$3; shift 3; git filter-branch --env-filter \"if [[ \\\"\$\`echo \$VAR\`\\\" = '\$OLD' ]]; then export \$VAR='\$NEW'; fi\" \$@; }; f "
git change-commits GIT_AUTHOR_NAME "<Old Name>" "<New Name>" -f
git change-commits GIT_AUTHOR_EMAIL <old@email.com> <new@email.com> -f
git change-commits GIT_COMMITTER_NAME "<Old Name>" "<New Name>" -f
git change-commits GIT_COMMITTER_EMAIL <old@email.com> <new@email.com> -f

5

เป็นไปได้มากที่ปัญหาจะเกิดขึ้นกับเทอร์มินัลที่จะหลบหนีสิ่งต่าง ๆ โดยอัตโนมัติ
Andrei Savin

3

พิจารณาการใช้git-filter-branchจะไม่ได้ต้องการที่จะทำในสิ่งเดียวกันในGit-กรอง repo (คุณอาจต้องติดตั้งมันเป็นครั้งแรกที่มีpip install git-filter-repo):

git-filter-repo --name-callback 'return name.replace(b"OldName", b"NewName")' --email-callback 'return email.replace(b"old@email.com", b"new@email.com")'

หากที่เก็บเป็นต้นฉบับโดยไม่มีรีโมตคุณจะต้องเพิ่ม--forceเพื่อบังคับให้เขียนซ้ำ (คุณอาจต้องการสร้างข้อมูลสำรองของ repo ของคุณก่อนทำสิ่งนี้)

หากคุณไม่ต้องการที่จะรักษา refs (พวกเขาจะปรากฏในประวัติศาสตร์สาขาของ Git GUI) --replace-refs delete-no-addคุณจะต้องเพิ่ม

สำหรับคุณลักษณะขั้นสูงเพิ่มเติมโปรดดูที่"การกรองของชื่อและอีเมล"

PS ที่ถูกขโมยและการปรับปรุงจากhttps://stackoverflow.com/a/59591928/714907

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.