Từ bỏ thay đổi mà không xóa khỏi lịch sử


180

Có một cam kết là không hoạt động, vì vậy tôi muốn từ bỏ nó mà không xóa nó khỏi lịch sử .

Tôi đã cập nhật từ một sửa đổi trước đó và cam kết, do đó tạo ra một cái đầu mới.


Tôi không có chi nhánh, tôi không muốn chi nhánh, tôi chỉ muốn tiếp tục với cái đầu mới chính xác, không có gì lạ mắt, không hợp nhất, không phải lo lắng, cứ quên đi cái trước đó.

Tôi dường như không thể tìm ra cách để làm điều đó và tôi bắt đầu tin rằng nó không thể được thực hiện. Tất cả những gì tôi tìm thấy là những thứ về các chi nhánh, hoặc những thứ về việc hợp nhất.


1
Nó nằm trong repo của bạn, vì vậy nó chưa bị xóa khỏi lịch sử. Bạn đã tạo một cái đầu mới, vì vậy bạn có thể tiếp tục chỉnh sửa mà không nhầm lẫn. Điều gì đang ngăn cản bạn tiếp tục với cái đầu mới?
ataylor

Điều gì với ác cảm của bạn với các chi nhánh?
Andres Jaan Tack

@Andres Nó không thực sự ác cảm với các chi nhánh. Tôi chỉ cần nó hoạt động mà không cần thêm một bước ngu ngốc để tạo một cái chỉ để đóng nó.
o0 '.

Bất cứ ai đọc - xin lưu ý rằng một nhánh đã được tạo trong kịch bản này; lưu ý lời giải thích được đưa ra trong câu trả lời này: stackoverflow.com/a/3692607/3195477
UuDdLrLrSs

Câu trả lời:


181

Cập nhật kho lưu trữ của bạn lên phần đầu với bản sửa đổi mà bạn muốn quên đi, sau đó sử dụng hg commit --close-branchđể đánh dấu nhánh (ẩn danh) đó là đóng. Sau đó cập nhật để người đứng đầu chi nhánh mà bạn làm muốn, và tiếp tục làm việc.

Bạn vẫn có thể thấy nhánh đóng nếu bạn sử dụng -ctùy chọn này hg heads, nhưng nó sẽ không hiển thị theo mặc định và hg mergesẽ biết không cố gắng hợp nhất với đầu đóng.

Bạn sẽ cần sử dụng hg push --forcelần đầu tiên khi bạn đẩy đầu đóng này sang kho lưu trữ khác vì bạn thực sự tạo ra các đầu bổ sung trong kho lưu trữ từ xa khi bạn đẩy. Vì vậy, nói với Mercurial rằng điều này là ổn với --force. Những người kéo đầu kín sẽ không bị làm phiền bởi bất kỳ cảnh báo nào.


3
@Niall C. sẽ không hoạt động nếu anh ấy đã đánh dấu đó là một chi nhánh có tên? Tôi giả sử từ những gì anh ta nói rằng anh ta đã làm điều đó theo mặc định
msarchet

nhưng ... điều đó không đúng, tôi vẫn nhận được cả hai đầu được liệt kê khi tôi gọi hg heads... Tôi đang sử dụng 1.4.3 đồng bóng, đó có phải là một tính năng mới hơn không?
o0 '.

2
@msarchet: AFAIK, dùng thử ngay hôm nay, - chi nhánh đóng cửa KHÔNG hoạt động cho các chi nhánh ẩn danh. Nó nên, nhưng không. Tôi hy vọng điều này sẽ thay đổi trong một số phiên bản tương lai của Mercurial. Các nhánh ẩn danh rất đẹp, nhưng nên là lớp đầu tiên như các nhánh được đặt tên.
Krazy Glew

4
@KrazyGlew: Vấn đề là một nhánh "ẩn danh" thực sự chỉ là một nhánh thứ hai có cùng tên với nhánh mà nó được dựa trên. Bạn không thực sự cố gắng đóng chi nhánh (được đặt tên): bạn đang cố gắng loại bỏ những thay đổi bạn đang thực hiện. Nói cách khác, hg branchesvẫn nên hiển thị tên chi nhánh bạn đang bật. Thay vì cố gắng đóng chi nhánh, hãy hợp nhất chi nhánh ẩn danh của bạn trở lại chi nhánh ban đầu, loại bỏ tất cả các thay đổi.
StriplingWar Warrior

