Đây chỉ là một ý tưởng, tôi đã không kiểm tra nó cho kịch bản này nhưng tôi đã sử dụng nó (theo một cách khác) đến join two Git
repositories and keep the original commit dates.
Nếu lịch sử có các chi nhánh và hợp nhất, tôi nghĩ không thể sắp xếp lại chúng và giữ cấu trúc, thậm chí là thủ công. Điều tốt nhất bạn có thể nhận được là một lịch sử tuyến tính.
Save the cam băm và timestamps (%ct
= ngày, %at
= author ngày cam kết) vào một tập tin, sắp xếp chúng theo ngày tác giả:
$ git log --pretty='%H %at %ct' --author-date-order --reverse > /tmp/hashlist
Nếu thứ tự được cung cấp bởi các lệnh trên không đáp ứng sau đó bạn buộc thứ tự bằng cách sắp xếp đầu ra bằng trường thứ hai (ngày tác giả):
$ git log --pretty='%H %at %ct' | sort -k 2 > /tmp/hashlist
Tạo kho lưu trữ mới để giữ lịch sử theo yêu cầu của ngày tác giả. Tạo một cam kết ban đầu thiết lập ngày cam kết trong quá khứ (trước khi cam kết lâu đời nhất trong kho của bạn):
$ GIT_COMMITTER_DATE='2010-01-01 12:00:00' GIT_AUTHOR_DATE='2010-01-01 12:00:00' git commit --allow-empty
Đặt ngày của riêng bạn vào lệnh trên.
Thêm kho lưu trữ cũ làm điều khiển từ xa vào bộ nhớ mới, tìm nạp tất cả các cam kết của nó. KHÔNG đặt chi nhánh master
của repo mới để theo dõi một trong các repo cũ.
Tạo một kịch bản mà anh đào sẽ chọn cung cấp cam kết và áp dụng nó trên đầu trang của các chi nhánh hiện nay, việc giữ ngày tác giả ban đầu và ngày cam kết:
$ echo '[email protected]$2 [email protected]$3 git cherry-pick $1' > /tmp/pick
$ chmod +x /tmp/pick
Nếu bạn không muốn giữ lại một trong hai ngày tác giả ban đầu hoặc ngày bắt đầu (hoặc cả hai) sau đó chỉ cần xóa nhiệm vụ tương ứng khỏi dòng lệnh trên.
Sử dụng tập lệnh mới với xargs
để chọn từng cam kết theo thứ tự đã chọn và cam kết trên đầu nhánh chính mới của bạn.
$ cat /tmp/hashlist | xargs -n 3 /tmp/pick
Nếu mọi thứ suôn sẻ thì hãy xóa các tệp tạm thời được tạo trong quá trình.
$ rm /tmp/hashlist
$ rm /tmp/pick
Ghi chú:
- Bạn sẽ nhận được một lịch sử tuyến tính. Các chi nhánh và hợp nhất ban đầu sẽ không được tạo lại vào tiến trình lịch sử mới.
- Các nhánh chưa được gắn sẽ không được sao chép. Bạn có thể sử dụng
git rebase
để sao chép và đính kèm chúng vào các cam kết mới.
- Ngay cả khi repo của bạn không có chi nhánh, vẫn có xác suất cao để có xung đột về lựa chọn anh đào; nó phụ thuộc rất nhiều thay đổi được giới thiệu bởi các cam kết theo thứ tự mới.
- Nếu nó không hoạt động, bạn luôn có thể xóa kho lưu trữ mới và bắt đầu lại (hoặc thoát); kho lưu trữ cũ không bị thay đổi.
Ý tưởng của bạn có vẻ hợp lý. Các cherry-picks đang chạy. Hy vọng không có/xung đột nhỏ – Blitzkr1eg
Có rất nhiều xung đột, do đó, giảm phương pháp này. Vì vậy, tôi cho họ A1-A2-A3-B1-B2-B3-C1-C2-C3 giống như sau khi hợp nhất. – Blitzkr1eg
Khi nó tạo ra sự khác biệt, 'git' không chỉ ghi lại các dòng đã thay đổi mà còn là ngữ cảnh của thay đổi (1 dòng trước và 1 dòng sau khi thay đổi). Nó sử dụng những dòng này khi nó áp dụng một diff để đảm bảo rằng các diff có thể được áp dụng một cách an toàn. Nếu các dòng ngữ cảnh không khớp (tức là vì chúng được thêm/thay đổi bởi một cam kết trước đó trong dòng thời gian ban đầu nhưng bạn muốn áp dụng sau trong dòng thời gian đã sửa đổi) một xung đột xuất hiện. Rất tiếc, việc giải quyết xung đột tự động không an toàn. Nếu bạn nhận được nhiều xung đột thì có thể thay đổi thứ tự của các cam kết là không thể. – axiac