Quiero cambiar el autor de un commit específico en el historial. No es el último commit.
Conozco esta pregunta - [¿Cómo puedo cambiar el autor de un commit en git?
Pero estoy pensando en algo, donde identifico el commit por hash o short-hash.
Rebase interactivo a partir de un punto anterior en el historial al del commit que necesitas modificar (git rebase -i <earliercommit>
). En la lista de confirmaciones que se están rebaseando, cambia el texto de pick
a edit
al lado del hash de la que quieres modificar. Luego, cuando git te pida que cambies el commit, usa esto:
git commit --amend --author="Author Name <[email protected]>"
Por ejemplo, si tu historial de commit es A-B-C-D-E-F
con F
como HEAD
, y quieres cambiar el autor de C
y D
, entonces...
git rebase -i B
(aquí hay un ejemplo de lo que verás después de ejecutar el comando git rebase -i B
)A
, utiliza git rebase -i --root
C
y D
de pick
a edit
.C
.git commit --amend --author="Nombre del autor <[email protected]>"
.git rebase --continue
.D
.git commit --amend --author="Nombre del autor <[email protected]>"
de nuevogit push -f
para actualizar tu origen con los commits actualizados.Las respuestas en la pregunta a la que enlazaste son buenas respuestas y cubren tu situación (la otra pregunta es más general ya que implica reescribir múltiples commits).
Como excusa para probar git filter-branch
, escribí un script para reescribir el Nombre del Autor y/o el Email del Autor para un commit dado:
#!/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
Al hacer git rebase -i
hay esta parte interesante en la documentación:
Si quieres plegar dos o más confirmaciones en una, sustituye el comando "pick" para la segunda y siguientes confirmaciones con "squash" o "fixup". Si las confirmaciones tienen diferentes autores, la confirmación plegada se atribuirá al autor de la primera confirmación. El mensaje de confirmación sugerido para la confirmación plegada es la concatenación de los mensajes de confirmación de la primera confirmación y de aquellas con el comando "squash", pero omite los mensajes de confirmación de las confirmaciones con el comando "fixup".
A-B-C-D-E-F
,B
y D
(= 2 commits),entonces puedes hacer:
git config user.name "Corregir nuevo nombre"
git config user.email "[email protected]"
git commit --allow-empty -m "empty"
git rebase -i B^
B^
selecciona el padre de B
.pick
por squash
para esos.Ejemplo de lo que le 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
cámbialo por
# 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
Le pedirá que edite los mensajes:
# 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...
y podrás eliminar las primeras líneas.