PEMBARUAN : Solusi saya sekarang dikemas ke dalam Debian / Ubuntu / Mint, Fedora, Gentoo dan mungkin distro lain:
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, tidak menyimpan cap waktu (dan metadata lain seperti izin dan kepemilikan) adalah batasan besargit .
Alasan Linus tentang stempel waktu yang berbahaya hanya karena "membingungkan make" adalah timpang :
make clean cukup untuk memperbaiki masalah apa pun.
Berlaku hanya untuk project yang menggunakan make, kebanyakan C / C ++. Ini benar-benar diperdebatkan untuk skrip seperti Python, Perl, atau dokumentasi secara umum.
Hanya ada salahnya jika Anda menerapkan cap waktu. Tidak ada salahnya menyimpannya dalam repo. Menerapkannya bisa menjadi --with-timestampsopsi sederhana untuk git checkoutdan teman ( clone, pulldll), sesuai kebijaksanaan pengguna .
Baik Bazaar dan Mercurial menyimpan metadata. Pengguna dapat menerapkannya atau tidak saat check out. Tapi di git, karena stempel waktu asli bahkan tidak tersedia di repo, tidak ada opsi seperti itu.
Jadi, untuk keuntungan yang sangat kecil (tidak harus mengkompilasi ulang semuanya) yang spesifik untuk subset proyek, gitkarena DVCS umum lumpuh , beberapa informasi dari file hilang , dan, seperti yang dikatakan Linus, TIDAK MUDAH dilakukan sekarang. Sedih .
Karena itu, bolehkah saya menawarkan 2 pendekatan?
1 - http://repo.or.cz/w/metastore.git , oleh David Härdeman. Mencoba melakukan apa yang git seharusnya dilakukan di tempat pertama : menyimpan metadata (tidak hanya stempel waktu) di repo saat melakukan (melalui hook pre-commit), dan menerapkannya kembali saat menarik (juga melalui hook).
2 - Versi sederhana saya dari skrip yang saya gunakan sebelumnya untuk menghasilkan rilis tarball. Seperti yang disebutkan dalam jawaban lain, pendekatannya sedikit berbeda : untuk menerapkan stempel waktu setiap file dari komit terbaru tempat file dimodifikasi untuk setiap file .
- git-restore-mtime , dengan banyak opsi, mendukung tata letak repositori apa pun, dan berjalan di Python 3.
Di bawah ini adalah benar-benar telanjang-tulang versi script, sebagai bukti-of-konsep, di Python 2.7. Untuk penggunaan sebenarnya, saya sangat merekomendasikan versi lengkap di atas:
#!/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
Performanya cukup mengesankan, bahkan untuk proyek monster wine, gitatau bahkan kernel 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