2008-12-13 25 views
33

Giả sử tôi có kho lưu trữ git và tôi đã làm việc trên máy chủ, tôi có thể tạo chi nhánh một cách hồi tố không. Ví dụ:Có thể quay trở lại một bộ cam kết thành chi nhánh không?

A - B - C - A1 - D - A2 - E

Tôi muốn làm cho nó trông như thế này:

A - A1 - A2 
\   \ 
B - C - D - E 

Các trường hợp sử dụng cụ thể là khi tôi đã cherry -picked một loạt các cam kết vào một phiên bản cũ chi nhánh và nó cần phải đi vào nhiều phiên bản cũ hơn và tôi không muốn lặp lại anh đào-pick trên tất cả những sửa đổi.

Về cơ bản, đó là một cái gì đó sẽ tốt như một đối tượng địa lý hoặc chi tiết ở nơi đầu tiên nhưng không được tạo ra như vậy.

Trả lời

15

Tất nhiên bạn có thể. (Với Git không có nhiều hơn bạn không thể làm anyway. :)

git checkout -b new-branch hash-of-A 
git cherry-pick hash-of-A1 
git cherry-pick hash-of-A2 

Điều này sẽ tạo ra một chi nhánh mới, bắt đầu từ cam kết A. Sau đó bạn quay trở lại với cùng cam kết một lần nữa, tạo ra một chi nhánh khác:

git checkout -b new-branch2 hash-of-A 
git cherry-pick hash-of-B 
git cherry-pick hash-of-C 
git cherry-pick hash-of-D 
git cherry-pick hash-of-E 
git merge new-branch 

Bây giờ bạn chỉ cần phải sáp nhập new-branchnew-branch2 để có được những cấu trúc mà bạn muốn và thả chi nhánh cũ của bạn.

Tất nhiên những gì Dustin cho biết vẫn giữ: các băm của các cam kết sẽ thay đổi, do đó bạn chỉ nên làm điều đó nếu bạn chưa xuất bản các thay đổi của mình.

+0

Vì vậy, nếu nhánh tôi đã làm chủ, tôi nên di chuyển tên chủ đến người đứng đầu nhánh mới2? Làm cho tinh thần. Cảm ơn. – Otto

+2

Cách làm việc quá nhiều. Xem câu trả lời của tôi dưới đây. –

+1

Vâng, kỹ năng rebasing tương tác của tôi đã được cải thiện rất nhiều kể từ đó. :) – Bombe

6

Bạn không thể làm điều đó một cách minh bạch bởi vì các băm sẽ phải thay đổi, nhưng về cơ bản bạn chỉ cần nhánh HEAD và rebase -i cả hai nhánh để giảm các thay đổi tương ứng.

0

Điều bạn muốn làm là thực sự ghi lại lịch sử. Số nhận dạng của các cam kết sẽ thay đổi và trong một số trường hợp, các thay đổi được đưa ra bởi các cam kết sẽ thay đổi. Vì vậy, nếu có một cơ hội mà ai đó có thể làm việc dựa trên phiên bản cũ của chi nhánh bạn muốn thay đổi, tốt hơn là không nên làm điều này. Nhưng nếu bạn không xuất bản chi nhánh này, hãy cảm thấy tự do.

Giả sử rằng nhánh mà chúng ta muốn thay đổi có tên là 'master', và điểm mà chúng ta muốn bắt đầu nhánh mới có tên 'A' (trong ví dụ đã cho của tên bạn có thể sử dụng là 'master ~' 6 ').

Thứ nhất, cho phép tạo ra các chi nhánh mới từ cam kết 'A', chúng ta hãy đặt tên cho nó 'sửa'

$ git checkout -b fixes A 

Điều này cũng sẽ làm cho chi nhánh 'sửa' hiện nay. Bởi vì chỉ có một vài cam kết mà chúng tôi muốn un-cherry-pick, chúng tôi anh đào có thể chọn chúng vào 'sửa' chi nhánh:

$ git cherry-pick A1 
$ git cherry-pick A2 

Sau đó, chúng tôi muốn loại bỏ các cam kết 'A1' và 'A2' từ chi nhánh 'bậc thầy'. Bởi vì chỉ có một vài cam kết chúng tôi muốn loại bỏ, và có thể nhiều hơn nữa, chúng tôi muốn giữ lại, chúng tôi eould sử dụng 'git rebase --interactive' cho rằng:

$ git rebase -i fixes master 

Một biên tập viên sẽ được bắn lên với tất cả các cam kết trong 'chủ' sau khi cam kết 'A' (là cam kết chung tức là hợp nhất cơ sở của nhánh 'chủ' và nhánh 'sửa').Danh sách này sẽ trông như thế này:

pick deadbee B 
pick fa1afe1 C 
pick a98d4ba A1 
... 

dòng Remove với cam kết 'A1' và 'A2', lưu các thay đổi, biên tập viên gần (hoặc gửi thay đổi cho inetractive rebase) và git sẽ nộp đơn xin lại tất cả các cam kết ngoại trừ những người mà bạn đã xóa.

Sau đó, bạn có thể hoàn thiện với

$ git merge fixes 

(git-rebase lại cho chúng ta về chi nhánh viết lại 'thầy').

84

Nếu bạn muốn tất cả các cam kết sau khi sửa đổi XXX đã xảy ra trong một chi nhánh, tôi thấy điều này dễ dàng hơn nhiều so với các phương pháp được đề xuất khác.

$ git branch fixes  # copies master to new branch 
$ git reset --hard XXX # resets master to XXX 

Điều này được mô tả trong trang trợ giúp của git cho reset trong "Hoàn tác cam kết, biến thành nhánh chủ đề".

+0

Vui vì tôi đã đọc xuống câu trả lời cuối cùng! - đây là giải pháp đơn giản nhất (cho trường hợp sử dụng cụ thể của tôi ít nhất) –

+3

Tôi đã quay lại câu trả lời này lần thứ hai trong tuần này. Tôi ước tôi có thể cho @alltom một phiếu bầu khác! –

+5

Giá trị hữu ích cho _XXX_ đó chỉ là 'origin/master': giả sử bạn đang ở trên nhánh' master', lấy tất cả các commit chưa được sửa và coi chúng như một nhánh thay thế. Bạn cũng có thể muốn 'git checkout fixes' ở cuối để thực sự chuyển về nhánh mới của bạn. –

1

Quên tất cả những gì anh đào hái. Chỉ cần rebase -i hai lần bỏ qua các thay đổi, tạo một nhánh mới mỗi lần và sau đó hợp nhất 2.

+0

oops .. Dustin đã trả lời cùng một cách .. –

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