MISE À JOUR : Ma solution est maintenant intégrée à Debian / Ubuntu / Mint, Fedora, Gentoo et éventuellement d'autres distributions:
https://github.com/MestreLion/git-tools#install
sudo apt install git-restore-mtime # Debian/Ubuntu/Mint
yum install git-tools # Fedora/ RHEL / CentOS
emerge dev-vcs/git-tools # Gentoo
À mon humble avis, ne pas stocker les horodatages (et d'autres métadonnées comme les autorisations et la propriété) est une grande limitation de git
.
La justification de Linus selon laquelle les horodatages sont nuisibles simplement parce qu'ils «confondent make
» est boiteuse :
make clean
suffit à résoudre les problèmes.
S'applique uniquement aux projets qui utilisent make
, principalement C / C ++. C'est complètement inutile pour les scripts comme Python, Perl ou la documentation en général.
Il n'y a de mal que si vous appliquez les horodatages. Il n'y aurait aucun mal à les stocker en pension. Les appliquer pourrait être une simple --with-timestamps
option pour git checkout
et amis ( clone
, pull
etc.), à la discrétion de l' utilisateur .
Bazaar et Mercurial stockent les métadonnées. Les utilisateurs peuvent les appliquer ou non lors de la vérification. Mais dans git, puisque les horodatages d'origine ne sont même pas disponibles dans le dépôt, il n'y a pas une telle option.
Donc, pour un très petit gain (ne pas avoir à tout recompiler) qui est spécifique à un sous-ensemble de projets, git
comme un DVCS général a été paralysé , certaines informations sur les fichiers sont perdues , et, comme l'a dit Linus, c'est INFEASIBLE à faire maintenant. Triste .
Cela dit, puis-je proposer 2 approches?
1 - http://repo.or.cz/w/metastore.git , par David Härdeman. Essaie de faire ce qui git
aurait dû être fait en premier lieu : stocke les métadonnées (pas seulement les horodatages) dans le dépôt lors de la validation (via un hook de pré-validation), et les réapplique lors de l'extraction (également via des hooks).
2 - Mon humble version d'un script que j'utilisais auparavant pour générer des archives tar. Comme mentionné dans d'autres réponses, l'approche est un peu différente : appliquer pour chaque fichier l' horodatage du commit le plus récent où le fichier a été modifié.
- git-restore-mtime , avec de nombreuses options, prend en charge toute disposition de référentiel et fonctionne sur Python 3.
Vous trouverez ci-dessous une version vraiment simple du script, comme preuve de concept, sur Python 2.7. Pour une utilisation réelle, je recommande fortement la version complète ci-dessus:
#!/usr/bin/env python
# Bare-bones version. Current dir must be top-level of work tree.
# Usage: git-restore-mtime-bare [pathspecs...]
# By default update all files
# Example: to only update only the README and files in ./doc:
# git-restore-mtime-bare README doc
import subprocess, shlex
import sys, os.path
filelist = set()
for path in (sys.argv[1:] or [os.path.curdir]):
if os.path.isfile(path) or os.path.islink(path):
filelist.add(os.path.relpath(path))
elif os.path.isdir(path):
for root, subdirs, files in os.walk(path):
if '.git' in subdirs:
subdirs.remove('.git')
for file in files:
filelist.add(os.path.relpath(os.path.join(root, file)))
mtime = 0
gitobj = subprocess.Popen(shlex.split('git whatchanged --pretty=%at'),
stdout=subprocess.PIPE)
for line in gitobj.stdout:
line = line.strip()
if not line: continue
if line.startswith(':'):
file = line.split('\t')[-1]
if file in filelist:
filelist.remove(file)
#print mtime, file
os.utime(file, (mtime, mtime))
else:
mtime = long(line)
# All files done?
if not filelist:
break
Les performances sont assez impressionnantes, même pour les projets monstres wine
, git
ou même le noyau Linux:
bash
# 0.27 seconds
# 5,750 log lines processed
# 62 commits evaluated
# 1,155 updated files
git
# 3.71 seconds
# 96,702 log lines processed
# 24,217 commits evaluated
# 2,495 updated files
wine
# 13.53 seconds
# 443,979 log lines processed
# 91,703 commits evaluated
# 6,005 updated files
linux kernel
# 59.11 seconds
# 1,484,567 log lines processed
# 313,164 commits evaluated
# 40,902 updated files