2012-05-21 29 views
15

Là phương pháp đáng tin cậy nhất để đi từng người một, sử dụng lệnh backout cho từng thay đổi, hoặc có cách tạo một thay đổi đảo chiều lớn để bao gồm toàn bộ bó [sửa: không tiếp giáp] changesets.Cách tốt nhất để sao lưu nhiều thay đổi trong mercurial là gì?

Nếu từng người một, đặt hàng có vấn đề không? (Có nên đi từ đầu đến đầu tiên không?)

Phương pháp tốt nhất có khác nhau nếu có sự hợp nhất giữa các tiểu dự án khác nhau trên đường đi không?

Điều này có xu hướng diễn ra suôn sẻ trong trải nghiệm của bạn không? :-)

+0

Tôi thấy các lệnh có thể khác nhau có thể có liên quan. diff -r có thể mất nhiều phiên bản, nhưng tôi nhầm lẫn về ngữ nghĩa chính xác. export -r thực hiện nhiều thay đổi. backout mất một duy nhất. Tôi không chắc chắn về ưu/khuyết điểm của mỗi xuất khẩu –

+0

không có cờ --reverse, sai lầm của tôi ở đó. –

Trả lời

5

Có tùy chọn --collapse cho rebase.

Helgi 's answer thể được nâng cấp thành:

1 -- A -- 2 -- B -- 3 -- C -- 4 -- 5 
          \ 
          C' -- B' -- A' 

$ hg update --clean C 
$ hg backout --rev C --message "Backed out changeset: C" 
$ hg backout --rev B 
$ hg commit --message "Backed out changeset: B" 
$ hg backout --rev A 
$ hg commit --message "Backed out changeset: A" 
$ hg rebase --collapse --source C' --dest 5 
$ hg commit --message "Backed out C, B, A" 

đó sẽ dẫn đến việc sau

1 -- A -- 2 -- B -- 3 -- C -- 4 -- 5 -- C'B'A' 

Tuy nhiên, sao lưu ra ở chi nhánh riêng biệt có thể dẫn đến [logic] xung đột trong hợp nhất tiếp theo.

1 -- A -- 2 -- B -- 3 -- X -- 4 
        \   \ 
         B' -- A' -- M 

nếu X phụ thuộc vào A hoặc B, sau đó M sẽ có xung đột (mâu thuẫn ít nhất logic).

+1