2
Trong trường hợp của tôi, tôi có một nhánh được gọi là default (đây là tiêu chuẩn) và một nhánh khác được gọi là default / master (tôi nghĩ do thực tế là kho từ xa thực sự là git). hg cập nhật mặc định / chính chủ; hg cam kết - chi nhánh; hg cập nhật mặc định làm việc cho tôi.
MattD

68

Tôi biết bạn không muốn làm việc với các chi nhánh trong giai đoạn này, nhưng đó chính xác là những gì bạn đã làm. Khi bạn quay lại phiên bản trước đó và cam kết một cái gì đó hoạt động, bạn đã tạo một nhánh - một nhánh không tên, nhưng một nhánh đều giống nhau.


Không có vấn đề gì khi chỉ tiếp tục như bạn và không lo lắng về việc có nhiều đầu, nhưng nếu bạn muốn dọn dẹp mọi thứ để bạn không vô tình chọn nhầm đầu một lần thì bạn có thể giết chết nhánh cũ.

Có một phần hay trong tài liệu Mercurial đưa bạn qua một số tùy chọn xung quanh Chi nhánh chết cắt tỉa .

Tôi nghĩ rằng lựa chọn tốt nhất cho bạn là đánh dấu chi nhánh cũ là "đóng cửa". Nếu đầu cũ của bạn là phiên bản "123" thì:

hg update -r 123
hg commit --close-branch -m 'Closing old branch'
hg update -C default

3
Blurgh - chỉ thấy câu trả lời của @ Niall sau khi tôi bước vào. Will upvote của Niall và tôi có thể mòn mỏi trong nhóm điểm không. :)
Nick Pierpoint

1
Tôi thích câu trả lời của bạn tốt hơn, nó yêu cầu ít tìm hiểu về thuật ngữ của thương nhân (mà gần như tôi có thể nói dường như được chọn để gây nhầm lẫn cho người dùng git)
tacaswell

8
lol thì ngược lại! Thuật ngữ của mercurial đã được chọn để nghe có vẻ tự nhiên đối với người dùng svn, trong khi thuật ngữ của git khó hiểu như địa ngục! Dù sao, nâng cao câu trả lời này vì nó bao gồm bản cập nhật cuối cùng -C
Tobia

2
Tại sao bạn cần -Ctrong hg update? Dường như không có tập tin nào được sửa đổi, vì vậy nó sẽ hoạt động mà không có nó.
tối đa

1
theo như tôi có thể nói, bạn không cần -C ở bất cứ đâu. tuy nhiên, nếu bạn có những thay đổi nổi bật khi bạn cố gắng cập nhật, bạn sẽ hủy bỏ.
Eli Albert

21

Trước hết, gõ:

hg heads

Hãy tưởng tượng, bạn có ba cái đầu được liệt kê:

changeset:   223:d1c3deae6297
user:        Your name  <your@email.com>
date:        Mon Jun 09 02:24:23 2014 +0200
summary:     commit description #3

changeset:   123:91c5402959z3
user:        Your name <your@email.com>
date:        Sat Dec 23 16:05:38 2013 +0200
summary:     commit description #2

changeset:   59:81b9804156a8
user:        Your name <your@email.com>
date:        Sat Sep 14 13:14:40 2013 +0200
summary:     commit description #1

Giả sử, bạn muốn giữ cho đầu cuối hoạt động (223) và đóng phần còn lại.

Sau đó, bạn sẽ làm như sau:

Đóng đầu # 59

hg up -r 59
hg ci --close-branch -m "clean up heads; approach abandoned"

Đóng đầu # 123

hg up -r 123
hg ci --close-branch -m "clean up heads; approach abandoned"

Cam kết thay đổi

hg push

Đừng quên chuyển sang đầu bên phải ở cuối

hg up -r 223

Và bạn đã hoàn thành.


Đây là một hướng dẫn tốt, nhưng các thông điệp cam kết ví dụ là một chút meta. Tôi sẽ bao gồm các ví dụ tốt hơn để những người học hỏi từ bạn có thể cung cấp các thông điệp cam kết tốt hơn. Một cái gì đó như --close-branch -m "Closing branch - technique #2 abandoned in favor of technique #3".
Jason R. Coombs

