UPDATE : Meine Lösung ist jetzt in Debian / Ubuntu / Mint, Fedora, Gentoo und möglicherweise anderen Distributionen verpackt:
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
IMHO ist das Nicht-Speichern von Zeitstempeln (und anderen Metadaten wie Berechtigungen und Besitz) eine große Einschränkung von git.
Linus 'Begründung, Zeitstempel seien schädlich, nur weil sie "verwirren make", ist lahm :
make clean reicht aus, um Probleme zu beheben.
Gilt nur für Projekte, die makehauptsächlich C / C ++ verwenden. Es ist für Skripte wie Python, Perl oder Dokumentation im Allgemeinen völlig umstritten.
Es schadet nur, wenn Sie die Zeitstempel anwenden . Es würde nicht schaden, sie im Repo zu lagern . Anwenden von ihnen könnte eine einfache seine --with-timestampsOption für git checkoutund Freunde ( clone, pullusw.), auf den Benutzer setzen zu müssen .
Sowohl Bazaar als auch Mercurial speichern Metadaten. Benutzer können sie beim Auschecken anwenden oder nicht. Aber in Git gibt es keine solche Option , da die ursprünglichen Zeitstempel nicht einmal im Repo verfügbar sind .
Für einen sehr kleinen Gewinn (der nicht alles neu kompilieren muss), der für eine Teilmenge von Projekten spezifisch ist , gehen einige Informationen über Dateien verloren , gitda ein allgemeines DVCS verkrüppelt wurde , und wie Linus sagte, ist es UNMÖGLICH, dies zu tun es jetzt. Traurig .
Darf ich zwei Ansätze anbieten?
1 - http://repo.or.cz/w/metastore.git , von David Härdeman. Versucht, das zu tun, was git eigentlich hätte getan werden sollen : Speichert Metadaten (nicht nur Zeitstempel) beim Festschreiben im Repo (über den Pre-Commit-Hook) und wendet sie beim Ziehen erneut an (auch über Hooks).
2 - Meine bescheidene Version eines Skripts, das ich zuvor zum Generieren von Release-Tarballs verwendet habe. Wie in anderen Antworten erwähnt, ist der Ansatz etwas anders : Für jede Datei wird der Zeitstempel des letzten Commits angewendet , bei dem die Datei geändert wurde.
- git-restore-mtime mit vielen Optionen unterstützt jedes Repository-Layout und läuft unter Python 3.
Im Folgenden finden Sie eine wirklich einfache Version des Skripts als Proof-of-Concept für Python 2.7. Für den tatsächlichen Gebrauch empfehle ich dringend die obige Vollversion:
#!/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
Die Leistung ist ziemlich beeindruckend, auch für Monster - Projekte wine, gitoder sogar den Linux - Kernel:
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