Necesito que las marcas de tiempo de los archivos en mi local y en mi servidor estén sincronizadas. Esto se logra con Subversion estableciendo use-commit-times = true en la configuración para que la última modificación de cada archivo sea cuando se comprometió.
Cada vez que clono mi repositorio, quiero que las marcas de tiempo de los archivos reflejen cuándo se cambiaron por última vez en el repositorio remoto, no cuándo cloné el repositorio.
¿Hay alguna forma de hacer esto con git?
git annex
podría ser útil para realizar un seguimiento de las imágenesRespuestas:
No estoy seguro de que esto sea apropiado para un DVCS (como en VCS "distribuido")
La gran discusión ya había tenido lugar en 2007 (ver este hilo)
Y algunas de las respuestas de Linus no estaban muy interesadas en la idea. Aquí hay una muestra:
(Nota: pequeña mejora: después de un pago, las marcas de tiempo de los archivos actualizados ya no se modifican (Git 2.2.2+, enero de 2015): "git checkout: ¿cómo puedo mantener las marcas de tiempo al cambiar de sucursal?" ).
La respuesta larga fue:
fuente
git
es un DVCS, para manipular el código fuente que se construyó en su producto final. Si desea un sistema de distribución, ya sabe dónde encontrarlorsync
.Sin embargo, si realmente desea usar los tiempos de confirmación para las marcas de tiempo al realizar el pago, intente usar este script y colóquelo (como ejecutable) en el archivo $ GIT_DIR / .git / hooks / post-checkout:
Sin embargo, tenga en cuenta que esta secuencia de comandos provocará una demora bastante grande para verificar repositorios grandes (donde grande significa una gran cantidad de archivos, no grandes tamaños de archivo).
fuente
| head -n 1
debe evitarse, ya que genera un nuevo proceso,-n 1
paragit rev-list
ygit log
se puede utilizar en su lugar.`...`
yfor
; consulte Por qué no lee líneas con "para" . Yo iría porgit ls-files -z
ywhile IFS= read -r -d ''
.git show --pretty=format:%ai --abbrev-commit "$(get_file_rev "$1")" | head -n 1
que puede hacergit show --pretty=format:%ai -s "$(get_file_rev "$1")"
, hace que elshow
comando genere muchos menos datos y debería reducir la sobrecarga.ACTUALIZACIÓN : Mi solución ahora está empaquetada en Debian / Ubuntu / Mint, Fedora, Gentoo y posiblemente otras distribuciones:
https://github.com/MestreLion/git-tools#install
En mi humilde opinión, no almacenar marcas de tiempo (y otros metadatos como permisos y propiedad) es una gran limitación de
git
.El razonamiento de Linus de que las marcas de tiempo sean dañinas solo porque "confunden
make
" es poco convincente :make clean
es suficiente para solucionar cualquier problema.Se aplica solo a proyectos que utilizan
make
, principalmente C / C ++. Es completamente discutible para scripts como Python, Perl o documentación en general.Solo hay daño si aplica las marcas de tiempo. No haría ningún daño almacenarlos en repositorio. Aplicarlos podría ser una
--with-timestamps
opción sencilla paragit checkout
y amigos (clone
,pull
etc.), a discreción del usuario .Tanto Bazaar como Mercurial almacenan metadatos. Los usuarios pueden aplicarlos o no al momento de pagar. Pero en git, dado que las marcas de tiempo originales ni siquiera están disponibles en el repositorio, no existe tal opción.
Entonces, para una ganancia muy pequeña (no tener que volver a compilar todo) que es específica de un subconjunto de proyectos,
git
ya que un DVCS general se paralizó , se pierde parte de la información de los archivos y, como dijo Linus, es INFEASIBLE hacerlo Es ahora. Sad .Dicho esto, ¿puedo ofrecer 2 enfoques?
1 - http://repo.or.cz/w/metastore.git , por David Härdeman. Intenta hacer lo que
git
debería haber hecho en primer lugar : almacena metadatos (no solo marcas de tiempo) en el repositorio cuando se confirma (a través de un gancho de confirmación previa) y los vuelve a aplicar al extraer (también a través de ganchos).2 - Mi versión humilde de un script que usé antes para generar tarballs de lanzamiento. Como se mencionó en otras respuestas, el enfoque es un poco diferente : aplicar para cada archivo la marca de tiempo de la confirmación más reciente donde se modificó el archivo.
A continuación se muestra una versión realmente básica del script, como prueba de concepto, en Python 2.7. Para el uso real, recomiendo encarecidamente la versión completa anterior:
El rendimiento es bastante impresionante, incluso para proyectos monstruosos
wine
,git
o incluso para el kernel de Linux:fuente
git
hace marcas de tiempo de las tiendas, etc. Simplemente no establece las marcas de tiempo por defecto. Basta con mirar a la salidagit ls-files --debug
git ls-files
opera en el directorio y el índice de trabajo, por lo que no significa que realmente almacene esa información en el repositorio. Si almacenara, recuperar (y aplicar) mtime sería trivial.Tomé la respuesta de Giel y en lugar de usar un script de enlace posterior a la confirmación, lo trabajé en mi script de implementación personalizado.
Actualización : también
| head -n
eliminé uno siguiendo la sugerencia de @ eregon y agregué soporte para archivos con espacios en ellos:fuente
--abbrev-commit
es superfluogit show
debido a que--pretty=format:%ai
se usa (el hash de confirmación no es parte de la salida) y| head -n 1
podría reemplazarse con el uso de la-s
bandera paragit show
%ai
es la fecha del autor, formato similar a ISO 8601 , para uso estricto de iso8601%aI
: git-scm.com/docs/git-shownos vimos obligados a inventar otra solución, porque necesitábamos tiempos de modificación específicos y no tiempos de compromiso, y la solución también tenía que ser portátil (es decir, conseguir que Python funcionara en las instalaciones git de Windows no es una tarea sencilla) y rápida. Se parece a la solución de David Hardeman, que decidí no usar debido a la falta de documentación (del repositorio no pude hacerme una idea de qué hace exactamente su código).
Esta solución almacena mtimes en un archivo .mtimes en el repositorio de git, los actualiza en consecuencia en las confirmaciones (jsut selectivamente los mtimes de los archivos en etapas) y los aplica al finalizar la compra. Funciona incluso con las versiones cygwin / mingw de git (pero es posible que deba copiar algunos archivos de cygwin estándar en la carpeta de git)
La solución consta de 3 archivos:
pre cometido:
post-pago
mtimestore - bash:
mtimestore - c ++
se puede encontrar más información aquí https://github.com/kareltucek/git-mtime-extension. Hay información desactualizada en http://www.ktweb.cz/blog/index.php?page=page&id=116
// editar - versión de c ++ actualizada:
// editar ver github para una versión actualizada
fuente
El siguiente script incorpora las sugerencias
-n 1
yHEAD
, funciona en la mayoría de los entornos que no son de Linux (como Cygwin) y se puede ejecutar en una caja después del hecho:Suponiendo que nombró el script anterior
/path/to/templates/hooks/post-checkout
y / o/path/to/templates/hooks/post-update
, puede ejecutarlo en un repositorio existente a través de:fuente
Esta solución debería ejecutarse con bastante rapidez. Establece tiempos para confirmar tiempos y mtimes para tiempos de autor. No utiliza módulos, por lo que debería ser razonablemente portátil.
fuente
Aquí hay una versión optimizada de las soluciones de shell anteriores, con correcciones menores:
fuente
Aquí hay un método con PHP:
Es similar a la respuesta aquí:
¿Cuál es el equivalente de use-commit-times para git?
crea una lista de archivos como esa respuesta, pero se basa en en
git ls-files
lugar de simplemente buscar en el directorio de trabajo. Esto resuelve el problema de la exclusión.git
y también resuelve el problema de los archivos sin seguimiento. Además, esa respuesta falla si la última confirmación de un archivo fue una combinación de confirmación, con la que resolvígit log -m
. Al igual que la otra respuesta, se detendrá una vez que se encuentren todos los archivos, por lo que no tiene que leer todas las confirmaciones. Por ejemplo con:https://github.com/git/git
a partir de esta publicación, solo tenía que leer 292 confirmaciones. También ignora los archivos antiguos del historial según sea necesario, y no tocará un archivo que ya se haya tocado. Finalmente parece ser un poco más rápido que la otra solución. Resultados con
git/git
repositorio:fuente
Vi algunas solicitudes para una versión de Windows, así que aquí está. Cree los siguientes dos archivos:
C: \ Archivos de programa \ Git \ mingw64 \ share \ git-core \ templates \ hooks \ post-checkout
C: \ Archivos de programa \ Git \ mingw64 \ share \ git-core \ templates \ hooks \ post-checkout.ps1
Esto utiliza git whatchanged , por lo que se ejecuta a través de todos los archivos en una sola pasada en lugar de llamar a git para cada archivo.
fuente
Estoy trabajando en un proyecto en el que guardo un clon de mi repositorio para usarlo con
rsync
implementaciones basadas. Utilizo ramas para apuntar a diferentes entornos ygit checkout
hace que las modificaciones del archivo cambien.Habiendo aprendido que git no proporciona una forma de verificar archivos y preservar las marcas de tiempo, encontré el comando
git log --format=format:%ai --name-only .
en otra pregunta SO: Enumere las últimas fechas de confirmación para una gran cantidad de archivos, rápidamente .Ahora estoy usando la siguiente secuencia de comandos para
touch
los archivos y directorios de mi proyecto para que mi implementaciónrsync
sea más fácil de diferenciar:fuente