Tôi đã tìm thấy lời giải thích tốt cho Cách hoàn nguyên Hợp nhất từ liên kết này và tôi sao chép dán phần giải thích bên dưới và nó sẽ hữu ích chỉ trong trường hợp nếu liên kết bên dưới không hoạt động.
Làm thế nào để hoàn nguyên một sự hợp nhất bị lỗi
Alan (alan@clueserver.org) cho biết:
Tôi có một chi nhánh chính. Chúng tôi có một chi nhánh mà một số nhà phát triển đang thực hiện. Họ tuyên bố nó đã sẵn sàng. Chúng tôi hợp nhất nó vào nhánh chủ. Nó phá vỡ một cái gì đó để chúng tôi hoàn nguyên hợp nhất. Họ thay đổi mã. họ đưa nó đến một điểm mà họ nói nó ổn và chúng tôi hợp nhất lại. Khi kiểm tra, chúng tôi thấy rằng các thay đổi mã được thực hiện trước khi hoàn nguyên không nằm trong nhánh chính, nhưng mã thay đổi sau nằm trong nhánh chính. và yêu cầu giúp đỡ phục hồi từ tình huống này.
Lịch sử ngay sau khi "hoàn nguyên hợp nhất" sẽ như thế này:
---o---o---o---M---x---x---W
/
---A---B
Trong đó A và B ở bên phát triển không tốt lắm, M là sự hợp nhất mang lại những thay đổi sớm này vào tuyến chính, x là những thay đổi không liên quan đến những gì nhánh bên đã làm và đã thực hiện trên tuyến chính và W là " hoàn nguyên hợp nhất M "(không W nhìn M lộn ngược?). IOW, "diff W ^ .. W" tương tự như "diff -RM ^ .. M".
Một "hoàn nguyên" của hợp nhất có thể được thực hiện với:
$ git Revert -m 1 M
Sau khi các nhà phát triển của nhánh bên sửa lỗi, lịch sử có thể như sau:
---o---o---o---M---x---x---W---x
/
---A---B-------------------C---D
trong đó C và D phải sửa những gì đã bị hỏng ở A và B, và bạn có thể đã có một số thay đổi khác trên tuyến chính sau W.
Nếu bạn hợp nhất nhánh bên được cập nhật (với D ở đầu), sẽ không có thay đổi nào được thực hiện trong A hoặc B, vì chúng được hoàn nguyên bởi W. Đó là những gì Alan thấy.
Linus giải thích tình huống:
Hoàn nguyên một cam kết thông thường chỉ có hiệu quả hoàn tác những gì cam kết đó đã làm, và khá đơn giản. Nhưng hoàn nguyên một cam kết hợp nhất cũng hoàn tác dữ liệu mà cam kết đã thay đổi, nhưng nó hoàn toàn không ảnh hưởng gì đến lịch sử mà hợp nhất có. Vì vậy, sự hợp nhất sẽ vẫn tồn tại và nó vẫn sẽ được coi là kết hợp hai nhánh lại với nhau và các sự hợp nhất trong tương lai sẽ thấy sự hợp nhất đó là trạng thái chia sẻ cuối cùng - và hoàn nguyên hoàn nguyên hợp nhất sẽ không ảnh hưởng đến điều đó. Vì vậy, một "hoàn nguyên" hoàn tác các thay đổi dữ liệu, nhưng nó không phải là rất nhiềumột "hoàn tác" theo nghĩa là nó không hoàn tác các tác động của một cam kết đối với lịch sử kho lưu trữ. Vì vậy, nếu bạn nghĩ "hoàn nguyên" là "hoàn tác", thì bạn sẽ luôn bỏ lỡ phần hoàn nguyên này. Vâng, nó hoàn tác dữ liệu, nhưng không, nó không hoàn tác lịch sử. Trong tình huống như vậy, trước tiên bạn muốn hoàn nguyên lại lần hoàn nguyên trước đó, điều này sẽ làm cho lịch sử trông như thế này:
---o---o---o---M---x---x---W---x---Y
/
---A---B-------------------C---D
Trong đó Y là hoàn nguyên của W. Như vậy "hoàn nguyên hoàn nguyên" có thể được thực hiện với:
$ git Revert W
Lịch sử này sẽ (bỏ qua những xung đột có thể có giữa những gì W và W..Y đã thay đổi) tương đương với việc không có W hoặc Y trong lịch sử:
---o---o---o---M---x---x-------x----
/
---A---B-------------------C---D
và sáp nhập nhánh bên một lần nữa sẽ không có xung đột phát sinh từ một lần hoàn nguyên trước đó và hoàn nguyên của hoàn nguyên.
---o---o---o---M---x---x-------x-------*
/ /
---A---B-------------------C---D
Tất nhiên những thay đổi được thực hiện trong C và D vẫn có thể xung đột với những gì được thực hiện bởi bất kỳ x nào, nhưng đó chỉ là xung đột hợp nhất bình thường.