2014-10-24 20 views
9

tôi sử dụng lệnh sau đây để áp dụng một bản vá trong Mercurial, không cam kết nó:Làm thế nào để áp dụng một số bản vá lỗi bằng cách sử dụng dòng lệnh hg khi đã có những thay đổi chưa được cam kết?

hg import patch.diff --no-commit 

Nó hoạt động tuyệt vời, tuy nhiên nếu tôi cố gắng áp dụng nhiều bản vá lỗi cùng một lúc như thế này:

hg import patch1.diff --no-commit 
hg import patch2.diff --no-commit 
... 

tôi nhận được thông báo lỗi này sau khi thứ hai cam kết:

abort: uncommitted changes 

Nếu tôi làm giống hệt nhau trong SourceTree (áp dụng patch1 sau đó vá 2 và chọn "Sửa đổi tập tin sao chép làm việc") nó hoạt động: hai bản vá được áp dụng trên bản sao làm việc, thay đổi từ patch1 và patch2 kết hợp/gấp lại với nhau.

Làm cách nào để thực hiện tương tự bằng cách sử dụng dòng lệnh hg?

Trả lời

10

Đây là hành vi được thiết kế bởi các tác giả Mercurial: hãy tưởng tượng rằng bạn đã thực hiện các thay đổi không được cam kết trong bản sao làm việc, chúng tôi không muốn hg import tự động áp dụng bản vá và cam kết cả thay đổi và bản vá của bạn thay đổi với thông báo nhật ký sai và cả hai thay đổi bị vướng vào nhau.

Đây là lý do tại sao hg help import nói:

Because import first applies changes to the working directory, import will 
abort if there are outstanding changes. 

lệnh Việc nhập khẩu được nhiều hơn cho nhập khẩu changesets (với metedata khi dữ liệu đến từ hg export) so với các bản vá lỗi chỉ áp dụng. Nếu bạn có thay đổi của riêng bạn trong bản sao làm việc, bạn có thể ví dụ vẫn sử dụng hg import --bypass và không có lỗi nào xảy ra ở đó vì cam kết được áp dụng trực tiếp cho kho lưu trữ chứ không phải bản sao làm việc. (Lưu ý: nhưng sau đó nếu bạn chỉ cam kết thay đổi của bạn, bạn sẽ nhận được hai đầu, rằng bạn sẽ cần phải hợp nhất .. :-).

Giải pháp với dòng lệnh cho hệ thống Unix là sử dụng lệnh patch trực tiếp thay vì hg import vì sau đó không kiểm tra sửa đổi cục bộ sẽ được thực hiện. Ví dụ:

for i in 1 2 etc. 
do 
    patch -p1 < patch$i.diff 
done 
hg commit ... 

Đối với phi Unix hệ thống bạn cũng có thể có một giải pháp Mercurial tinh khiết bằng cách cài đặt phần mở rộng shelve, cho phép nó trong tập tin cấu hình toàn cầu của bạn (mercurial.ini), và sau đó sử dụng shelve để xử lý thao tác trộn một bản vá sau khi khác:

hg import --no-commit patch1.diff 
hg shelve 
hg import --no-commit patch2.diff 
hg unshelve 
etc. 

Nếu bao giờ một cuộc xung đột có thể xảy ra, shelve sẽ phát hiện nó và bạn sẽ phải giải quyết sau đó nó nói shelve rằng nó được giải quyết với các tùy chọn --continue.

Hy vọng nó sẽ hữu ích.

+0

Về lệnh 'patch': Tôi không có tiện ích trong thư mục thủy tinh (cửa sổ), bạn đang nói về' hg patch'? Nếu vậy tôi đã thử nó trước khi hỏi câu hỏi SO này và nó chỉ báo cáo thông báo lỗi giống như 'hg import' – tigrou

+0

Nó có vẻ là một tiện ích' Linux', có thể cài đặt 'cygwin' sẽ làm cho nó hoạt động. – tigrou

+0

Tôi không nhận ra bạn đã không sử dụng Unix, có 'patch' là một tiện ích Unix. Bạn có thể: sử dụng phiên bản Cygwin, sử dụng bản sao như bạn đã đề cập, hoặc tôi nghĩ bạn có thể có giải pháp "thuần-hg", tôi sẽ thêm nó vào câu trả lời của tôi ..;) –

4

Đây là những gì làm việc cho tôi (cửa sổ giải pháp), ý tưởng đã được nắm lấy từ Christophe Muller câu trả lời:

copy /b "patch01.diff" + "patch02.diff" + ... + "patchXX.diff" "all.diff" 

hg import "all.diff" --no-commit 

Nó chỉ đơn giản nối tất cả các bản vá lỗi với nhau (như là một tập tin lớn) sau đó áp dụng nó.

2

Một giải pháp có thể là sử dụng Mercurial Queues (lưu ý - có vẻ như tiện ích mở rộng này "thường được xem là không dùng nữa" nhưng chưa được dùng nữa và được cài đặt sẵn với Mercurial).

Nếu bạn chưa từng sử dụng MQ trước đây, nó rất tiện dụng nếu một chút phức tạp. Nhưng nó có hiệu quả cho phép bạn tạo hàng đợi của các bản vá lỗi, mà có thể được đẩy, popped, lại ra lệnh vv

Bạn có thể sử dụng nó để giúp giải quyết vấn đề của bạn như sau:

:: if you don't already have MQ initialised for the repo, do so 
hg init --mq 

:: import the patches you want as queue entries 
hg qimport -P patch1.diff 
hg qimport -P patch2.diff 
hg qimport -P patch3.diff 

Các -P tùy chọn đẩy các thay đổi khi bạn nhập chúng, điều đó có nghĩa là bạn đang kiểm tra hiệu quả rằng chúng áp dụng chính xác. Khi bạn có tất cả các bản vá lỗi được nhập khẩu vào MQ, bật chúng tất cả (vì vậy không được áp dụng và bạn trở lại nơi mà bạn bắt đầu), và gấp tất cả chúng vào một mới, kết hợp vá:

:: go back to no patches applied, and create a new patch at the front of the queue 
hg qpop --all 
hg qnew -m "Your planned commit message" combined_patches 
:: fold the named patches into the current one 
hg qfold patch1 patch2 patch3 

Sau đó, nếu bạn hài lòng với bản vá kết quả, chỉ cần chuyển đổi nó thành một thay đổi "thực":

:: convert combined_patches into a "real" changeset 
hg qfinish combined_patches 
+0

Hàng đợi Mercurial được phân phối với Mercurial, nhưng không được kích hoạt theo mặc định. Trong trường hợp bạn đang tự hỏi tại sao nó thường được xem là không dùng nữa: http://gregoryszorc.com/blog/2014/06/23/please-stop-using-mq/ – Mathiasdm

+0

@Mathiasdm: Ah, tôi phải kích hoạt nó bản thân tôi sau đó :) - và vâng, tôi đã thực sự đọc bài báo đó ngay bây giờ. – icabod

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