J'ai besoin que les horodatages des fichiers sur mon local et sur mon serveur soient synchronisés. Ceci est accompli avec Subversion en définissant use-commit-times = true dans la configuration afin que la dernière modification de chaque fichier ait lieu lors de sa validation.
Chaque fois que je cloné mon référentiel, je veux que les horodatages des fichiers reflètent la date de leur dernière modification dans le référentiel distant, et non le moment où j'ai cloné le référentiel.
Y a-t-il un moyen de faire cela avec git?
git annex
peut être utile pour garder une trace des imagesRéponses:
Je ne suis pas sûr que ce serait approprié pour un DVCS (comme dans le VCS «distribué»)
L'énorme discussion avait déjà eu lieu en 2007 (voir ce fil)
Et certaines réponses de Linus n'étaient pas trop enthousiastes à l'idée. Voici un exemple:
(Note: petite amélioration: après une extraction, les horodatages des fichiers à jour ne sont plus modifiés (Git 2.2.2+, janvier 2015): "git checkout - comment puis-je maintenir les horodatages lors du changement de branche?" .)
La longue réponse était:
la source
git
est un DVCS, pour manipuler le code source qui sera intégré à votre produit final. Si vous voulez un système de distribution, vous savez où le trouverrsync
.Si, cependant, vous voulez vraiment utiliser les heures de validation pour les horodatages lors de l'extraction, essayez d'utiliser ce script et placez-le (comme exécutable) dans le fichier $ GIT_DIR / .git / hooks / post-checkout:
Notez cependant que ce script entraînera un retard assez important pour l'extraction de grands référentiels (où grand signifie une grande quantité de fichiers, pas de grandes tailles de fichiers).
la source
| head -n 1
doit être évité car il engendre un nouveau processus,-n 1
cargit rev-list
etgit log
peut être utilisé à la place.`...`
etfor
; voir Pourquoi vous ne lisez pas les lignes avec "pour" . J'irais pourgit ls-files -z
etwhile IFS= read -r -d ''
.git show --pretty=format:%ai --abbrev-commit "$(get_file_rev "$1")" | head -n 1
vous pouvez fairegit show --pretty=format:%ai -s "$(get_file_rev "$1")"
, cela entraîne la génération de beaucoup moins de données par lashow
commande et devrait réduire la surcharge.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
À 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 pourgit 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é.
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:
Les performances sont assez impressionnantes, même pour les projets monstres
wine
,git
ou même le noyau Linux:la source
git
ne horodatages en magasin, etc. Il ne vient pas défini par défaut les horodateurs. Il suffit de regarder la sortie degit ls-files --debug
git ls-files
fonctionne sur le répertoire de travail et l'index, donc cela ne signifie pas qu'il stocke réellement ces informations sur le dépôt. Si elle stockait, récupérer (et appliquer) mtime serait trivial.J'ai pris la réponse de Giel et au lieu d'utiliser un script hook post-commit, je l'ai intégré dans mon script de déploiement personnalisé.
Mise à jour : J'ai également supprimé une
| head -n
suite à la suggestion de @ eregon et ajouté la prise en charge des fichiers contenant des espaces:la source
--abbrev-commit
est superflue engit show
raison de--pretty=format:%ai
son utilisation (le hachage de validation ne fait pas partie de la sortie) et| head -n 1
pourrait être remplacé par l'utilisation d'un-s
indicateur àgit show
%ai
est auteur date, ISO 8601 comme le format, pour le strict usage de ISO8601%aI
: git-scm.com/docs/git-shownous avons été obligés d'inventer encore une autre solution, car nous avions spécifiquement besoin de temps de modification et non de temps de validation, et la solution devait également être portable (c'est-à-dire que faire fonctionner python dans les installations git de Windows n'est vraiment pas une tâche simple) et rapide. Cela ressemble à la solution de David Hardeman, que j'ai décidé de ne pas utiliser en raison du manque de documentation (à partir du référentiel, je n'ai pas pu me faire une idée de ce que fait exactement son code).
Cette solution stocke les mtimes dans un fichier .mtimes dans le référentiel git, les met à jour en conséquence sur les commits (jsut sélectivement les mtimes des fichiers staged) et les applique à l'extraction. Cela fonctionne même avec les versions cygwin / mingw de git (mais vous devrez peut-être copier certains fichiers de cygwin standard dans le dossier de git)
La solution se compose de 3 fichiers:
pré-commit:
après le paiement
mtimestore - bash:
mtimestore - C ++
plus d'informations peuvent être trouvées ici https://github.com/kareltucek/git-mtime-extension certaines informations obsolètes sont à http://www.ktweb.cz/blog/index.php?page=page&id=116
// edit - version C ++ mise à jour:
// modifier voir github pour la version à jour
la source
Le script suivant incorpore les suggestions
-n 1
etHEAD
, fonctionne dans la plupart des environnements non Linux (comme Cygwin) et peut être exécuté lors d'une extraction après coup:En supposant que vous avez nommé le script ci-dessus
/path/to/templates/hooks/post-checkout
et / ou/path/to/templates/hooks/post-update
, vous pouvez l'exécuter sur un référentiel existant via:la source
Cette solution devrait fonctionner assez rapidement. Il définit des temps pour committer des temps et mtimes pour des temps d'auteur. Il n'utilise aucun module et doit donc être raisonnablement portable.
la source
Voici une version optimisée des solutions shell ci-dessus, avec des corrections mineures:
la source
Voici une méthode avec PHP:
C'est similaire à la réponse ici:
Quel est l'équivalent de use-commit-times pour git?
il construit une liste de fichiers comme cette réponse, mais il se construit à partir de
git ls-files
au lieu de simplement chercher dans le répertoire de travail. Cela résout le problème de l'exclusion.git
et résout également le problème des fichiers non suivis. De plus, cette réponse échoue si le dernier commit d'un fichier était un commit de fusion, que j'ai résolu avecgit log -m
. Comme l'autre réponse, s'arrêtera une fois que tous les fichiers seront trouvés, il n'est donc pas nécessaire de lire tous les validations. Par exemple avec:https://github.com/git/git
à partir de cette publication, il n'avait qu'à lire 292 commits. En outre, il ignore les anciens fichiers de l'historique selon les besoins, et il ne touchera pas un fichier qui a déjà été touché. Enfin cela semble être un peu plus rapide que l'autre solution. Résultats avec
git/git
repo:la source
J'ai vu quelques demandes pour une version Windows, alors la voici. Créez les deux fichiers suivants:
C: \ Program Files \ Git \ mingw64 \ share \ git-core \ templates \ hooks \ post-checkout
C: \ Program Files \ Git \ mingw64 \ share \ git-core \ templates \ hooks \ post-checkout.ps1
Cela utilise git whatchanged , donc il parcourt tous les fichiers en une seule passe au lieu d'appeler git pour chaque fichier.
la source
Je travaille sur un projet où je conserve un clone de mon référentiel pour une utilisation avec des
rsync
déploiements basés. J'utilise des branches pour cibler différents environnements etgit checkout
provoque le changement des modifications du fichier.Ayant appris que git ne fournit pas un moyen d'extraire des fichiers et de préserver les horodatages, je suis tombé sur la commande
git log --format=format:%ai --name-only .
dans une autre question SO: lister les dates de dernière validation pour un grand nombre de fichiers, rapidement .J'utilise maintenant le script suivant pour
touch
mes fichiers et répertoires de projet afin que mon déploiement avecrsync
soit plus facile à différencier:la source