2013-11-21 15 views
6

Chúng tôi có một repo Git với 7 nhà phát triển đóng góp với hơn 2,5 năm lịch sử và khoảng 10.000 cam kết. Chúng tôi sử dụng Assembla để đẩy và kéo. Khi chúng tôi thêm các nhà phát triển mới nhân bản repo vào máy tính dev của họ mất gần một giờ.Làm thế nào để co/Cắt một Repo Git

Tôi không chắc đây có phải là thuật ngữ thích hợp hay không, nhưng mục tiêu của chúng tôi là "thu nhỏ" repo bằng cách "cắt/cắt" khỏi giá trị cam kết 1,5 năm đầu tiên và chỉ giữ lại năm mới nhất của lịch sử. Chúng tôi muốn giữ một bản sao lưu "sao lưu" của toàn bộ repo, cho dù là một repo riêng biệt hoặc có thể là một chi nhánh? Chúng tôi muốn lặp lại điều này trong tương lai, có thể hợp nhất phân chia ban đầu với phần tách mới khi cần, nhưng tôi không chắc liệu điều này có khả thi hay không. Nếu có một cách để có tất cả lịch sử trên một chi nhánh riêng biệt và chỉ giữ chi nhánh master chỉ với lịch sử của năm ngoái, điều đó thật tuyệt vời, nhưng hãy cho tôi biết về những ưu và khuyết điểm có thể có.

Tôi không biết tất cả các khả năng/tùy chọn mà chúng tôi có là lý do tôi ở đây. Tôi đọc một cái gì đó về patches nhưng tôi không chắc chắn nếu đó thực sự là những gì tôi cần hoặc nếu có cái gì đó tốt hơn/dễ dàng hơn. Các bạn đang làm gì để chăm sóc một vấn đề như thế này, bao gồm ưu và nhược điểm? Hãy nhớ, tôi vẫn cần mọi nhà phát triển tiếp tục đẩy và kéo, tốt nhất là ở lại chi nhánh master.

Cảm ơn trước!

+0

Làm thế nào lớn là repo của bạn (kích thước đĩa)? Git sẽ có thể xử lý số tiền cam kết này. Bạn cũng có thể tìm tải dư thừa trên máy chủ hoặc các vấn đề về mạng (như so sánh, hạt nhân Linux có dung lượng lớn khoảng 800MB, có 400K cam kết và mất khoảng 1/2 giờ để được nhân bản từ git.kernel.org). – Rudi

+0

Rudi, repo là khoảng 30GB với hơn 10K cam kết (.git/objects/folder là 12GB), không có gì so với hạt nhân Linux. Tuy nhiên, ngoài bất kỳ vấn đề mạng nào có thể xảy ra, tôi không chỉ cố gắng sửa lỗi và tiếp tục, tôi cũng muốn tìm hiểu các phương pháp khác nhau có sẵn liên quan đến vấn đề này. Cảm ơn! – RoLYroLLs

+0

