Làm cách nào để đặt một loạt các thay đổi chưa cam kết sang một bên trong khi làm việc khác


98

Nếu tôi có một loạt các thay đổi chưa cam kết và muốn đặt nó sang một bên trong khi làm việc khác thay vào đó, sau đó (fi sau vài ngày) quay lại với nó và tiếp tục làm việc. Quy trình làm việc dễ dàng nhất để thực hiện điều này là gì? (Cho đến nay tôi chỉ có kinh nghiệm với chức năng cơ bản của Mercurial). Phương pháp thông thường của tôi là tạo một nhánh mới bằng cách sử dụng bản sao, nhưng có thể có nhiều cách tốt hơn.

Câu trả lời:


133

Bạn có một số tùy chọn:

  1. Kệ các mặt hàng. Thao tác này lưu các thay đổi và xóa chúng khỏi thư mục làm việc để chi nhánh có thể tiếp tục. Nó không tạo ra một tập hợp thay đổi.

    hg shelve --all --name "UnfinishedChanges"
    
    hg unshelve --name "UnfinishedChanges"
    

    Cập nhật / Chỉnh sửa : Có thể cần sử dụng phiên bản mới hơn của thương mại

    hg shelve -n "UnfinishedChanges"
    hg unshelve "UnfinishedChanges"
    

    Bạn vẫn có thể sử dụng --namenhư một sự thay thế -n, nhưng có vẻ lanh lợi không còn thích --namenữa. Ngoài ra, điều --allnày không còn bắt buộc và sự lanh lợi trên thực tế sẽ cảm thấy lo lắng về nó.

  2. Vá hàng đợi các mục sử dụng mq. Ở một số khía cạnh, điều này không quá khác biệt với việc xếp xó, nhưng hành xử lại khác. Kết quả cuối cùng là như nhau, các thay đổi được loại bỏ và có thể được tùy chọn áp dụng lại sau đó. Khi được đẩy, các bản vá là tập hợp thay đổi hợp lý, khi được bật lên, chúng sẽ được lưu ở nơi khác và không phải là một phần của lịch sử tập hợp thay đổi.

    hg qnew "UnfinishedWork"
    hg qrefresh
    hg qpop
    
    hg qpush "UnfinishedWork"
    
  3. Cam kết chúng cục bộ, cập nhật lên tập thay đổi trước đó và tiếp tục làm việc và sử dụng các nhánh ẩn danh (hoặc nhiều đầu). Sau đó, nếu bạn muốn thay đổi, bạn có thể hợp nhất các đầu. Nếu bạn không muốn thay đổi, bạn có thể tách tập hợp thay đổi.

    hg commit -m"Commiting unfinished work in-line."
    hg update -r<previous revision>
    
    hg strip -r<revision of temporary commit>
    
  4. Giao họ với một nhánh được đặt tên. Quy trình làm việc sau đó sẽ giống như tùy chọn 3 - hợp nhất hoặc tách khi bạn đã sẵn sàng.

    hg branch "NewBranch"
    hg commit -m"Commiting unfinished work to temporary named branch."
    hg update <previous branch name>
    

Cá nhân tôi sử dụng tùy chọn 3 hoặc 4 vì tôi không ngại loại bỏ các bộ thay đổi hoặc đăng ký một phần mã (miễn là cuối cùng điều đó không bị đẩy). Điều này có thể được sử dụng cùng với nội dung Giai đoạn mới để ẩn tập hợp thay đổi cục bộ của bạn với những người dùng khác nếu cần.

Tôi cũng sử dụng rebaselệnh để di chuyển các tập hợp thay đổi xung quanh để tránh hợp nhất trong đó hợp nhất sẽ không thêm bất kỳ điều gì vào lịch sử của mã. Hợp nhất mà tôi có xu hướng lưu cho hoạt động giữa các nhánh quan trọng (chẳng hạn như các nhánh phát hành) hoặc hoạt động từ một nhánh tính năng tồn tại lâu hơn. Ngoài ra còn có histeditlệnh mà tôi sử dụng để nén các tập hợp thay đổi trong đó "độ chát" của chúng làm giảm giá trị.

Hàng đợi vá lỗi cũng là một cơ chế phổ biến để thực hiện việc này, nhưng chúng có ngữ nghĩa ngăn xếp. Bạn đẩy và bật các bản vá, nhưng một bản vá nằm "bên dưới" một bản vá khác trong ngăn xếp yêu cầu cũng phải đẩy bản vá ở trên cùng của nó.

