2011-01-14 9 views
9

Tôi có một số cam kết:Sử dụng git rebase để hồi tố thực hiện cam kết trên một nhánh khác?

- 1 - 2 - 3 - 4 - 5 (HEAD, master) 

Sau đó tôi nhận thấy cam kết 2 & 3 thực sự nên đã đi vào chi nhánh riêng của họ. Chúng hoàn toàn độc lập với cam kết 4 và 5 Tôi có thể sử dụng git rebase để thực hiện không?

- 1 - 4 - 5 (HEAD, master) 
    \ 
    2 - 3 (TestBranch) 

Và quan trọng nhất, SHA1s cho Commit 2Commit 3 sẽ giữ nguyên như lúc trước rebase?

+2

Tôi đã sửa đổi danh sách cam kết của bạn thành nhiều đồ thị chuẩn hơn, như bạn sẽ thấy trong các trang người dùng git và tất cả trên internet. Nếu bạn thích danh sách theo chiều dọc, bạn có thể chỉnh sửa lại danh sách này - nhưng tôi khuyên bạn nên đảo ngược thứ tự. Bạn đã có phiên bản mới nhất ở dưới cùng, ngược lại với đầu ra của các lệnh như 'git log' và chế độ xem trong' gitk' và các trình xem lịch sử khác. Tôi cũng cho rằng Head thực sự là 'HEAD', và bạn cũng đã kiểm tra chi nhánh; Tôi đặt tên nó là chủ. – Cascabel

+0

Cảm ơn, @Jefromi, để làm cho câu hỏi này dễ hiểu hơn. – Oliver

Trả lời

9

Trước tiên, lưu ý rằng các điểm TestBranch mong muốn của bạn chỉ đơn giản là cam kết hiện tại 3; bạn không phải làm bất cứ điều gì nhưng git branch TestBranch <commit 3> để thực hiện điều đó. Hãy nhớ rằng, chi nhánh chỉ là con trỏ để cam kết. Điều này sẽ trả lời câu hỏi của bạn về SHA1s của cam kết 2 và 3. Bạn chưa thay đổi những cam kết đó, vì vậy SHA1 của họ là tất nhiên như nhau.

Để có nhánh hiện tại (chính) nơi bạn muốn (cam kết 1, 4, 5), bạn thực sự sẽ rebase. Đây là một trường hợp rất đơn giản cho chế độ tương tác của nó. Đầu tiên, hãy chạy:

git rebase -i <commit 1> master  # -i is a synonym for --interactive 

Git sẽ khởi động soạn thảo của bạn, và cho bạn thấy tất cả các cam kết kể từ khi cam kết 1 trên chi nhánh chủ của bạn (2,3,4,5), cùng với một số gợi ý về những gì để làm. Bạn chỉ cần xóa các dòng cho các cam kết 2 và 3, sau đó lưu và thoát. Sau đó nó sẽ áp dụng những gì còn lại (4 và 5), để lại cho bạn những gì bạn muốn. Tất nhiên, nếu cam kết 4 và 5 phụ thuộc vào cam kết 2 hoặc 3, bạn sẽ nhận được xung đột hợp nhất khi git cố gắng áp dụng các bản vá lỗi của họ trong quá trình rebase.

Lưu ý rằng điều này sẽ thay đổi SHA1 của cam kết 4 và 5, vì SHA1 của cam kết phụ thuộc vào cha mẹ của nó. Điều này sẽ gây rối với bất cứ ai đã kéo nhánh đó. (Bạn đã được cảnh báo.) Kết quả cuối cùng thực tế của bạn sẽ chính xác hơn được mô tả như thế này:

- 1 - 4' - 5' (HEAD, master) 
    \ 
    2 - 3 (TestBranch) 

cam kết 4' và 5' có diffs giống như cam kết 4 và 5, nhưng có cha mẹ khác nhau, vì vậy chúng các cam kết khác nhau.

+2

Sẽ không thể sử dụng 'git rebase --onto TestBranch master' thay vì rebase tương tác? –

+2

@Sven: Tuyệt đối, vâng.Tôi có xu hướng đề nghị một tương tác bởi vì bạn thấy chính xác những gì bạn đang làm, mặc dù cá nhân tôi có thể đã thực hiện nó noninteractively. – Cascabel

2

Nếu bạn kiểm tra 3, bạn có thể tạo chi nhánh mới TestBranch tại thời điểm đó và nhận chi nhánh bạn muốn.

Sau đó, bạn có thể quay lại chi nhánh masterrebase it interactively với git rebase -i HEAD~6, xóa 23 bằng cách xóa dòng của chúng.

+0

Tại sao bạn sử dụng tính năng rebase tương tác để tạo TestBranch? Bạn có thể chỉ cần tạo nó tại cam kết 3 trực tiếp. – Cascabel

+0

Chính xác, tôi nhầm tưởng rằng có các cam kết giả giữa 1 và 3. – huitseeker