git - ramas - ¿Cómo cambiar el autor de confirmación para una confirmación específica?
ver commits git (9)
Al hacer git rebase -i
hay un bit interesante en el documento:
Si desea plegar dos o más confirmaciones en una, reemplace el comando
"pick"
para la segunda y subsiguientes confirmaciones con"squash"
o"fixup"
. Si las confirmaciones tenían 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 aquellos con el comando"squash"
, pero omite los mensajes de confirmación de confirmaciones con el comando"fixup"
.
- Si tienes un historial de
ABCDEF
, - y quieres cambiar las confirmaciones
B
yD
(= 2 confirmaciones),
entonces puedes hacer
-
git config user.name "Correct new name"
-
git config user.email "[email protected]"
- Crear confirmaciones vacías (una para cada confirmación):
- Necesitas un mensaje para propósitos de rebase.
-
git commit --allow-empty -m "empty"
- iniciar la operación de rebase
-
git rebase -i B^
-
B^
selecciona el padre deB
-
- Usted querrá poner una confirmación vacía antes de cada confirmación para modificar
- Usted querrá cambiar
pick
tosquash
para esos.
Ejemplo de lo que git rebase -i B^
te dará:
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
cambiar eso a
# 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 simplemente puedes quitar las primeras líneas.
Quiero cambiar el autor de un commit específico en la historia. No es el último compromiso.
Sé sobre esta pregunta: ¿Cómo cambio el autor de un commit en git?
Pero estoy pensando en algo, donde identifico el cometer por hash o short-hash.
Comprometerse antes:
Para corregir el autor de todas las confirmaciones, puede aplicar el comando de la respuesta de @Ambar:
git commit --amend --author="Author Name <[email protected]>"
O para reutilizar su nombre y correo electrónico puede simplemente escribir:
git commit --amend --author=Eugen
Cometer después del comando:
Por ejemplo, para cambiar todo a partir de 4025621
:
Debes correr:
git rebase --onto 4025621 --exec "git commit --amend --author=Eugen" 4025621
Nota: para incluir un autor que contenga espacios, como un nombre y una dirección de correo electrónico, el autor debe estar rodeado de comillas de escape. Por ejemplo:
git rebase --onto 4025621 --exec "git commit --amend --author=/"Foo Bar <[email protected]>/"" 4025621
o agrega este alias en ~/.gitconfig
:
[alias]
reauthor = !bash -c ''git rebase --onto $1 --exec /"git commit --amend --author=$2/" $1'' --
Y luego ejecute:
git reauthor 4025621 Eugen
Hay un paso adicional a la respuesta de Amber si está utilizando un repositorio centralizado:
git push -f
para forzar la actualización del repositorio central.
Tenga cuidado de que no haya mucha gente trabajando en la misma rama porque puede arruinar la consistencia.
La documentación de Github contiene un script que reemplaza la información del remitente para todas las confirmaciones en una rama .
#!/bin/sh
git filter-branch --env-filter ''
OLD_EMAIL="[email protected]"
CORRECT_NAME="Your Correct Name"
CORRECT_EMAIL="[email protected]"
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
La respuesta aceptada a esta pregunta es un uso maravillosamente inteligente de la rebase interactiva, pero desafortunadamente muestra conflictos si el compromiso que intentamos cambiar el autor solía estar en una rama que posteriormente se fusionó. Más generalmente, no funciona. cuando se manejan historias desordenadas.
Ya que estoy preocupado por la ejecución de scripts que dependen de la configuración y el desarmado de variables de entorno para volver a escribir el historial de git, estoy escribiendo una nueva respuesta basada en esta publicación que es similar a esta respuesta pero es más completa.
Lo siguiente está probado y funcionando, a diferencia de la respuesta vinculada. Supongamos, para claridad de la exposición, que 03f482d6
es el compromiso cuyo autor estamos intentando reemplazar, y 42627abe
es el compromiso con el nuevo autor.
Compruebe el compromiso que estamos tratando de modificar.
git checkout 03f482d6
Haz que el autor cambie.
git commit --amend --author "New Author Name <New Author Email>"
Ahora tenemos un nuevo commit con hash que se supone que es
42627abe
.Revisa la sucursal original.
Reemplace el antiguo compromiso con el nuevo localmente.
git replace 03f482d6 42627abe
Reescriba todos los compromisos futuros basados en el reemplazo.
git filter-branch -- --all
Retire el reemplazo para la limpieza.
git replace -d 03f482d6
Presiona el nuevo historial (solo usa --force si falla lo siguiente, y solo después de verificar la cordura con
git log
y / ogit diff
).git push --force-with-lease
En lugar de 4-6, simplemente puedes cambiar a un nuevo commit:
git rebase -i 42627abe
Las respuestas en la pregunta a la que vinculó son buenas respuestas y cubren su situación (la otra pregunta es más general, ya que implica reescribir múltiples confirmaciones).
Como excusa para probar git filter-branch
, escribí un script para volver a escribir el nombre del autor y / o el correo electrónico del autor para un compromiso determinado:
#!/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
Puede cambiar el autor de la última confirmación con el comando siguiente.
git commit --amend --author="Author Name <[email protected]>"
Sin embargo, si desea cambiar más de un nombre de autor de confirmación, es un poco complicado. Debe iniciar una rebase interactiva, luego marcar las confirmaciones como ediciones, enmendarlas una por una y finalizar.
Empieza a git rebase -i
con git rebase -i
. Te mostrará algo como esto.
Cambie la palabra clave de pick
para edit
las confirmaciones que desea cambiar el nombre del autor.
Luego cierra el editor. Para los principiantes, :wq
Escape
luego escriba :wq
y :wq
Enter
.
Entonces verás tu terminal como si nada hubiera pasado. En realidad estás en medio de una rebase interactiva. Ahora es el momento de enmendar el nombre de autor de su confirmación usando el comando anterior. Se abrirá el editor de nuevo. Salir y continuar rebase con git rebase --continue
. Repita lo mismo para el recuento de confirmaciones que desea editar. Puede asegurarse de que la rebase interactiva haya finalizado cuando obtenga la No rebase in progress?
mensaje.
Rebase interactivo fuera de un punto anterior en el historial que el compromiso que necesita modificar ( git rebase -i <earliercommit>
). En la lista de confirmaciones que se rebasan, cambie el texto de pick
a edit
junto al hash del que desea modificar. Luego, cuando git te pide que cambies el commit, usa esto:
git commit --amend --author="Author Name <[email protected]>"
Por ejemplo, si su historial de confirmación es ABCDEF
con F
como HEAD
, y desea cambiar el autor de C
y D
, entonces ...
- Especifique
git rebase -i B
( este es un ejemplo de lo que verá después de ejecutar elgit rebase -i B
)- Si necesita editar
A
, usegit rebase -i --root
- Si necesita editar
- cambiar las líneas para
C
yD
depick
aedit
- Una vez que comenzó la rebase, primero se detendría en
C
-
git commit --amend --author="Author Name <[email protected]>"
- Entonces
git rebase --continue
- Se detendría de nuevo en
D
- Luego, volvería a
git commit --amend --author="Author Name <[email protected]>"
nuevo -
git rebase --continue
- La rebase se completaría.
- Utilice
git push -f
para actualizar su origen con las confirmaciones actualizadas.
Restablece tu correo electrónico a la configuración global:
git config --global user.email [email protected]
Ahora reinicie el autor de su confirmación sin necesidad de editar:
git commit --amend --reset-author --no-edit