Lệnh mà anh ấy gợi ý để thực hiện việc này đúng cách sau khi đã nhập "một lịch sử lâu dài và có liên quan" là
Date: Wed, 5 Dec 2007 22:09:12 -0800 (PST)
From: Linus Torvalds <torvalds at linux-foundation dot org>
To: Daniel Berlin <dberlin at dberlin dot org>
cc: David Miller <davem at davemloft dot net>,
ismail at pardus dot org dot tr,
gcc at gcc dot gnu dot org,
git at vger dot kernel dot org
Subject: Re: Git and GCC
In-Reply-To: <4aca3dc20712052111o730f6fb6h7a329ee811a70f28@mail.gmail.com>
Message-ID: <alpine.LFD.0.9999.0712052132450.13796@woody.linux-foundation.org>
References: <4aca3dc20712051947t5fbbb383ua1727c652eb25d7e@mail.gmail.com>
<20071205.202047.58135920.davem@davemloft.net>
<4aca3dc20712052032n521c344cla07a5df1f2c26cb8@mail.gmail.com>
<20071205.204848.227521641.davem@davemloft.net>
<4aca3dc20712052111o730f6fb6h7a329ee811a70f28@mail.gmail.com>
Vào ngày 6 tháng 12 năm 2007, Daniel Berlin đã viết:
Trên thực tế, đôi khi nó git-gc --aggressive
thực hiện điều ngu ngốc này khi đóng gói tệp bất kể bạn có chuyển đổi từ repo SVN hay không.
Chắc chắn rồi. git --aggressive
hầu hết là câm. Nó thực sự chỉ hữu ích cho trường hợp “Tôi biết tôi có một gói hàng thực sự tồi tệ và tôi muốn vứt bỏ tất cả các quyết định đóng gói tồi tệ mà tôi đã làm.”
Để giải thích điều này, cần phải giải thích (có thể bạn đã biết về nó, nhưng hãy để tôi đi qua những điều cơ bản) cách git delta-chain hoạt động và chúng khác biệt như thế nào so với hầu hết các hệ thống khác.
Trong các SCM khác, một chuỗi đồng bằng thường cố định. Nó có thể là "tiến" hoặc "ngược" và nó có thể phát triển một chút khi bạn làm việc với kho lưu trữ, nhưng nhìn chung đó là một chuỗi các thay đổi đối với một tệp được biểu thị dưới dạng một số loại thực thể SCM duy nhất. Trong CVS, rõ ràng đó là *,v
tệp và rất nhiều hệ thống khác làm những việc tương tự.
Git cũng thực hiện chuỗi đồng bằng, nhưng nó thực hiện chúng “lỏng lẻo” hơn nhiều. Không có thực thể cố định. Deltas được tạo dựa trên bất kỳ phiên bản ngẫu nhiên nào khác mà git được coi là một ứng cử viên delta tốt (với nhiều phương pháp phỏng đoán khá thành công khác nhau) và hoàn toàn không có quy tắc nhóm cứng.
Đây nói chung là một điều rất tốt. Nó tốt vì nhiều lý do khái niệm khác nhau ( tức là , git nội bộ thậm chí không bao giờ thực sự cần quan tâm đến toàn bộ chuỗi sửa đổi - nó không thực sự nghĩ về delta cả), nhưng nó cũng tuyệt vời vì việc loại bỏ các quy tắc delta không linh hoạt có nghĩa là Ví dụ: git không có bất kỳ vấn đề nào với việc hợp nhất hai tệp với nhau - đơn giản là không có *,v
“tệp sửa đổi” tùy ý nào có ý nghĩa ẩn nào đó.
Điều đó cũng có nghĩa là sự lựa chọn của các delta là một câu hỏi mở hơn nhiều. Nếu bạn giới hạn chuỗi delta chỉ trong một tệp, bạn thực sự không có nhiều lựa chọn về việc phải làm gì với delta, nhưng trong git, nó thực sự có thể là một vấn đề hoàn toàn khác.
Và đây là nơi mà cái tên thực sự tồi tệ --aggressive
xuất hiện. Mặc dù git thường cố gắng sử dụng lại thông tin delta (vì đó là một ý tưởng hay và nó không lãng phí thời gian CPU tìm lại tất cả các delta tốt mà chúng tôi đã tìm thấy trước đó), đôi khi bạn muốn nói "hãy bắt đầu lại từ đầu, với một phương tiện chặn trống và bỏ qua tất cả thông tin về delta trước đó và cố gắng tạo một tập hợp delta mới."
Vì vậy, --aggressive
không thực sự là về việc tích cực, mà là lãng phí thời gian CPU để thực hiện lại quyết định mà chúng tôi đã làm trước đó!
Đôi khi đó là một điều tốt. Một số công cụ nhập cụ thể có thể tạo ra các delta thực sự tồi tệ. git fast-import
Chẳng hạn, bất kỳ thứ gì sử dụng đều có khả năng không có nhiều bố cục delta tuyệt vời, vì vậy có thể đáng để nói rằng “Tôi muốn bắt đầu từ một phương tiện chặn sạch sẽ”.
Nhưng hầu như luôn luôn, trong những trường hợp khác, đó thực sự là một điều thực sự tồi tệ. Nó sẽ lãng phí thời gian của CPU, và đặc biệt là nếu bạn đã thực sự làm tốt công việc delta trước đó, kết quả cuối cùng sẽ không sử dụng lại tất cả những delta tốt mà bạn đã tìm thấy, vì vậy bạn sẽ thực sự kết thúc với rất nhiều kết quả cuối cùng tệ hơn quá!
Tôi sẽ gửi một bản vá cho Junio để xóa git gc --aggressive
tài liệu. Nó có thể hữu ích, nhưng nhìn chung nó chỉ hữu ích khi bạn thực sự hiểu ở mức độ rất sâu về những gì nó đang làm và tài liệu đó không giúp bạn làm điều đó.
Nói chung, làm tăng dần git gc
là cách tiếp cận đúng và tốt hơn là làm git gc --aggressive
. Nó sẽ sử dụng lại các delta cũ và khi không thể tìm thấy những delta cũ đó (lý do để thực hiện GC gia tăng ngay từ đầu!), Nó sẽ tạo ra những cái mới.
Mặt khác, chắc chắn đúng rằng “quá trình nhập ban đầu của một lịch sử lâu dài và có liên quan” là một điểm mà có thể đáng để dành nhiều thời gian tìm kiếm các châu thổ thực sự tốt . Sau đó, mọi người dùng mãi mãi về sau (miễn là họ không sử dụng git gc --aggressive
để hoàn tác!) Sẽ nhận được lợi thế của sự kiện một lần đó. Vì vậy, đặc biệt là đối với các dự án lớn có lịch sử lâu đời, có lẽ bạn nên thực hiện thêm một số công việc, bảo mã tìm kiếm delta trở nên hoang dã.
Vì vậy, tương đương với git gc --aggressive
- nhưng được thực hiện đúng cách - là làm (qua đêm) một cái gì đó như
git repack -a -d --depth=250 --window=250
trong đó vấn đề về độ sâu chỉ là về độ sâu của các chuỗi delta (làm cho chúng dài hơn theo lịch sử cũ - nó đáng giá trên không gian) và vấn đề cửa sổ là về mức độ lớn của cửa sổ đối tượng mà chúng tôi muốn mỗi ứng viên delta quét.
Và ở đây, bạn có thể muốn thêm -f
cờ (đó là "bỏ tất cả các delta cũ", vì bây giờ bạn thực sự đang cố gắng đảm bảo rằng cái này thực sự tìm thấy các ứng cử viên tốt.
Và sau đó nó sẽ mất mãi mãi và một ngày ( tức là một việc “làm qua đêm”). Nhưng kết quả cuối cùng là tất cả mọi người hạ nguồn từ kho lưu trữ đó sẽ nhận được các gói tốt hơn nhiều mà không cần phải tự mình bỏ ra bất kỳ nỗ lực nào.
Linus