¿Hay alguna forma en git de obtener una fecha de envío para una confirmación determinada?

93

Me pregunto si hay una forma de ver una fecha de inserción asociada con cada confirmación en el registro de git. Si eso no es posible, ¿hay alguna manera de ver todas las confirmaciones bajo un cierto impulso?

Estoy escribiendo un programa que necesita realizar un seguimiento de las confirmaciones a medida que se envían. Debido a que el registro de git está ordenado por la fecha de confirmación, no por la fecha de envío, no puedo ver las confirmaciones más recientes que se envían. Por ejemplo, si un usuario se compromete con su repositorio local 2 días antes de enviar al maestro, esa confirmación se colocará 2 días después de otras confirmaciones en el registro del repositorio maestro.

justkikuchi
fuente

Respuestas:

77

Me tomó un tiempo increíblemente largo reunir información dispersa y finalmente encontrar la mejor respuesta a esta pregunta, pero ahora sé que la tengo. En solo dos líneas, sin código y sin ganchos:

# required for a bare repo
git config core.logAllRefUpdates true

git reflog --date=local master

Simple al fin.

Advertencia: probablemente desee anular los valores predeterminados de gc.reflogExpirey gc.reflogExpireUnreachable. Verifique los git help reflogdetalles y comprenda cómo y por qué funciona esto.

Los dos comandos anteriores deben ejecutarse dentro del clon al que presionas . Si eso no es posible, entonces se ejecutará una aproximación en otro clon permanente :

git fetch               origin        # often and *regularly*
git reflog --date=local origin/master

Nunca elimine este clon permanente o perderá las fechas.

Marzo
fuente
2
Me gustaría agregar que en mi caso tuve que hacer git reflog --date=local origin/master(nota origin/) para ver la lista de empujes. De lo contrario, solo las confirmaciones, las cajas y las extracciones estaban en la lista (lo que también es útil). En realidad, me lo señaló la respuesta de @ JonathanDay .
NIA
@NIA: origin / master solo te dará una aproximación. Actualicé mi respuesta después de tu comentario, ¿esto aclara?
MarcH
37

Git es un sistema de control de versiones distribuido, por lo que debe definir cuidadosamente lo que quiere decir con "fecha de envío". Por ejemplo, supongamos que el usuario A envía algunas confirmaciones al repositorio del usuario B. Algún momento después, el usuario B envía esas mismas confirmaciones a un tercer repositorio. ¿Qué fecha te interesa?

Estoy especulando que tienes un repositorio compartido y quieres que los usuarios de ese repositorio compartido puedan determinar cuándo se publicó algo en el repositorio. Si eso es cierto, deberá recopilar esa información en el repositorio compartido.

Las malas noticias

Desafortunadamente, no hay forma de agregar la fecha a los mensajes de confirmación. Eso cambiaría el ID de confirmación (que es un hash SHA1 del contenido), causando todo tipo de problemas.

Las buenas noticias

Afortunadamente, Git tiene una característica (relativamente nueva) llamada notas . Esta función le permite adjuntar texto arbitrario a las confirmaciones, que se git logpueden mostrar. Las notas se pueden editar y compartir con otros.

Puede utilizar la función de notas para adjuntar un mensaje de "esta confirmación se recibió el [fecha]" a cada confirmación tal como la recibe el repositorio compartido.

Consulte git help notespara obtener más detalles.

Cómo registrar la fecha

Este es el enfoque que recomiendo:

  1. Modifique el post-receiveenlace en su repositorio compartido para recorrer cada nueva confirmación accesible para cada referencia actualizada.
  2. Para cada confirmación, agregue algo como "[usuario] de [repository_url] agregó esta confirmación a [ref] el [fecha]" a la nota de la confirmación.

    Es posible que desee utilizar una referencia de notas dedicada a este propósito (como refs/notes/received-on) en lugar de la predeterminada refs/notes/commits. Esto evitará conflictos con notas creadas para otros fines.

  3. Modifique su receivegancho para denegar actualizaciones a la referencia de sus notas (para evitar que los usuarios jueguen accidentalmente o intencionalmente con las notas).
  4. Diga a todos los usuarios que ejecuten los siguientes comandos desde dentro de su árbol de trabajo:

    # Fetch all notes from the shared repository.
    # Assumes the shared repository remote is named 'origin'.
    git config --add remote.origin.fetch '+refs/notes/*:refs/remote-notes/origin/*'
    
    # Show all notes from the shared repository when running 'git log'
    git config --add notes.displayRef 'refs/remote-notes/origin/*'
    

    Este paso es necesario porque Git ignora las referencias que no son ramas ni etiquetas en los repositorios ascendentes de forma predeterminada.

Lo anterior asume que las referencias solo son avanzadas, nunca se eliminan o se actualizan a la fuerza. Probablemente desee que el post-receivegancho también agregue notas de "eliminado el [fecha]" para manejar estos casos.

