2016-04-29 15 views
5

Khi tôi hiểu, cam kết là ảnh chụp nhanh của tệp vì vậy nếu tôi thực hiện thay đổi A và sau đó thay đổi B, thay đổi cam kết B tệp đã bao gồm các thay đổi trong thay đổi A, sẽ không sắp xếp lại thay đổi.Tại sao sắp xếp lại các cam kết bằng cách sử dụng git rebase -i không làm hỏng lịch sử?

+0

Git có sự khác biệt khi cần thiết; rebase áp dụng khác với nội dung cơ sở mới. – jthill

Trả lời

5

Đó là, trên thực tế, một câu hỏi rất hay, vì cam kết ảnh chụp nhanh.

Lý do rebase hoạt động là do rebase thực sự được lặp lại git cherry-pick (với một chút gói ở mặt trước để tìm ra những gì để chọn, và nhiều hơn nữa ở cuối để di chuyển nhãn chi nhánh), và git cherry-pick hoạt động bằng cách cam kết thành một tập hợp thay đổi.

Giả sử ví dụ mà bạn có chuỗi này cam kết:

  A--B--C <-- topic 
     /
...--o--*--o--o  <-- mainline 

Để rebase topic vào mainline chúng ta cần phải (1) tìm ra cam kết rằng đang trên topic nhưng không phải trên mainline (mà là C, BA dọc theo hàng trên cùng, kết thúc tại cam kết được đánh dấu *) và sau đó (2) sao chép chúng vào các cam kết mới, chúng tôi sẽ thêm vào bên dưới đầu của mainline.

rebase đầu tiên tìm thấy ba hậu * cam kết và đặt chúng vào một (đảo ngược lệnh: A, B, C) danh sách (nó cũng bỏ qua sáp nhập cam kết theo mặc định nhưng không có hòa trộn ở đây). Sau đó nó thực hiện một lựa chọn anh đào cho mỗi cam kết.

Để chọn cherry A, Git diffs A chống lại *. Điều này biến hai ảnh chụp nhanh thành các changesets. Git sau đó áp dụng các thay đổi đối với mũi-hầu hết các cam kết của mainline và làm cho một mới cam kết, chúng ta hãy gọi nó A', trên một nhánh vô danh:

  A--B--C <-- topic 
     /
...--o--*--o--o  <-- mainline 
       \ 
       A' <-- HEAD 

Để anh đào-chọn B, Git diffs B chống A. Áp dụng các thay đổi này cho A' sẽ tạo một cam kết khác B'. Lặp lại cho C để có được C':

  A--B--C   <-- topic 
     /
...--o--*--o--o   <-- mainline 
       \ 
       A'-B'-C' <-- HEAD 

ngoái, Git bị lột nhãn topic xa C và chỉ nó để C' để thay thế. Chuỗi cũ đang bị bỏ rơi (mặc dù bạn vẫn có thể tìm thấy nó qua reflogs, và rebase bản sao ID của C với tên đặc biệt ORIG_HEAD cũng):

  A--B--C   [abandoned] 
     /
...--o--*--o--o   <-- mainline 
       \ 
       A'-B'-C' <-- topic 

và bây giờ rebase hoàn tất.

Lưu ý rằng mỗi bản sao được thực hiện bằng cách sử dụng cơ chế hợp nhất của git nếu cần (nếu các khác biệt không áp dụng ngay lập tức). Mỗi người có thể dẫn đến xung đột hợp nhất, yêu cầu phải ngừng lại và nhận trợ giúp từ bạn. (Hoặc, tệ hơn, bạn có thể bị kết hợp sai, mặc dù điều này hiếm gặp trong thực tế.Và tất nhiên, nếu bạn sắp xếp lại các cam kết (bằng cách di chuyển pick đường xung quanh trong một lần rebase tương tác), chúng tôi chỉ thay đổi thứ tự mà chúng tôi chọn và áp dụng từng cam kết. Các hoạt động pick-cherry vẫn hoạt động theo cùng một cách: so sánh cam kết đã chọn với cha mẹ của nó (C vs B, A vs *, B vs A).

+0

Nhưng dữ liệu khác biệt phụ thuộc vào nội dung của tệp trong cam kết trước đó, điều này sẽ thay đổi sau khi sắp xếp lại chúng. Hay liệu thứ tự này chỉ là mỹ phẩm? –

+0

Các bản sao mới là * bản sao mới *, với tất cả những điều này ngụ ý. Giả sử, ví dụ, trong khi anh đào chọn 'B' bạn nhận được một cuộc xung đột hợp nhất vì đầu của' đường chính 'có một sự thay đổi mâu thuẫn. Khi bạn sửa chữa xung đột và tiếp tục rebase, commit mới 'B'' bây giờ có một sự thay đổi khác so với commit ban đầu' B'. Cả 'B' và' B'' vẫn còn trong kho, và lựa chọn cherry-pick tiếp theo (giả sử nó là cho 'C') so sánh' C' với 'B' trước khi cố gắng áp dụng thay đổi đó cho' B'' (có thể nhận được xung đột hợp nhất khác vì 'B'' giờ đã khác!). – torek

+0

Tôi nghĩ rằng tôi thấy nó ngay bây giờ sau khi đọc bình luận của bạn và đọc lại câu trả lời của bạn. Có vẻ như tôi bị ném ra bởi thuật ngữ. Như tôi thấy nó bây giờ, chắc chắn, các cam kết có thể được sắp xếp lại nhưng kết quả cam kết sau khi một rebase là hoàn toàn mới cam kết cho dù bạn sắp xếp lại chúng hay không. Kết quả cam kết này cũng có một "tệp ảnh chụp nhanh" khác nhau, đó là kết quả của việc chỉ áp dụng sự khác biệt từ việc chọn anh đào đến đầu dòng chính. Theo cách đó, việc sắp xếp lại là mỹ phẩm vì các cam kết ban đầu được sắp xếp lại không thay đổi. Vui lòng cho tôi biết nếu tôi đúng. –

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