Tôi có thể cam kết bí mật ở Mercurial không?


109

Tôi có một số cam kết thực sự chỉ là một. Nếu tôi đang sử dụng git, tôi sẽ sử dụng:

git rebase -i <some-commit-before>

và sau đó ép chúng.

Tôi có thể làm điều đó một cách dễ thương không? Nếu vậy, làm thế nào?

Câu trả lời:


88

Có, bạn có thể làm điều này bằng cách sử dụng thương mại mà không có bất kỳ phần mở rộng nào bằng cách Kết hợp các bộ thay đổi .

Ngoài ra, nếu bạn muốn sử dụng tiện ích mở rộng, bạn có thể sử dụng:


Vâng, tôi đã tìm ra câu trả lời đó từ những câu hỏi dupe mà tôi thích trong phần bình luận của tôi về câu hỏi chung. Tôi nghĩ đó là câu trả lời của bạn trên đó.
Ry4an Brase

4
Một lưu ý nhỏ: Phần mở rộng Histedit được phân phối với Mercurial 2.3 trở lên. Bạn chỉ cần kích hoạt nó.
Paidhi

1
Trong tài liệu Concatenating Changesets sử dụng các khái niệm trừu tượng về "repos", làm cách nào để tôi tham chiếu đến chúng? Ví dụ: hg -R oldrepo xuất khẩu ... sản xuất "hủy bỏ: kho oldrepo không tìm thấy!
Aleksandr Levchuk

13
Chỉ đang cố gắng bóp nghẹt 2 cam kết. Tôi có thực sự cần một trang wiki với hơn 10 lệnh hoặc phần mở rộng thay thế không?
Aleksandr Levchuk

3
Xem các bình luận. Histedit hiện đang được xây dựng-in, bạn chỉ cần kích hoạt nó (vì không có lệnh mặc định sẽ sửa đổi lịch sử)
Ry4an Brase

43

Yêu thích của tôi là hg strip --keeplệnh. Và sau đó tôi cam kết tất cả các thay đổi trong một lần cam kết.

Đó là cách nhanh nhất và thoải mái nhất đối với tôi, vì tôi thích thực hiện nhiều cam kết nhỏ trong công việc hàng ngày của mình;)


Lưu ý 1: stripcần có một tiện ích mở rộng tích hợp mqđể được bật.
Lưu ý 2: Ứng dụng khách Git / Mercurial yêu thích của tôi (SmartGit / Hg) gắn với --keeptham số mặc định trong suốt strip. Và điều còn thuận tiện hơn nữa: nó cung cấp tùy chọn có tên join commits:]


4
Lệnh đầy đủ cho dải hg là: hg strip --keep --rev [rev] đâu revlà số phiên bản đầu tiên cam kết mà bạn muốn bí với người cuối cùng
Nicolas Forney

3
@NicolasForney Không chính xác, --revlà không bắt buộc, đầy đủ lệnh làhg strip --keep [rev]
G. Demecki

Tôi bắt buộc phải sửa đổi trong 3.3.3: hg help stripcho hg strip [-k] [-f] [-n] [-B bookmark] [-r] REV...và bỏ qua sửa đổi mang lại cho tôi abort: empty revision set.
Roman Starkov

3
Sử dụng hg stripkhông phải là ý tưởng tốt nhất. Nó không chính xác an toàn. Hãy thử hg histedit, thậm chí có thể thử sử dụng tiện ích mở rộng phát triển.
Martin Thomson

Có vẻ là cách tự nhiên nhất cho người git;)
foo

32

Các phần mở rộng rebase làm việc như một nét duyên dáng. Để bí 2 cam kết:

$ hg rebase --dest .~2 --base . --collapse

Dấu chấm là một phím tắt cho bản sửa đổi hiện tại.

Điều đó thậm chí còn dễ dàng hơn khi bạn có một vài cam kết trên một nhánh và muốn thu gọn tất cả chúng thành một:

$ hg rebase --dest {destination branch (e.g. master)} --base . --collapse

Cách thức hoạt động:

nhập mô tả hình ảnh ở đây