bản sao có thể có của [Git remove history commit] (http://stackoverflow.com/questions/13091928/git-remove-history-commit) – sschuberth

Trả lời

7

Hướng dẫn từng bước tốt nhất có thể được tìm thấy trên bài đăng trên blog Git SCM "Replace Kicker".

Bản tóm tắt ngắn gọn là thế này:

  • Tạo một chi nhánh mới đó là tại điểm mà bạn muốn cắt, nói git branch historybăm.
  • Đẩy lịch sử vào một kho lưu trữ mới.
  • Tạo cơ sở mới bằng cách sử dụng git commit-tree.
  • Rebase bài đăng của bạn- history cam kết vào cơ sở mới của bạn.
  • Đẩy chi nhánh cắt ngắn master mới của bạn lên máy chủ.
  • Mọi người có thể sử dụng git replace để kết nối lại lịch sử với nhau.

Bài đăng gốc giải thích rõ hơn về hình ảnh.

Khi xử lý lịch sử phức tạp liên quan đến việc hợp nhất, điều này có thể không hoạt động tốt, tùy thuộc vào mức độ git rebase --onto hoạt động với --preserve-merges. Bạn nên kiểm tra rõ ràng trước khi tiếp tục.

+0

Cảm ơn! Tôi thực sự thích quá trình này. Tôi đã thử nghiệm phương pháp này. Bạn có biết nếu có cách nào để giữ phương pháp này một nửa không? IE: nhánh 'master' có phiên bản cắt ngắn, và nhánh' history' giữ toàn bộ lịch sử cho đến khi tôi tách chúng ra? Tôi không muốn phải đẩy đến một repo riêng biệt. – RoLYroLLs

+0

Để thêm vào bình luận của tôi ở trên, tôi chỉ đọc rằng một 'git pull {remote}' kéo tất cả các nhánh nhưng không tạo ra một nhánh địa phương cho bất kỳ/tất cả các nhánh trên repo từ xa. nếu tôi quản lý để giữ lịch sử trong một chi nhánh và tất cả các cam kết mới trên một chi nhánh khác, các nhà phát triển mới sẽ kéo TẤT CẢ dữ liệu từ mỗi chi nhánh (mà tôi đoán là lý do để 'đẩy' vào một repo mới trong câu trả lời của bạn), hay nó chỉ kéo tên chi nhánh chứ không phải dữ liệu? – RoLYroLLs

+0

Tôi đã làm một số thử nghiệm trên một repo khác và nhận được câu trả lời cho câu hỏi của tôi về bao nhiêu dữ liệu 'git pull' nhận được. Thật vậy, nó có được tất cả các chi nhánh và thay đổi được theo dõi của họ, ngay cả khi bạn không có một chi nhánh địa phương theo dõi những thay đổi cho một chi nhánh cụ thể. Vì vậy, ý tưởng của tôi về việc giữ lịch sử trên một nhánh riêng biệt sẽ không khả thi. Tôi sẽ phải theo dõi bài đăng Thay thế Kicker mà bạn đã đăng! Cảm ơn! – RoLYroLLs

0

Tuyên bố từ chối trách nhiệm: Trước tiên, bạn nên thực hiện thao tác này với repo thử nghiệm, vì các lệnh được liệt kê tại đây có thể hủy dữ liệu của bạn.

Bạn có thể chỉnh sửa (ví dụ: để chỉnh sửa tập lệnh) lịch sử thông qua cơ chế xuất nhanh. Bước đầu tiên là chạy git fast-export --signed-tags=strip --no-data --full-tree --export-marks=export.marks branch1 branch2 [...] branchN > commits.fi. Bây giờ bạn có một dòng nhập nhanh của tất cả các chi nhánh của bạn. Trong luồng này, bạn có thể thả một cam kết bằng cách xóa các dòng từ commit refs/... thành newline trailing. Bạn cũng cần phải xóa đường dây from :<mark> (và cũng có merge :<mark> dòng nếu lịch sử mới của bạn bắt đầu bằng cách hợp nhất) từ các cam kết "đầu tiên" mới của bạn.

Để hỗ trợ quy trình này, bạn nên xem xét đồ thị sửa đổi và thực hiện các sửa đổi mà không có sự hợp nhất nào vượt qua lịch sử của chúng. Trong biểu đồ sau, A, D và F là các ứng cử viên tốt để bắt đầu. B hoặc C không có vấn đề, mà sự kế thừa D cũng không phụ thuộc vào G và A.

A ---- B ---- C ---- D --- E ---- F 
    \    /\  \ /
    \--- G ------- H \--I--J-/ 

Với file export.marks bạn có thể dịch các cam kết ID để đánh dấu numers trong dòng.

Bạn cần phải đặt tên cho các nhánh mới, vì nhập nhanh sẽ không chấp nhận lịch sử mới, vì các nhánh mới không chứa các cam kết từ các nhánh hiện có.

Sau khi bạn tạo lịch sử mới, bạn cần nhập nó với git fastimport < manipulated-history.fi vào kho lưu trữ hiện tại của mình.

Bây giờ là lúc kiểm tra xem việc nhập có chính xác hay không. Đối với điều này, bạn cần sao chép repo thành một repo tạm thời, và trong repo tạm thời này bạn tạo cho mỗi commit mới được tạo ra để ghép nó có cùng các bản sửa đổi cha mẹ giống như trước đây. Sau đó bạn chạy git filter-branch newBranch1 newBranch2 [...] newBranchN. Việc nhập khẩu là chính xác nếu mỗi newBranch hiện tại vẫn ở cùng một cam kết với nhánh tương ứng.

Khi mọi thứ đã hoạt động cho đến giờ, bạn có thể tạo một repo mới và kéo chi nhánh mới từ bản sao làm việc đầu tiên vào nó và làm cho nó trở lại làm việc mới. Cũng lưu ý rằng bạn không nên để lại bất kỳ repos nào với ghép ở bất cứ đâu, kể từ ghép can cause harm.

+0

@Rubi cảm ơn vì điều này. không chắc chắn giải pháp này sẽ hoạt động tốt như thế nào do vấn đề đồ thị bạn đã đề cập. – RoLYroLLs

Các vấn đề liên quan