2011-01-19 12 views
9

Có rất nhiều cuộc nói chuyện về việc làm thế nào nó không dễ dàng để "hoàn tác" một hợp nhất trong git. Phiên bản ngắn: nếu bạn hoàn tác một cam kết hợp nhất, nó cũng yêu cầu git không bao giờ hợp nhất các thay đổi đó lại trong tương lai.Làm thế nào tôi có thể làm git sáp nhập theo cách mà họ dễ dàng quay trở lại?

Có điều gì tôi có thể làm khi thực hiện hợp nhất để giảm bớt vấn đề này không? Có rất nhiều tình huống mà việc hoàn tác hợp nhất sẽ thực sự, thực sự hữu ích, chỉ trong quá trình phát triển phần mềm bình thường, và quan trọng hơn, trong việc kiểm soát trạng thái của một nhánh phát hành, khi các thay đổi cần được khôi phục.

chỉnh sửa

Tôi đã thấy dung dịch trong this article và không thực sự coi đó là một giải pháp, nhiều hơn một giải thích về vấn đề này. Nó đòi hỏi

  1. lúc nào cũng sử dụng --no ff-
  2. nhớ
  3. tất cả hoàn tác-hòa trộn của bạn khi bạn muốn mang lại trong mã phụ thuộc vào họ (điều này có thể là một vài giờ, vài ngày, tuần, hoặc tháng trong tương lai ...)

những gì tôi muốn

sau đây là cách nó hoạt động trong Subversion. Giả sử tôi có một chi nhánh được gọi là "ứng cử viên phát hành", đó là những gì chúng tôi chạy trên máy chủ dàn dựng và nơi chúng tôi thử các tính năng. Hãy nói rằng tôi hợp nhất trong tính năng Một chi nhánh. Trong Subversion, đó là tất cả một changeset và tất cả lịch sử cho tất cả các tệp được hợp nhất. Hãy nói rằng chúng tôi không thích nó, vì vậy chúng tôi muốn lấy nó ra. Chúng tôi chỉ hoàn tác những thay đổi duy nhất đó, và không phải suy nghĩ về bất cứ điều gì khác. Chúng tôi có thể hợp nhất chi nhánh tính năng A trở lại vào bất kỳ lúc nào trong tương lai mà không cần phải nhớ rằng chúng tôi đã hợp nhất nó vào và lấy nó ra.

Tôi muốn có thể nhận được càng gần luồng đó càng tốt. Tôi muốn tối ưu hóa cho "không phải nhớ những thứ trong tương lai", ngay cả khi nó làm cho mọi thứ mất nhiều bước hơn theo cách nào đó. (Điều này có thể là không thể ...)

+0

Có lý do nào khiến bạn không thể quay lại cam kết bằng cách sử dụng git reset --hard ORIG_HEAD? – urschrei

+0

Câu trả lời của tôi có cần thêm thông tin không? –

+0

urschrei: nếu tôi đã làm điều đó trên một chi nhánh trên một máy chủ, sau đó để đẩy các kết quả tôi sẽ phải sử dụng '- force', phải không? –

Trả lời

11

UPDATE:

Một công việc mà làm cho nó dễ dàng hơn để làm việc với các tính năng chi nhánh mỗi là ở đây: http://dymitruk.com/blog/2012/02/05/branch-per-feature/


(phần SVN của câu hỏi đã được trả lời cuối cùng)

Vâng, đây là cách bạn giới thiệu lại một tính năng mà bạn đã bỏ ghim. Xem xét lịch sử sau (giả sử bạn "phá hoại" một hợp nhất đã được):

x---x----x--x---x--M--U--L 
    \   /
     x--x--x--x-F 

F là chi nhánh tính năng, M là việc hợp nhất, U là điều ngược lại khi kh chạy tính năng đó, L là cam kết mới nhất.