5
Ngoài ra, bạn đã hoàn thành công việc cuối cùng, ngoại trừ bản sao làm việc của bạn vẫn ở trên đầu mà bạn vừa đóng. Cam kết một thay đổi khác sẽ xảy ra trên đầu đóng cửa, mở lại nó. Bạn sẽ muốn hg up -r 223trước khi thực hiện bất kỳ thay đổi.
Jason R. Coombs

@Jason R. Coombs: Phải!
Artur Barseghyan

theo @Niall, và kinh nghiệm của riêng tôi vừa rồi, bạn sẽ cần hg push --force, không chỉ hg pushđể vượt qua cảnh báo về việc đẩy nhiều đầu.
craq

1
@Artur Tôi đồng ý nói chung. Trong trường hợp này, hg pushbản thân nó đã không làm việc cho tôi. Làm thế nào để bạn đề nghị đẩy các thay đổi sang một repo bên ngoài nếu nó từ chối vì nhiều đầu?
craq

12

Bạn muốn sử dụng hg backout. Điều này loại bỏ những thay đổi được thực hiện bởi bộ thay đổi từ bất kỳ bộ thay đổi con nào.

Kiểm tra này ra cho một lời giải thích tốt. Sao lưu Mercurial


2
Đây chính xác là câu trả lời đúng. Backout thêm nghịch đảo của một bộ thay đổi, hoàn tác công việc và cung cấp cho bạn một thông điệp cam kết để nhắc nhở bản thân tại sao bạn không thích ý tưởng đó.
Ry4an Brase

7
Tôi thực sự không đồng ý - từ bỏ công việc trên một đầu và bắt đầu lại từ một điểm khởi đầu tốt có vẻ như là một mô hình công việc sạch hơn là sử dụng backouts. Đặc biệt là vì bạn không thể sao lưu nhiều hơn một thay đổi cùng một lúc.
Martin Geisler

1
@Martin Geisler, tôi đồng ý với điều này nói chung, nhưng OP nói rằng anh ấy muốn từ bỏ các thay đổi mà không có chi nhánh
msarchet

2
@Martin Geisler yea Tôi là tất cả để phân nhánh đôi khi chỉ cần thay đổi xấu là tốt nhất
msarchet

1
đôi khi nó có thể hữu ích, nhưng đó không thực sự là điều tôi muốn. Dù sao cũng cảm ơn :)
o0 '.

2

Cả hai câu trả lời của Niall và Nick đều được đưa ra. Bởi vì tôi thấy mình tạo ra rất nhiều cái đầu lơ lửng, cuối cùng tôi đã viết một bí danh để đóng những cái đầu dễ dàng hơn. Bằng cách thêm phần này vào .hgrc:

[alias]
behead = !REV=$($HG id -i); $HG update $@ -q && $HG ci --close-branch -m "Closing dead head" && $HG update $REV -q

(nếu bạn đã có một [alias]phần, thay vào đó bạn có thể thêm vào phần đó)

Bây giờ bạn có thể đóng một đầu trong một lệnh đơn (và không phải cập nhật lên một bộ thay đổi khác theo cách thủ công) như thế này:

$ hg behead 123

Lưu ý: bí danh lợi dụng thực tế là các bí danh Mercurial có thể là các lệnh shell . Điều này có nghĩa là điều này có thể sẽ chỉ hoạt động trên UNIX, không phải trên Windows.


2

Một cách khác để đóng hoặc tước nhánh không mong muốn sẽ là hợp nhất nó theo cách hoàn toàn loại bỏ các hiệu ứng của nó, nhưng để lại nó trong lịch sử. Cách tiếp cận này sẽ cho phép những thay đổi không mong muốn đó lan truyền trong một lần đẩy - vì vậy chỉ sử dụng điều này nếu đó là hiệu quả dự định.

Hãy nói rằng lịch sử thay đổi trông như thế này:

1-2-3-4-5-6    
       \    
        7-8-*

và nó là 56không còn muốn nữa.

Bạn có thể làm được việc này:

hg up 8
hg merge -r 6 -t :local
hg commit ...

Điều này sẽ tạo ra điều này:

1-2-3-4-5-6    
       \   \
        7-8-9-*