Richard Hansen
fuente
He usado tu idea en mi blog mnaoumov.wordpress.com/2013/01/31/git-get-push-date
mnaoumov
8
git reflog show origin/master --pretty='%h %gd %gs %s' --date=iso

Esto parece funcionar bastante bien para mí. La fecha de confirmación (% cd) es engañosa porque no es necesariamente la misma que la fecha de envío. La opción --date = iso, sin embargo, generará la fecha de inserción / recuperación .

Tenga en cuenta que si lo obtuvo de origen / maestro, se imprimirá la fecha en que lo obtuvo; NO la fecha en que alguien más presionó el compromiso.

 - %h:  abrev. hash
 - %gd: human readable reflog selector
 - %gs: reflog subject
 - %s:  subject/commit message

Bono: por supuesto, puede hacer un formateo más bonito. Hasta ahora, me gusta este código de colores. Sin embargo, es un poco demasiado para escribir. Esto hará que el SHA se vuelva rojo, el selector de reenganche a cian y el reenganche sujeto a verde.

git reflog show origin/master --pretty='format:%C(red)%h%Creset %C(cyan)%gd%Creset %C(green)%gs%Creset: %s' --date=iso
VC
fuente
Hola VC, ¿significa que si la salida del comando "reflog show origin / master --pretty = '% Cred% h% Creset -% C (amarillo)% gd% Creset% Cblue (% gs)% Creset% s' - -date = iso "es" da4c192cd -origin / master @ {2019-02-07 08:13:40 +0100} (pull: fast-forward) JIRA-2542 mejorar el informe de prueba ", significa que el contenido de mi rama JIRA -2542 se fusionó en origin / master a través de un fast-froward en 2019-02-07 08:13:40?
Simon
Hola Simon, si. Hiciste un git pull en tu rama y se fusionó en origin / master vía avance rápido en ese momento.
VC
Funciona solo en el repositorio del autor. Si clono un repositorio, el valor está vacío. No puedes ver el tiempo de empuje de otras personas.
ramwin
6

Échale un vistazo git reflog show master. Probablemente no sea el formato exacto que desea, pero debería apuntarle en la dirección correcta.

Otra idea es ejecutar un script dentro de un push hook.

Karl Bielefeldt
fuente
Pensé en ejecutar el gancho de empuje, pero parece que debería ser un último esfuerzo. Con un gancho, parece que todos los usuarios deberían tener ese gancho en cada uno de sus repositorios. ¿Puede ser más específico sobre el git reflog show master? Quiero poder ver la fecha de envío de las confirmaciones individuales de cada usuario.
justkikuchi
git reflog muestra el orden de los cambios en cualquier repositorio en el que lo ejecutes . No estoy seguro de si hay una forma directa de obtener la fecha, pero .git/logs/refs/heads/mastermuestra una marca de tiempo.
Karl Bielefeldt
3
En cuanto a los ganchos, no se reciben los ganchos que se ejecutan en la máquina que empuja a . Dado que empujar solo es relevante en relación con un repositorio específico, supongo que tiene un determinado repositorio "bendecido" en el que desea ejecutarlo. Lo mismo ocurre git reflogcon el asunto.
Karl Bielefeldt
5

Esta respuesta con respecto a la inspección del reflog en el control remoto podría ayudar ( https://stackoverflow.com/a/8791295/336905 ) al brindarle información sobre qué rama se empujó incluso a través de ella, no muestra qué confirmaciones se enviaron, pero usted podría correlacionarse encontrando el siguiente impulso después de la fecha de confirmación local. No infalible, pero útil si aún no ha implementado la excelente sugerencia de notas de @RichardHansen publicada anteriormente

Día de Jonathan
fuente
1
Con una nota de que reflog of origin/branchsolo mostrará los cambios realizados en la máquina actual , ¡esto es extremadamente útil! Para el uso diario, no quiero implementar ningún gancho, así que para una simple pregunta "Hmmm, ¿cuándo presioné ese compromiso la semana pasada?" - funciona muy bien.
NIA
4

También puede consultar la hora de modificación del archivo del objeto de confirmación en el directorio "objetos" del repositorio git del servidor.

Rico
fuente
3

¿Por qué git AuthorDate es diferente de CommitDate?

  • AuthorDate es cuando se creó la confirmación por primera vez.
  • CommitDate es cuando la confirmación se modificó por última vez (por ejemplo, rebase).

Puede obtenerlos con las --prettyopciones de formato:

       o    %cd: committer date
       o    %cD: committer date, RFC2822 style
       o    %cr: committer date, relative
       o    %ct: committer date, UNIX timestamp
       o    %ci: committer date, ISO 8601 format

Entonces, si usted y otros desarrolladores lo están haciendo git rebaseantes git push, terminarán con una fecha de confirmación posterior a la fecha del autor .

Este comando muestra la fecha de confirmación: git log --pretty=fuller

dnozay
fuente
1

Supongo que puede usar la siguiente notación para obtener la fecha de inserción: git log -g --date = local

Pashh PGH
fuente