Dưới đây là lựa chọn của bạn:

  1. Revert U (không --force cần thiết để đẩy):

    x---x----x--x---x--M--U--L--^U 
        \   /
        x--x--x--x-F 
    
  2. rebase F vào L (và sau đó hợp nhất --ff-only F') (không --force cần thiết để đẩy):

    x---x----x--x---x--M--U--L 
        \   /  \ 
         x--x--x--x-x   x'--x'--x'--x'--F' 
    
  3. rebase F vào L (và sau đó hợp nhất --no-ff F' - giữ gìn điểm chi nhánh mới của bạn) (không --force cần thiết để đẩy):

    x---x----x--x---x--M--U--L-------------------M2 
        \   /  \    /
         x--x--x--x-x   x'--x'--x'--x'--F' 
    
  4. rebase -i head^^ và loại bỏ U từ danh sách (--force là cần thiết để đẩy) :

    x---x----x--x---x--M--L 
        \   /
         x--x--x--x-F 
    
  5. rebase --onto M^1 L^ L để loại bỏ hợp nhất và hủy hợp nhất. Bây giờ bạn có thể remerge F sau.

        L' 
           /
    x---x----x--x---x--M--U--L 
        \   /
         x--x--x--x-F 
    

Để dẹp tất cả các tính năng cam kết, sử dụng modifier --squash về việc hợp nhất đầu tiên. Tôi sẽ để trí tưởng tượng của bạn thực hiện công việc về cách nó sẽ trông như thế nào trong lịch sử. Có một lý do tôi không khuyên bạn nên làm điều này. Có giá trị trong việc biết làm thế nào bạn có một tính năng làm việc và những bước nó đã làm. Việc sáp nhập tiếp theo sẽ dễ dàng hơn vì Git có thể kiểm tra lịch sử lý do tại sao một tệp nhất định trông giống như vậy. Đập các cam kết với nhau sẽ mất thông tin đó.

Có những hạn chế bổ sung có thể có hoặc không ảnh hưởng đến khả năng tận dụng lịch sử định tuyến lại của bạn.

Những gì tôi khuyên bạn nên luôn luôn đánh dấu những gì được phát hành với sự hợp nhất trống trong trang cái. Điều này được thực hiện thông qua hợp nhất với tùy chọn --no-ff. Bạn không bao giờ làm việc trên chủ và các cam kết duy nhất được thực hiện có những hợp nhất - không có cam kết thay đổi mã. Trong nhánh QA, bạn gắn thẻ cam kết đánh dấu điểm mà tại đó bạn đã giải phóng. Vì vậy, khi bạn thực hiện git merge --no-ff rc-12.2, bạn sẽ tự động tạo một nhận xét cam kết "đã hợp nhất rc-12.2".

Kiểm tra luồng git.

Hy vọng cung cấp cho bạn thêm chi tiết.

+1

Đó là một tổng quan tuyệt vời về các tùy chọn của tôi, nhưng câu hỏi của tôi là nếu có điều gì đó tôi có thể làm tại thời điểm hợp nhất ban đầu để làm cho mọi việc trở nên đơn giản hơn trong tương lai. Tôi vừa cập nhật câu hỏi của mình với phần "những gì tôi muốn". –

+1

Trong câu trả lời của bạn: đó là 4 tùy chọn riêng biệt, phải không? Muốn đánh số chúng? Ngoài ra, trong số họ sẽ yêu cầu '--force' nếu tất cả các chi nhánh đã được xuất bản từ xa? Sẽ tốt nếu bạn đánh dấu những người như vậy .. –

+0

Điều duy nhất tôi sẽ lo lắng là nếu bạn không có công việc trong dòng chính. Điều này sẽ dẫn đến việc hợp nhất nhanh về phía trước. Điều này không bảo toàn được điểm hợp nhất. Trong trường hợp đó, khi bạn thực hiện việc hợp nhất, hãy đảm bảo bạn chỉ định --no-ff để thực hiện một cam kết trống với 2 cha mẹ. Điều này sẽ bảo vệ điểm chi nhánh của bạn. Cho tôi biết nếu bạn cần thứ gì khác. –