2010-12-14 34 views
16

Tình huống: Bắt đầu với Thạc sĩ theo số A Tôi phân nhánh và thực hiện một số thay đổi tại B sau đó sáp nhập chi nhánh đó trở lại trong (C). Sau khi thực hiện một số thay đổi khác, tôi đã ở số D nhưng thấy rằng tôi cần triển khai mã mà không có thay đổi nào xảy ra trong chi nhánh. Nếu tôi không hợp nhất nó thì sẽ ổn thôi.Git: Cách "hoàn tác" hợp nhất

A_______C___D 
\ /
    \_B_/ 

Trước tiên, tôi muốn biết tôi nên làm gì từ đây để triển khai mã như thể quá trình hợp nhất chưa từng xảy ra. Lưu ý: không có tập tin nào đã được chỉnh sửa trong nhánh đã được chỉnh sửa trong bản gốc.

Thứ hai ...

Tôi không có thời gian để làm việc ra các phương pháp tốt nhất để đối phó với điều này, vì vậy tôi đã xóa các tập tin mà chi nhánh gia tăng, và tự quay trở một vài chỉnh sửa được thực hiện tại các chi nhánh sau đó cam kết kết quả cho việc triển khai (F)

A_______C___D___F 
\ /
    \_B_/ 

tôi muốn để có thể tiếp tục phát triển các chi nhánh và hợp nhất bất kỳ thay đổi từ các bậc thầy vào nó để giữ cho nó được cập nhật, nhưng nếu tôi làm điều đó những thứ tôi đã làm để tạo F sẽ được hợp nhất và khiến các tệp sẽ bị xóa và các chỉnh sửa cần được hoàn nguyên. Cách tốt nhất để giải quyết vấn đề này là gì?

Trả lời

16

Bạn có thể sử dụng rebase để làm điều đó chỉ trong một bước:

git rebase --onto A C D 

tôi chỉ thử nghiệm này, với kết quả thích hợp:

$ edit test.txt 
$ git add . 
$ git commit -mA 
$ git checkout -b the_branch 
$ edit test.txt 
$ git commit -a -mB 
$ git checkout master 
$ git merge master the_branch --no-ff 
$ edit test.txt 
$ git commit -a -mD 

Từ đây bạn có tình huống mà bạn mô tả. Sau đó:

$ git rebase --onto <SHA1-for-A> <SHA1-for-C> master 

rebases cam kết từ C (phí tự túc) để làm chủ, vào A. tôi cần phải khắc phục một số xung đột kể từ khi tôi sửa đổi tại cùng một nơi trong B và D, nhưng tôi nghĩ rằng bạn sẽ không.

_D' 
/
/
A_______C___D 
\ /
    \_B_/ 

Doc về git rebase --onto, mà là nhiều hơn hoặc ít hơn tình hình của bạn: http://git-scm.com/docs/git-rebase


Nếu bạn có:

A_______C___D___F 
\ /
    \_B_/ 

, sau đó bạn có bây giờ:

_D'___F'_(master) 
/
/
A_______C___D___F 
\ /
    \_B_/(the_branch) 

Từ đây, việc kết hợp các thay đổi trong master thành nhánh thật dễ dàng. Hủy bỏ cam kết F' hoàn toàn.

$ git checkout master # if you were not here already 
$ git branch old_fix # if you want to be able to return to F' later 
$ git reset --hard <SHA1-to-D'> 

Sau các lệnh trên bạn có:

 (master) 
    /
    _D'___F'_(old_fix) 
/
/
A_______C___D___F 
\ /
    \_B_/(the_branch) 

Để nhập thông tin cập nhật của thầy vào the_branch:

$ git checkout the_branch 
$ git merge master 

... và khắc phục xung đột.

+0

Tuyệt vời, cảm ơn! Tôi sẽ sử dụng điều này trong tương lai (nếu cẩn thận hơn với việc hợp nhất của tôi không hoạt động). Xem câu trả lời của @ terminus cho những gì tôi đã làm. Tôi nghĩ rằng nó đạt được khá nhiều kết quả tương tự như câu trả lời của bạn. – Jake

6

Giải pháp rõ ràng là đặt lại thành A, áp dụng lại tất cả các bản vá theo cách thủ công và giải quyết xung đột (mà bạn sẽ không có).

Hoặc bạn chỉ có thể git revertB nhưng điều đó sẽ tạo một cam kết mới.

Mặc dù câu trả lời của Gauthier tốt hơn.

+0

Cảm ơn, Sau khi đọc bài viết này, tôi đã xem xét các bản vá và kết thúc ở đây: http://www.gitready.com/intermediate/2009/03/04/pick-out-individual-commits.html Vì vậy, tôi đã chia nhánh A và anh đào chọn D và F, sau đó hợp nhất kết quả vào nhánh ban đầu để cập nhật nó. – Jake

+0

Bạn có thực sự anh đào-chọn F? Tôi nghĩ F chỉ để đảo ngược B và C, vậy nên không có gì để làm sau C '? – Gauthier

+0

Rất tiếc, hiện tại tôi không chắc chắn. Có lẽ tôi đã làm nhưng không thực sự cần. – Jake

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