Điều này thật tuyệt vời, không chỉ dành cho --collapse. Sử dụng các backouts riêng biệt (last-to-first) cho phép các thay đổi không tiếp giáp. Vì điều này có thể được thực hiện trong một tình huống phức tạp, tôi nghĩ rằng tôi sẽ ưu tiên một hợp nhất đơn giản hơn là rebaseing. Chi nhánh với các thay đổi ngược lại có thể bị sụp đổ (với bất kỳ phương thức khác nhau) hay không. Một điều cần lưu ý là lặp lại từ câu trả lời của Helgi, là bạn không thể sử dụng backout nếu có bất kỳ sự hợp nhất nào để đảo ngược. ["Cách an toàn duy nhất để đối phó với việc hợp nhất xấu là từ bỏ chi nhánh."] (Http://mercurial.selenic.com/wiki/Backout#Backout_of_a_Merge_Changeset) –

+0

Tôi nên thêm, 'diff --reverse', như được sử dụng trong câu trả lời của riêng tôi, cũng không tốt cho việc hợp nhất. Cho rằng không phải sẽ làm việc với các hợp nhất, tôi nghĩ rằng backout/cam kết là thuận tiện hơn nhiều so với giải pháp của tôi. –

+0

@JoshuaGoldberg hậu quả của việc kết hợp các backouts cá nhân đơn giản là, như bạn đã đề cập, bạn không thể 'backout' hợp nhất backout của bạn .. vì vậy đối với tôi, tốt hơn là' rebase' chúng .. –

8

Nếu bạn không có sự hợp nhất nào, bạn có thể trả lại từng thay đổi riêng lẻ (hoặc theo thứ tự ngược lại), hoặc nếu có nhiều thay đổi, hãy thực hiện với một bản vá nghịch đảo lớn.

Nếu bạn có các thay đổi tốt trên đỉnh những cái bạn cần để thoát ra, hãy cam kết đắp miếng inverse lên trên các thay đổi xấu gần đây nhất, sau đó đặt lại chúng lên đầu nhánh.

1 -- 2 -- A -- B -- C -- 3 -- 4 
        \ 
         C'B'A' 

$ hg up C 
$ hg diff -r C:2 > backout.diff 
$ hg import --no-commit backout.diff 
$ hg ci -m "Backout A, B, C" 
$ hg up 4 
$ hg rebase -s C'B'A -d . 

Sẽ có vấn đề nếu bạn muốn sao lưu ra changesets merge, xem this wiki page để biết thêm thông tin.

Trong trường hợp này, nếu có thể, hãy xem xét việc làm lại nhánh và tước dòng cũ. Nếu không, bạn có thể phải từ bỏ chi nhánh hoàn toàn, cứu vãn những thay đổi tốt thông qua ghép hoặc cấy ghép.

+0

Tính năng này có hoạt động với các thay đổi không tiếp giáp không? Tôi nhận được ấn tượng rằng nó sẽ không, do thiếu sự hỗ trợ rõ ràng trên http://stackoverflow.com/questions/5435567/mercurial-diff-multiple-changesets-at-same-time Tức là, điều gì sẽ xảy ra nếu tôi nói 'hg diff -r 'keyword (xyz)'' trong đó từ khóa chọn một loạt các thay đổi không tiếp giáp liên quan đến xyz dự án? –

+0

@JoshuaGoldberg: Không, nó sẽ nhổ ra những khác biệt riêng lẻ. Tuy nhiên, bạn có thể làm một cái gì đó như 'hg diff -r" 100: 90 "-I src/subdir' để thu hẹp sự khác biệt của bạn thành tập hợp các tệp hoặc thư mục. Bạn có thể chỉ định một số '-I' hoặc '-X' (loại trừ). – Helgi

0

Nếu bạn không muốn thay đổi "backout" trong lịch sử của mình, bạn cũng có thể làm một việc khác:
Tạo bản sao kho lưu trữ, nhưng chỉ đến lần thay đổi cuối cùng mà bạn không muốn nhận loại bỏ.

Xem Mercurial: Fix a borked history để biết ví dụ về cách thực hiện việc này.

Nếu kho lưu trữ của bạn là một địa phương, đó là tất cả những gì bạn phải làm. Nhưng nếu các thay đổi xấu đã được đẩy vào kho lưu trữ trung tâm, bạn cần truy cập máy chủ để xóa kho lưu trữ đó và thay thế bằng bản sao của bạn.
Ngoài ra, nếu ai đó đã rút khỏi repo với các thay đổi xấu, họ cần phải xóa và sao chép lại (nếu không, các thay đổi xấu nằm trong repo trung tâm một lần nữa ngay khi một trong những người khác đẩy lại).
Vì vậy, nó phụ thuộc vào hoàn cảnh cho dù giải pháp này là tốt nhất cho bạn ...

4

Điều tôi đưa ra là không phù hợp, nhưng đã hoàn thành công việc, mặc dù những thay đổi tôi cần để thoát ra được xen kẽ với công việc khác và có một số nhánh nội bộ. Đây là những gì tôi đã làm. (Cảm nhận và cải tiến được hoan nghênh.)

Got một danh sách của tất cả các changesets (mà tôi sử dụng để tạo ra các lệnh dưới đây):

hg log -r 'keyword(xyz)' --template '{rev}\n' 

tạo một bản vá cho mỗi changeset:

hg diff -p -U 8 --reverse -c 15094 > 15094.rev.patch 
hg diff -p -U 8 --reverse -c 15095 > 15095.rev.patch 
... 

Sau đó, áp dụng từng bản vá ngược.Ở đây, vấn đề trật tự, cuối cùng-to-đầu tiên:

hg import -m "reversing changeset 15302" 15302.rev.patch 
hg import -m "reversing changeset 15292" 15292.rev.patch 
... 

Quá trình này bị gián đoạn nhiều lần cho các ô hợp nhất đã không đi qua sẽ tự động, nơi mà tôi đã phải tự áp dụng thay đổi vào một tập tin từ tập tin .rej và sau đó tự cam kết, trước khi chọn lên hàng nhập khẩu nơi nó đã tắt.

Cuối cùng (trong một bản sao khác ... tôi đã đề cập đến tôi đã làm điều này tất cả trong một bản sao?) Tôi nén toàn bộ tập hợp các thay đổi ngược thành một changeset sử dụng hg histedit -o và lệnh gấp của nó.

Bây giờ tôi có một thay đổi duy nhất mà tôi có thể đảo ngược và áp dụng nếu tôi quyết định đưa công việc trở lại sau này (Mặc dù nếu tôi băng qua cây cầu đó, tôi có thể áp dụng các bản vá "chuyển tiếp" một lần nữa để có được thông tin đổ lỗi/chú thích tốt hơn)

+0

Từ 'help diff':" diff có thể tạo ra kết quả không mong muốn cho việc hợp nhất, ... "Nó chỉ cung cấp sự khác biệt cho một phụ huynh, do đó, như backout, quá trình này không tốt cho việc hợp nhất. –

1

Đây là cách bạn có thể làm điều đó với TortoiseHg. Tất nhiên bạn có thể làm tương tự với dòng lệnh.

Với lịch sử này, nơi bạn wan't để thoát khỏi changeset A, B và C:

1 -- 2 -- A -- B -- C -- 3 -- 4 

cập nhật đầu tiên cho phiên bản 2.

Sau đó rebase là người đầu tiên của bất kỳ sửa đổi sau này bạn wan't để giữ - trong trường hợp phiên bản này 3.

lịch sử của bạn bây giờ trông như thế này:

1 -- 2 -- A -- B -- C 
     \ 
     3 -- 4 

Bây giờ nâng cấp lên revison 4.

Và cuối cùng sử dụng "Hợp nhất với địa phương" để hợp nhất phiên bản C lên phiên bản 4.

Tại thời điểm này điều quan trọng là bạn chọn tùy chọn "Bỏ tất cả thay đổi từ mục tiêu hợp nhất (khác) sửa đổi ".

Mô tả có thể không hợp lý nhất, nhưng điều đó có nghĩa là bạn hợp nhất thủ thuật C cũ về nhánh mặc định - nhưng không có thay đổi A, B và C.

Kết quả là:

1 -- 2 -- A -- B -- C -- 
     \   /
     3 -- 4 

Cam kết và bạn đã hoàn tất.

+0

Điều này rất hữu ích, nhưng trong một rất nhiều trường hợp chiến thuật này sẽ không có sẵn --- nếu những thay đổi đã được đẩy. Rebase không phải là một lựa chọn trong trường hợp đó. Hữu ích cho những thay đổi cục bộ, mặc dù, cảm ơn cho ý tưởng. –

+0

Vâng, bạn nói đúng: Nó sẽ không hoạt động sau khi các thay đổi đã được đẩy. –

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