CẬP NHẬT : Giải pháp của tôi hiện đã được đóng gói thành Debian / Ubuntu / Mint, Fedora, Gentoo và có thể là các bản phân phối khác:
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, không lưu trữ dấu thời gian (và các siêu dữ liệu khác như quyền và quyền sở hữu) là một hạn chế lớngit
.
Cơ sở lý luận của Linus về việc dấu thời gian có hại chỉ vì nó "nhầm lẫn make
" là khập khiễng :
make clean
là đủ để sửa chữa mọi vấn đề.
Chỉ áp dụng cho các dự án sử dụng make
, chủ yếu là C / C ++. Nó là hoàn toàn tranh luận cho các tập lệnh như Python, Perl hoặc tài liệu nói chung.
Chỉ có hại nếu bạn áp dụng các dấu thời gian. Sẽ không có hại gì khi lưu trữ chúng trong repo. Áp dụng chúng có thể là một --with-timestamps
lựa chọn đơn giản cho git checkout
và bạn bè ( clone
, pull
v.v.), theo quyết định của người dùng .
Cả siêu dữ liệu cửa hàng Bazaar và Mercurial. Người dùng có thể áp dụng chúng hoặc không khi thanh toán. Nhưng trong git, vì dấu thời gian gốc thậm chí không có sẵn trong repo, nên không có tùy chọn như vậy.
Vì vậy, đối với một lợi ích rất nhỏ (không phải biên dịch lại mọi thứ) cụ thể cho một tập hợp con của các dự án, git
vì một DVCS chung đã bị tê liệt , một số thông tin từ các tệp bị mất và, như Linus đã nói, KHÔNG THỂ LÀM ĐƯỢC. nó bây giờ. Buồn .
Điều đó nói rằng, tôi có thể đưa ra 2 cách tiếp cận không?
1 - http://repo.or.cz/w/metastore.git , của David Härdeman. Cố gắng thực hiện những gì đáng git
lẽ phải làm ngay từ đầu : lưu trữ siêu dữ liệu (không chỉ dấu thời gian) trong repo khi cam kết (thông qua hook trước khi cam kết) và áp dụng lại chúng khi kéo (cũng như qua hook).
2 - Phiên bản khiêm tốn của tôi về một script mà tôi đã sử dụng trước đây để tạo tarball phát hành. Như đã đề cập trong các câu trả lời khác, cách tiếp cận hơi khác một chút : áp dụng cho mỗi tệp dấu thời gian của lần cam kết gần đây nhất mà tệp đã được sửa đổi.
- git-restore-mtime , với nhiều tùy chọn, hỗ trợ mọi bố cục kho lưu trữ và chạy trên Python 3.
Dưới đây là phiên bản thực sự đơn giản của tập lệnh, như một bằng chứng về khái niệm, trên Python 2.7. Để sử dụng thực tế, tôi thực sự khuyên bạn nên sử dụng phiên bản đầy đủ ở trên:
#!/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
Hiệu suất là khá ấn tượng, ngay cả đối với các dự án con quái vật wine
, git
hay thậm chí là hạt nhân 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