Bản cập nhật để 8đảm bảo bạn đang làm việc ở phần đầu mong muốn trong lịch sử mà bạn muốn giữ.

Các -t :localchỉ thị HG sử dụng merge "công cụ" gọi địa phương mà nói với nó để bỏ qua những thay đổi từ chi nhánh khác, ví dụ, là KHÔNG thể hiện bằng trạng thái thư mục làm việc hiện tại. Thêm thông tin .

Do đó, những thay đổi không mong muốn trong 56được bảo tồn trong lịch sử nhưng không ảnh hưởng đến bất kỳ điều gì gần đây hơn.


2

Đây là trường hợp sử dụng cho phần mở rộng Evolve . Hiện tại nó không được đóng gói với Mercurial, vì vậy về mặt kỹ thuật, đây là phần mở rộng của bên thứ ba. Nhưng nó được sử dụng khá nhiều bởi một nhóm người, bao gồm cả các nhà phát triển Mercurial, đang được phát triển rất tích cực và không đi đến đâu cả.

Với tiện ích mở rộng Evolve, bạn chỉ cần làm

hg prune -r revname

và tiếp tục cuộc sống của bạn. Các cset vẫn sẽ ở đó, nhưng đã lỗi thời. Nó sẽ không hiển thị trừ khi bạn chuyển --hiddentùy chọn cho các lệnh Mercurial và theo mặc định sẽ không được đẩy vào kho lưu trữ từ xa. Mặc dù tôi nghĩ bạn có thể ép buộc nếu bạn thực sự muốn.

Nếu cset bạn đang cắt tỉa có tổ tiên bạn muốn giữ, thì bạn sẽ phải chạy hg evolveđể chống lại những thay đổi đó. hg evolvesẽ làm như vậy tự động. Nếu không, bạn không phải làm bất cứ điều gì.


1

Bạn có thể sao chép repo bị hỏng của bạn sang một cái mới mà không nhân bản cái đầu không mong muốn đó. Sau đó xóa kho lưu trữ cũ, di chuyển bản sao mới được tạo vào vị trí ban đầu và tiếp tục làm việc với nó. Điều này sẽ mất một chút thời gian, nhưng bạn sẽ có được một kho lưu trữ hoàn toàn sạch mà không có dấu hiệu sửa đổi không mong muốn đó.

hg clone --rev myGoodResition myDirtyRepo myCleanRepo

1
Đây là hoàn toàn không phải những gì tôi yêu cầu, xin lỗi.
o0 '.

4
@Kristof: đó là một trò đùa? Đọc lại dòng đầu tiên của bài viết của tôi: "từ bỏ nó mà không xóa nó khỏi lịch sử "
o0 '.

-1

Tôi đã gặp phải vấn đề này nhiều lần khi tôi muốn chặt đầu một người bị lỗi. Tôi luôn muốn thấy nó biến mất khỏi mặt Trái đất.

Trên bản sao địa phương của bạn, nhận bản mới nhất và sau đó:

  1. Tìm phần đầu của một cái đầu bạn muốn lột (nơi một cái cổ mới bắt đầu rẽ nhánh), lấy số sửa đổi

  2. Dải nó.


Nguồn: TipsAndTricks .

Nguồn: PruningDeadBranches # Sử dụng_strip .

hg --config extensions.hgext.mq= strip -n <rev>
  1. Thực hiện cập nhật tệp tầm thường (thêm khoảng trắng vào tệp), cam kết và đẩy.

Repo của bạn bây giờ nên có đầu bị tước. Bước cuối cùng rất quan trọng vì tước không tạo ra bất kỳ thay đổi nào bạn có thể đẩy vào kho lưu trữ trung tâm của mình. Nếu không có bước cuối cùng, bạn chỉ có thể lột đầu cục bộ.


1
Nhưng, đẩy không bao giờ xóa bất cứ điều gì từ kho lưu trữ từ xa. Nó chỉ bao giờ thêm thông tin. Nếu bộ thay đổi đã có trên kho lưu trữ trung tâm, bạn cần phải sử dụng tiện ích mở rộng tiến hóa hoặc bằng cách nào đó tước nó trên máy chủ trung tâm. Nếu bộ thay đổi chưa có trên kho lưu trữ trung tâm, thì việc tước nó cục bộ sẽ đủ mà không cần bất kỳ sự thúc đẩy nào.
Ben
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.