2012-02-19 21 views
5

Tôi đang cố gắng thực hiện quá trình hợp nhất phức tạp trong một kho lưu trữ hg phức tạp. Tôi không hài lòng với "tổ tiên được chia sẻ mới nhất" mà Mercurial chọn để sử dụng làm "cơ sở" để thực hiện hợp nhất.Làm cách nào để chỉ định cơ sở hợp nhất để sử dụng trong 'hợp nhất hg'

Tôi muốn chỉ định một cam kết cụ thể về lựa chọn của riêng tôi để sử dụng làm cơ sở.

Điều này có thể thực hiện được không và nếu có thì làm cách nào?

Trả lời

14

Mercurial 3.0: Bây giờ bạn có thể chọn tổ tiên để sử dụng làm cơ sở hợp nhất. Bạn làm điều đó bằng cách thiết lập merge.preferancestor. Mercurial sẽ cho bạn biết về nó khi điều này có ý nghĩa. Với ví dụ dưới đây, bạn sẽ thấy:

$ hg merge 
note: using eb49ad46fd72 as ancestor of 333411d2f751 and 7d1f71140c74 
     alternatively, use --config merge.preferancestor=fdf4b78f5292 
merging x 
0 files updated, 1 files merged, 0 files removed, 0 files unresolved 
(branch merge, don't forget to commit) 

Mercurial trước khi phiên bản 3.0: Lazy Badger là đúng mà bạn không thể chọn tổ tiên chọn bởi Mercurial khi sử dụng nó từ dòng lệnh. Tuy nhiên, bạn có thể làm điều đó trong nội bộ và không quá khó để viết phần mở rộng cho việc này:

from mercurial import extensions, commands, scmutil 
from mercurial import merge as mergemod 

saved_ancestor = None 

def update(orig, repo, node, branchmerge, force, partial, ancestor=None): 
    if saved_ancestor: 
     ancestor = scmutil.revsingle(repo, saved_ancestor).node() 
    return orig(repo, node, branchmerge, force, partial, ancestor) 

def merge(orig, ui, repo, node=None, **opts): 
    global saved_ancestor 
    saved_ancestor = opts.get('ancestor') 
    return orig(ui, repo, node, **opts) 

def extsetup(ui): 
    extensions.wrapfunction(mergemod, 'update', update) 
    entry = extensions.wrapcommand(commands.table, 'merge', merge) 
    entry[1].append(('', 'ancestor', '', 'override ancestor', 'REV')) 

Đặt tệp này vào một tệp và tải tiện ích. Bây giờ bạn có thể sử dụng

hg merge --ancestor X 

để ghi đè tổ tiên bình thường. Như bạn đã phát hiện ra, điều này không tạo sự khác biệt nếu có nhiều tổ tiên có thể. Tình huống đó nảy sinh nếu bạn có các vụ sáp nhập chéo chéo. Bạn có thể tạo ra một trường hợp như vậy với các lệnh:

hg init; echo a > x; hg commit -A -m a x 
hg update 0; echo b >> x; hg commit -m b 
hg update 0; echo c >> x; hg commit -m c 
hg update 1; hg merge --tool internal:local 2; echo c >> x; hg commit -m bc 
hg update 2; hg merge --tool internal:local 1; echo b >> x; hg commit -m cb 

Đồ thị trông như thế này:

@ changeset: 4:333411d2f751 
|\ 
+---o changeset: 3:7d1f71140c74 
| |/ 
| o changeset: 2:fdf4b78f5292 
| | 
o | changeset: 1:eb49ad46fd72 
|/ 
o changeset: 0:e72ddea4d238 

Nếu bạn nhập thông thường bạn có được changeset eb49ad46fd72 như tổ tiên và các tập tin x chứa:

a 
c 
b 
c 

Nếu thay vào đó bạn sử dụng hg merge --ancestor 2, bạn sẽ nhận được kết quả khác:

a 
b 
c 
b 

Trong cả hai trường hợp, KDiff3 của tôi có thể xử lý việc hợp nhất tự động mà không báo cáo bất kỳ xung đột nào. Nếu tôi sử dụng chiến lược hợp nhất "đệ quy" và chọn e72ddea4d238 làm tổ tiên, thì tôi sẽ trình bày với một xung đột hợp lý. Git sử dụng chiến lược phối hợp đệ quy theo mặc định.

+0

Đó là một WOW! Hoạt động hoàn hảo. Cảm ơn nhiều. Trong thực tế, tôi không hiểu tại sao tính năng này không được đưa vào Mercurial. Trong hầu hết các trường hợp, người ta sẽ không cần đến nó, nhưng trong trường hợp cần thiết, nó có thể tiết kiệm hàng giờ xung đột để giải quyết, hoặc thậm chí ngăn chặn việc hợp nhất tự động không chính xác. Tôi vừa gặp phải những vấn đề như vậy sau khi những thay đổi không chính xác đối với repo. –

-1

Bạn không thể làm điều đó. Bởi vì tổ tiên được chia sẻ mới nhất IS cơ sở thực sự cho việc hợp nhất của bạn

Nếu bạn muốn thực hiện hợp nhất và không muốn nghĩ lại (vì logic của bạn hiển thị/tôi/giả định sai và giải pháp-đường dẫn) bạn có thể đi clone-rebase-merge-export-import tuyến đường đắp vá

+3

có thể có nhiều tổ tiên được chia sẻ ứng cử viên "không kém phần", nhưng khác nhau. xem http://man.he.net/man1/git-merge-base –

+0

@LucasMeijer - 1. chúng tôi đã nói về Mercurial, chứ không phải Git 2. Họ ** không phải là "bình đẳng", bởi vì tổ tiên mới nhất là * "tốt hơn" * –

+2

Lý do của bạn để biết rằng mới nhất là _always_ là tốt nhất. Imo, không có cách nào để biết điều đó. (mặc dù thường là mới nhất là tốt nhất). liên kết git chỉ minh họa một tình huống mà không có "tốt nhất", một tình huống có thể xảy ra trong thủy ngân giống hệt nhau. –

1

Cơ sở chỉ được sử dụng làm đầu vào khác cho công cụ hợp nhất của bạn. Nếu bạn tắt premerge trong Cấu hình Công cụ Hợp nhất của mình (chèn sẵn tạo "lựa chọn hiển nhiên" cho bạn khi không có xung đột) và gọi công cụ hợp nhất của bạn theo cách thủ công cung cấp bản sao của 3 bản sửa đổi bạn muốn làm địa phương, từ xa và cơ sở, bạn có thể nhận bất cứ điều gì bạn muốn trong công cụ hợp nhất của bạn. Chỉ cha mẹ bên trái và cha mẹ bên phải thực sự được ghi lại trong hợp nhất.

+0

yeah , Tôi có thể đi theo con đường hoàn toàn thủ công, và đối với mỗi mergeconflict, sao chép thủ công dán vào cơ sở tôi muốn. Tôi đang xem xét 20 + xung đột hợp nhất mặc dù, và figured chúng ta phải có thể tìm ra một cái gì đó tự động. –

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