2014-12-02 23 views
5

Tôi đã sáp nhập 3 Repos git khác nhau vào một tại lịch sử của tôi trông giống như sau:Sắp xếp lại git commit lịch sử theo ngày

A1-A2-A3-B1-B2-B3-C1-C2-C3

Bây giờ tôi muốn sắp xếp lại tất cả các cam kết này theo ngày. Vì vậy, cuối cùng nó có thể là một cái gì đó giống như C1-A1-A2-B1-C2 -... bạn có được ý tưởng

Tôi ổn nếu tôi mất tất cả các ID cam kết SHA gốc. Và tất nhiên tôi không thể làm việc sắp xếp lại bằng tay vì vậy tôi cần một số kịch bản hoặc một số ý tưởng làm thế nào để tiếp cận điều này.

Trả lời

0

Bạn không thể sắp xếp lại A1-A2-A3-B1-B2-B3-C1-C2-C3 mà không làm nó bằng tay

4

Đâ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.
+0

Ý 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

+0

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

+0

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

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