Cảnh báo , như với tất cả các tùy chọn này, nếu các tệp có nhiều thay đổi hơn kể từ các thay đổi tạm thời mà bạn đã xếp hàng / xếp hàng / phân nhánh, sẽ có độ phân giải hợp nhất được yêu cầu khi hủy xếp / đẩy / hợp nhất.


Cảm ơn vì câu trả lời tuyệt vời và những ví dụ hữu ích. Bạn có tình cờ biết nếu sử dụng dấu trang hg cũng là một lựa chọn không?
Erik

@Erik Có thể, nhưng tôi không có kinh nghiệm sử dụng nó.
Adam Houldsworth

2
dấu trang có thể được sử dụng để trợ giúp với tùy chọn 3 - bạn có thể sử dụng một dấu trang để gắn nhãn bản sửa đổi mà bạn đã tạo để lưu trữ thay đổi của mình. Họ không thể tự mình làm nhiệm vụ.
Steve Kaye

tùy chọn --allkhông được công nhận. đó là một hành vi mặc định để tạm dừng tất cả các thay đổi.
naXa

@naXa Chào bạn, nếu một trong các lệnh của tôi hơi sai sót (có thể do phiên bản đã thay đổi), vui lòng chỉnh sửa câu trả lời và tôi sẽ chấp thuận nếu cần :-)
Adam Houldsworth 12/1218

23

Cá nhân tôi không thích bất kỳ câu trả lời nào được đăng cho đến nay:

  1. Tôi không thích phân nhánh nhân bản vì tôi thích mỗi dự án chỉ có một thư mục. Làm việc trên các thư mục khác nhau cùng lúc hoàn toàn làm xáo trộn lịch sử của các tệp gần đây của các biên tập viên của tôi. Tôi luôn luôn kết thúc việc thay đổi tệp sai. Vì vậy, tôi không làm như vậy nữa.
  2. Tôi sử dụng shelveđể sửa lỗi nhanh chóng (chỉ để chuyển các thay đổi không giới hạn của tôi sang một nhánh khác, nếu tôi nhận ra mình đang sai). Bạn đang nói về những ngày, không đời nào tôi bỏ qua vài ngày.
  3. Tôi nghĩ mqlà quá phức tạp đối với một tình huống bình thường như vậy

Tôi nghĩ rằng cách tốt nhất là chỉ cần thực hiện các thay đổi của bạn, thay vì bạn quay lại tập hợp các thay đổi trước khi bắt đầu các thay đổi này và làm việc từ đó. Có một số vấn đề nhỏ, hãy để tôi minh họa:

Giả sử bạn có bộ thay đổi A. Hơn là bạn bắt đầu các thay đổi của mình. Tại thời điểm này, bạn muốn đặt nó sang một bên. Trước hết, hãy cam kết công việc của bạn:

hg ci -m "Working on new stuff"

Nếu muốn, bạn có thể thêm dấu trang để quay lại sau dễ dàng hơn. Tôi luôn tạo dấu trang cho các nhánh ẩn danh của mình.

hg bookmark new-stuff

Quay lại tập hợp các thay đổi trước các sửa đổi này

hg update A

Từ đây, bạn làm việc và tạo tập thay đổi C. Bây giờ bạn có 2 đầu (B và C), bạn sẽ được cảnh báo khi cố gắng đẩy. Bạn chỉ có thể đẩy một nhánh bằng cách chỉ định người đứng đầu của nhánh đó:

hg push -r C

Hoặc bạn có thể thay đổi giai đoạn của new-stuffnhánh thành bí mật. Các bộ thay đổi bí mật sẽ không được đẩy.

hg phase -r new-stuff --secret --force

Cảm ơn các câu trả lời chi tiết! Tôi thực sự thích đọc quy trình làm việc của mọi người cho những vấn đề (thông thường?).
Erik

Tôi nghĩ rằng mqlà một chút quá phức tạp cho chỉ tình trạng này, nhưng nó có một phạm vi đủ rộng về mục đích sử dụng, trong đó có một này, rằng nó giá trị trong khi đầu tư thời gian để thành thạo với nó.
Norman Grey

12

Để giữ các thay đổi cục bộ không giới hạn, cách dễ nhất đối với tôi là lưu chúng dưới dạng tệp vá.

hg diff > /tmp/`hg id -i`.patch

và khi bạn cần trở lại trạng thái trước đó:

