Voglio cambiare l'autore di uno specifico commit nella storia. Non è l'ultimo commit.
So di questa domanda - Come posso cambiare l'autore di un commit in git?
Ma sto pensando a qualcosa, dove identifico il commit per hash o short-hash.
Il rebase interattivo parte da un punto precedente nella storia rispetto al commit che devi modificare (git rebase -i <earliercommit>
). Nella lista dei commit in fase di rebase, cambia il testo da pick
a edit
accanto all'hash di quello che vuoi modificare. Poi quando git ti chiede di cambiare il commit, usa questo:
git commit --amend --author="Author Name <[email protected]>"
Per esempio, se la tua cronologia di commit è A-B-C-D-E-F
con F
come HEAD
, e vuoi cambiare l'autore di C
e D
, allora dovresti...
git rebase -i B
(ecco un esempio di ciò che vedrete dopo l'esecuzione del comando git rebase -i B
)A
, usa git rebase -i --root
C
e D
da pick
a edit
C
.git commit --amend --author="Nome Autore <[email protected]>"
git rebase --continue
.D
.git commit --amend --author="Nome Autore <[email protected]>"
di nuovogit rebase --continue
.git push -f
per aggiornare la tua origine con i commit aggiornati.Le risposte nella domanda a cui ti sei collegato sono buone risposte e coprono la tua situazione (l'altra domanda è più generale poiché implica la riscrittura di più commit).
Come scusa per provare git filter-branch
, ho scritto uno script per riscrivere il nome dell'autore e/o l'email dell'autore per un dato commit:
#!/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
Quando si fa git rebase -i
c'è questo pezzo interessante nel documento:
Se vuoi piegare due o più commit in uno solo, sostituisci il comando "pick"
per il secondo e i successivi commit con "squash"
o "fixup"
. Se i commit hanno autori diversi, il commit ripiegato sarà attribuito all'autore del primo commit. Il messaggio di commit suggerito per il folded commit è la concatenazione dei messaggi di commit del primo commit e di quelli con il comando "squash"
, ma omette i messaggi di commit dei commit con il comando "fixup"
.
A-B-C-D-E-F
,B
e D
(= 2 commit),allora puoi fare:
git config user.name "Corretto nuovo nome"
git config user.email "[email protected]"
git commit --allow-empty -m "empty"
git rebase -i B^
B^
seleziona il genitore di B
.pick
in squash
per quelli.Esempio di cosa ti darà git rebase -i B^
:
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
cambialo in:
# 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
Ti chiederà di modificare i messaggi:
# 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...
e puoi semplicemente rimuovere le prime righe.