(từ http://mercurial-scm.org/wiki/RebaseExtension#Collapsing )


1
Bạn đã tìm thấy "~ 2" cho hai cam kết ở đâu?
Mi-La

1
Nó được giải thích trong chủ đề tập hợp lại, xem phần trợ giúp hg.
mark và

13

Nếu bạn đang đọc câu trả lời này, bạn có thể quên mọi tùy chọn khác được đề cập trong câu trả lời này và sử dụng foldlệnh từ tiện ích mở rộng evolve .

evolvelà một phần mở rộng của thương mại giúp chúng ta có được lịch sử có thể thay đổi an toàn, mặc dù vậy nó vẫn còn đang thử nghiệm. Bạn có thể sử dụng nó bằng cách sao chép nó từ repo của nó và thêm nó vào .hgrc của bạn như thế này.

[extensions]
evolve = ~/evolve/hgext/evolve.py

Giả sử rằng bạn đã nhân bản repo evolve trong thư mục chính của mình. Bây giờ bạn đã tốt để đi. Bạn cũng có thể tìm kiếm sự giúp đỡ bằng cách hg help fold.

Lệnh gấp

Bạn yêu foldcầu thu gọn / gấp một chuỗi cam kết tuyến tính mà không bị phá vỡ. Màn hình đầu tiên có chức năng gì, nó tạo ra một tập hợp thay đổi mới chứa các thay đổi từ tất cả các tập hợp thay đổi và đánh dấu tất cả các cam kết đó là lỗi thời. Bạn có thể có cái nhìn sâu hơn về vấn đề này tại tài liệu .

Bây giờ giả sử bạn có lịch sử sau đây.

a -> b -> c -> d -> e -> f -> g

Bạn muốn bí e, fg. Bạn có thể làm

hg up g
hg fold -r e

Kết quả sẽ là

a -> b -> c -> d -> h

nơi hlà changeset trong đó có sự thay đổi từ tất cả ba cam kết e, fg.

Bạn cũng có thể gấp các tập thay đổi từ giữa lịch sử, tức là không nhất thiết bạn phải chọn một chuỗi bao gồm mẹo. Giả sử bạn muốn gấp b, cd. Bạn có thể làm

hg up d
hg fold -r b
hg evolve --all

Điều này sẽ dẫn đến

a -> i -> j

nơi ilà changeset gấp b, c, djlà changeset giống như h. Hướng dẫn sử dụng Evolve là phải đọc.


Có vẻ như rebase bao gồm hầu hết (có thể là tất cả?) Các trường hợp sử dụng của tiện ích mở rộng đó và chắc chắn là trường hợp được hỏi trong câu hỏi này. Tính năng tuyệt vời của tiện ích mở rộng đó là ẩn (thay vì xóa) các bản sửa đổi mà bạn thay thế, nhưng --keeptùy chọn rebase bao gồm điều này (tiếp theo là đánh dấu các bản sửa đổi là bí mật hoặc sử dụng dải trên chúng khi bạn đã kiểm tra kết quả). Thậm chí có thể di chuyển các bản sửa đổi giữa các bản sửa đổi khác với một chuỗi hai lệnh rebase.
Arthur Tacca

... ngoài ra, nếu bạn đang làm điều gì đó thực sự phức tạp, bạn luôn có thể sao chép repo cục bộ trước để sử dụng làm bản sao lưu. Xem xét mức độ hiếm (hy vọng là như vậy!), Việc học cách sử dụng một tiện ích mở rộng hoàn toàn mới sẽ ít tốn công sức hơn.
Arthur Tacca

"NameError: name 'execfile' không được định nghĩa" —mà nghĩa là evolve được viết bằng Python 2, về cơ bản là thời kỳ đồ đá.
Neil G

1
@NeilG bleurial chưa hỗ trợ Python 3.
Pulkit Goyal

2
@NeilG vâng, cộng đồng lanh lợi đang làm việc chăm chỉ để nhận được sự hỗ trợ của py3 càng sớm càng tốt.
Pulkit Goyal

1

Với Mercurial 4.8 (tháng 11 năm 2018, 9 năm sau), bạn có thể xem xét lệnh mới hg absorb(trước đây nó là một tính năng thử nghiệm ).

Xem " Thay đổi cam kết hấp thụ trong Mercurial 4.8 "

Phần mở rộng hấp thụ sẽ thực hiện mỗi thay đổi trong thư mục làm việc của bạn, tìm ra cam kết nào trong chuỗi của bạn đã sửa đổi dòng đó và tự động sửa đổi thay đổi đối với cam kết đó.
Nếu có bất kỳ sự không rõ ràng nào (tức là nhiều cam kết được sửa đổi trên cùng một dòng), thì hấp thụ sẽ chỉ cần bỏ qua thay đổi đó và để nó trong thư mục làm việc của bạn để được giải quyết theo cách thủ công.

Ở cấp độ kỹ thuật, hg absorbtìm tất cả các thay đổi chưa được cam kết và cố gắng ánh xạ từng dòng đã thay đổi thành một cam kết trước rõ ràng.
Đối với mọi thay đổi có thể được ánh xạ rõ ràng, các thay đổi chưa được cam kết sẽ được đưa vào cam kết trước thích hợp. Các cam kết bị ảnh hưởng bởi hoạt động sẽ tự động được hoàn lại.
Nếu một thay đổi không thể được ánh xạ tới một cam kết trước rõ ràng, nó sẽ bị bỏ cam kết và người dùng có thể quay trở lại quy trình làm việc hiện có (ví dụ: sử dụng hg histedit).

Logic viết lại tự động của hg absorbđược thực hiện bằng cách theo dõi lịch sử các dòng: Điều này về cơ bản khác với cách tiếp cận được thực hiện bởi hg histedithoặc git rebase, có xu hướng dựa vào các chiến lược hợp nhất dựa trên hợp nhất 3 chiều để tạo ra phiên bản mới của tệp được cung cấp nhiều đầu vào các phiên bản.

Cách tiếp cận này kết hợp với thực tế là hg hấp thụ bỏ qua các thay đổi với một cam kết ứng dụng không rõ ràng có nghĩa là hg hấp thụ sẽ không bao giờ gặp phải xung đột hợp nhất!

Bây giờ, bạn có thể đang nghĩ nếu bạn bỏ qua các dòng có mục tiêu ứng dụng không rõ ràng, bản vá sẽ luôn áp dụng rõ ràng bằng cách sử dụng hợp nhất 3 chiều cổ điển. Tuyên bố này về mặt logic nghe có vẻ đúng. Nhưng nó không phải là: hg absorbcó thể tránh xung đột hợp nhất khi hợp nhất được thực hiện bởi hg histedithoặc git rebase -isẽ không thành công.


0

Tôi nghĩ chistedit(được xây dựng từ Mercurial 2.3) là gần nhất với rebase -iMercurial tinh khiết ( chisteditlà phiên bản tương tác của histedit). Khi trong lịch sử, các foldbản đồ lệnh tới bản đồ của rebase squashrollbản đồ lệnh tới bản đồ của rebase fixup. Xem histedit tài liệu cho biết thêm.

Đây là một ví dụ đơn giản. Giả sử bạn có những thứ sau và muốn chuyển tất cả các thay đổi của 1e21c4b1 vào bản sửa đổi trước đó và chỉ giữ lại thông báo của bản sửa đổi trước.

@  1e21c4b1 drees tip
|  A commit you want to squash
o  b4a738a4 drees
|  A commit
o  788aa028 drees
|  Older stuff

Bạn có thể chạy hg chistedit -r b4a738a4để chỉnh sửa lịch sử trở lại b4a738a4. Trong chistedit, sau đó bạn trỏ chuột xuống 1e21c4b1 và nhấn rđể cho biết bạn muốn cuộn bản sửa đổi đó. Xin lưu ý rằng thứ tự trong lịch sử (cũ nhất đến mới nhất) được đảo ngược từ hg log(mới nhất đến cũ nhất).

#0  pick   160:b4a738a49916   A commit
#1  ^roll  161:1e21c4b1500c

Sau khi chọn các thay đổi của bạn, sau đó bạn chọn ccam kết chúng. Kết quả là như sau:

@ bfa4a3be mẹo drees | A cam kết o 788aa028 drees | Đồ cũ hơn

Nếu bạn chưa quen với chúng, thì đây histeditcó thể là một lựa chọn tốt hơn chisteditvì nó cung cấp các mô tả lệnh trong tệp histedit để tham khảo. Chỉ cần chỉnh sửa thêm một chút để thiết lập các lệnh bằng cách sử dụng chỉnh sửa văn bản thông thường (giống như rebase thông thường).

Lưu ý, để sử dụng histedithoặc chisteditbạn cần thêm histeditvào tiện ích mở rộng trong ~ / .hgrc của mình:

[extensions]
histedit =

Tôi đã đề xuất chisteditvì nó gần giống nhất rebase -ivà hoạt động ở bất kỳ đâu trong lịch sử. Nếu bạn thực sự chỉ muốn đăng ký / chỉnh sửa bản sửa đổi hiện tại thành bản trước đó thì hãy @G. stripĐề xuất của Demecki có thể tốt vì những gì đang xảy ra là rõ ràng. Nó được xây dựng từ Mercuria 2.8. Để có kết quả tương đương như trên bạn có thể làm như sau:

hg strip .
hg add
hg commit --amend

Lưu ý strip, giống như histedit, cần được bật trong ~ / .hgrc của bạn:

[extensions]
strip =

0

Giả sử bạn muốn kết hợp (hợp nhất) 2 lần cam kết gần đây nhất.

  1. Tìm một số sửa đổi

    hg log -G -l 3
    

    đầu ra có thể:

    @  changeset:   156:a922d923cf6f
    |  branch:      default
    |  tag:         tip
    |  user:        naXa!
    |  date:        Thu Dec 13 15:45:58 2018 +0300
    |  summary:     commit message 3
    |
    o  changeset:   155:5feb73422486
    |  branch:      default
    |  user:        naXa!
    |  date:        Thu Dec 13 15:22:15 2018 +0300
    |  summary:     commit message 2
    |
    o  changeset:   154:2e490482bd75
    |  branch:      default
    ~  user:        naXa!
       date:        Thu Dec 13 03:28:27 2018 +0300
       summary:     commit message 1
    
  2. Nhánh thiết lập lại mềm

    hg strip --keep -r 155
    
  3. Cam kết thay đổi một lần nữa

    hg commit -m "new commit message"
    

Ghi chú

stripyêu cầu một tiện ích mở rộng tích hợp để được bật. Tạo / chỉnh sửa ~/.hgrctệp cấu hình với nội dung sau:

[extensions]
strip = 

-1

Tôi sử dụng:

hg phase --draft --force -r 267
...
hg rebase --dest 282 --source 267 --collapse
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.