hg up <REV_WHERE_SAVED>
hg patch --no-commit /tmp/<REV_WHERE_SAVED>.patch

Tôi sẽ gỡ bỏ /tmphg id -inó cũng sẽ hoạt động trên Windoze.
anatoly techtonik

hg upkhông cần thiết ở đó.
anatoly techtonik

1
@techtonik Điều gì sẽ xảy ra nếu tôi áp dụng bản vá trên một bản sửa đổi khác? Đặc biệt là nếu các tập tin vá được sửa đổi.
mapcuk

Mercurial sẽ cố gắng hợp nhất nó, và dù sao thì bạn cũng sẽ phải giải quyết xung đột.
anatoly techtonik

6

Bạn chỉ có thể sao chép repo của mình nhiều lần. Tôi có xu hướng có một bản sao gốc, sau đó nhiều con từ đó. Thí dụ:

  • MyProject.Root
  • MyProject.BugFix1
  • MyProject.BugFix2
  • MyProject.FeatureChange1
  • MyProject.FeatureChange2

4 con đều được nhân bản từ gốc và đẩy / kéo đến / từ gốc. Sau đó root sẽ push / pull từ master repo trên mạng / internet ở đâu đó. Gốc hoạt động như một loại khu vực dàn dựng cá nhân của bạn.

Vì vậy, trong trường hợp của bạn, bạn chỉ cần sao chép một repo mới và bắt đầu hoạt động. Để công việc 'được xếp lại' của bạn một mình trong repo khác. Nó đơn giản mà.

Nhược điểm duy nhất là sử dụng dung lượng ổ đĩa, nhưng nếu đó là mối quan tâm, bạn sẽ không sử dụng DVCS chút nào;) Ồ và nó thực sự gây ô nhiễm danh sách "các dự án gần đây" của Visual Studio, nhưng này.

[Chỉnh sửa các nhận xét sau]: -

Để kết luận thì ... những gì bạn đang làm là hoàn toàn tốt đẹp và bình thường. Tôi cho rằng đó là cách tốt nhất có thể để hoạt động khi những điều sau là đúng: 1) nó tồn tại trong thời gian ngắn 2) bạn không cần cộng tác với các nhà phát triển khác 3) những thay đổi không cần phải rời khỏi PC của bạn cho đến khi cam kết / thời gian đẩy.


Bất kỳ lý do gì để không sử dụng các chi nhánh? Đây là công dụng của chúng và nhanh hơn đáng kể so với sao chép lại.
Adam Houldsworth

Trong câu hỏi của mình, tôi đã nêu như sau: Phương pháp thông thường của tôi là tạo một nhánh mới bằng cách sử dụng bản sao, nhưng có thể có nhiều cách tốt hơn.
Erik

1
@AdamHouldsworth, về mặt kỹ thuật thì đây là những nhánh ... chỉ là những nhánh tồn tại trong thời gian ngắn. Tạo ra một chi nhánh được đặt tên cho một tác phẩm ngắn hạn là hoàn toàn ngu ngốc. Nó lạm dụng mục đích được đặt tên là các nhánh dành cho những câu chuyện lâu dài về công việc.
nbevans

@NathanE Nếu bạn cho rằng các nhánh được đặt tên cho công việc ngắn hạn là "hoàn toàn ngu ngốc", thì cũng có nhánh ẩn danh, giá đỡ hoặc hàng đợi vá lỗi như các tùy chọn nhẹ khác. Nhân bản lại, theo ý kiến ​​của tôi, cũng ngu ngốc không kém khi đối mặt với các lựa chọn khác - đó là một lợi ích tiềm năng là có hai bộ mã mở trong hai trường hợp VS, nhưng tôi hiếm khi phải làm điều này vì vậy sử dụng nhân bản như một điều tất nhiên. không phục vụ tôi. Chỉ để làm rõ, tôi không phải là người tán thành.
Adam Houldsworth

@NathanE Họ cũng không dành riêng cho "những câu chuyện dài hơi trong công việc", đó chỉ là thứ họ giỏi nếu bạn theo dõi tích hợp liên tục. Từ các tài liệu : "Các nhánh xảy ra nếu các đường phát triển phân kỳ", nếu bạn đang gác một hạng mục công việc để làm việc khác, điều này đối với tôi nghe có vẻ giống như sự phân kỳ, bất kể nó tồn tại bao lâu.
Adam Houldsworth
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.