Tôi tin rằng vấn đề là kết hợp công việc khác so với bạn nghĩ. Bạn viết
Vì nhánh phát hành mới chứa tất cả các thay đổi nhánh của tính năng (không có gì được sao lưu), tại sao nhánh mặc định cũng không nhận được tất cả các thay đổi này?
Khi bạn hợp nhất hai nhánh, không thể nghĩ về nó khi áp dụng tất cả thay đổi từ một chi nhánh lên nhánh khác. Vì vậy, chi nhánh default
không "nhận" bất kỳ thay đổi nào từ release2
. Tôi biết đây là cách chúng ta thường nghĩ về sự hợp nhất, nhưng nó không chính xác.
Điều gì thực sự xảy ra khi bạn hợp nhất hai changesets như sau:
Mercurial tìm thấy tổ tiên chung cho hai changesets.
Đối với mỗi tệp khác nhau giữa hai thay đổi Mercurial chạy three-way merge algorithm bằng cách sử dụng tệp tổ tiên, tệp trong changeset đầu tiên và tệp trong changeset thứ hai.
Trong trường hợp của bạn, bạn đang sáp nhập phiên bản 11 và 12. Các tổ tiên chung nhỏ nhất là phiên bản 8. Điều này có nghĩa rằng Mercurial sẽ chạy một ba chiều kết hợp giữa các tập tin từ đó sửa đổi:
Revision 8: không backout
Revision 11: tính năng chi nhánh đã được sao lưu ra
Revision 12: không backout
Trong một ba chiều hợp nhất, một sự thay đổi luôn Trumps không thay đổi. Mercurial thấy rằng các tập tin đã được thay đổi giữa 8 và 11 và nó thấy không có thay đổi giữa 8 và 12. Vì vậy, nó sử dụng phiên bản thay đổi từ phiên bản 11 trong hợp nhất. Điều này áp dụng cho bất kỳ thuật toán hợp nhất ba chiều nào. Bảng merge đầy đủ trông như thế này ở đâu old
, new
... là những nội dung của hunks phù hợp trong ba tập tin:
ancestor local other -> merge
old old old old (nobody changed the hunk)
old old new new (they changed the hunk)
old new old new (you changed the hunk)
old new new new (hunk was cherry picked onto both branches)
old foo bar <!> (conflict, both changed hunk but differently)
Tôi sợ rằng một merge changeset shouldn't be backed out ở tất cả vì hành vi hợp đáng ngạc nhiên này. Mercurial 2.0 và sau đó sẽ hủy bỏ và khiếu nại nếu bạn cố gắng backout một hợp nhất.
Nói chung, người ta có thể nói rằng thuật toán hợp nhất ba chiều giả định rằng tất cả thay đổi là tốt. Vì vậy, nếu bạn hợp nhất branch1
thành dev
và sau đó hoàn tác việc hợp nhất với một bản sao lưu, sau đó thuật toán hợp nhất sẽ nghĩ rằng trạng thái "tốt hơn" so với trước đây. Điều này có nghĩa là bạn không thể chỉ hợp nhất lại branch1
thành dev
sau này để nhận lại các thay đổi được sao lưu.
Điều bạn có thể làm là sử dụng "kết hợp giả" khi bạn nhập vào default
. Bạn chỉ cần hợp nhất và luôn giữ những thay đổi từ chi nhánh phát hành bạn đang sáp nhập vào default
:
$ hg update default
$ hg merge release2 --tool internal:other -y
$ hg revert --all --rev release2
$ hg commit -m "Release 2 is the new default"
Điều đó sẽ phụ bước vấn đề và lực lượng default
được giống như release2
. Điều này giả định rằng hoàn toàn không có thay đổi được thực hiện trên default
mà không được sáp nhập vào một chi nhánh phát hành.
Nếu bạn phải có khả năng tạo bản phát hành có các tính năng bị bỏ qua, thì cách "đúng" là không hợp nhất các tính năng đó. Sáp nhập là một cam kết mạnh mẽ: bạn nói với Mercurial rằng changeset hợp nhất bây giờ có tất cả những thứ tốt từ cả tổ tiên của nó. Miễn là Mercurial sẽ không cho phép bạn pick your own base revision when merging, thuật toán kết hợp ba chiều sẽ không cho phép bạn thay đổi ý định về một bản sao lưu.
Tuy nhiên, những gì bạn có thể làm là để phát lại bản sao lưu. Điều này có nghĩa là bạn giới thiệu lại các thay đổi từ chi nhánh tính năng của bạn trên chi nhánh phát hành của bạn. Vì vậy, bạn bắt đầu với một đồ thị như
release: ... o --- o --- m1 --- m2
/ /
feature-A: ... o --- o /
/
feature-B: ... o --- o --- o
Bây giờ bạn quyết định rằng Một đặc điểm là xấu và bạn backout hợp nhất:
release: ... o --- o --- m1 --- m2 --- b1
/ /
feature-A: ... o --- o /
/
feature-B: ... o --- o --- o
Sau đó bạn kết hợp tính năng khác vào chi nhánh phát hành của bạn:
release: ... o --- o --- m1 --- m2 --- b1 --- m3
/ / /
feature-A: ... o --- o / /
/ /
feature-B: ... o --- o --- o /
/
feature-C: ... o --- o --- o --- o --- o
Nếu bây giờ bạn muốn giới thiệu lại tính năng A, bạn có thể sao lưu b1
:
release: ... o --- o --- m1 --- m2 --- b1 --- m3 --- b2
/ / /
feature-A: ... o --- o / /
/ /
feature-B: ... o --- o --- o /
/
feature-C: ... o --- o --- o --- o --- o
Chúng ta có thể thêm các vùng đồng bằng để đồ thị để hiển thị tốt hơn những gì thay đổi ở đâu và khi:
+A +B -A +C --A
release: ... o --- o --- m1 --- m2 --- b1 --- m3 --- b2
Sau backout thứ hai này, bạn có thể kết hợp lại với feature-A
trong trường hợp changesets mới đã được thêm vào ở đó. Đồ thị bạn đang sáp nhập trông giống như:
release: ... o --- o --- m1 --- m2 --- b1 --- m3 --- b2
/ / /
feature-A: ... o -- a1 - a2/ /
/ /
feature-B: ... o --- o --- o /
/
feature-C: ... o --- o --- o --- o --- o
và bạn hợp nhất a2
và b2
. Tổ tiên chung sẽ là a1
. Điều này có nghĩa là những thay đổi duy nhất bạn sẽ cần cân nhắc trong quá trình hợp nhất ba chiều là những thay đổi giữa a1
và a2
và a1
và b2
. Tại đây, b2
đã có số lượng lớn các thay đổi "trong" a2
để hợp nhất sẽ nhỏ.
hg diff -r 9 -r 12 ??? –