Tại sao git hoàn nguyên phàn nàn về tùy chọn -m bị thiếu?


183

Vì vậy, tôi đang làm việc trên một dự án với những người khác và có nhiều dĩa github đang được thực hiện. Ai đó vừa sửa lỗi và tôi đã hợp nhất với ngã ba của anh ta, nhưng sau đó tôi nhận ra rằng tôi có thể tìm ra giải pháp tốt hơn. Tôi muốn hoàn nguyên các cam kết tôi vừa thực hiện. Tôi đã thử làm điều này với git revert HEADnhưng nó đã cho tôi lỗi này:

gây tử vong: Cam kết <SHA1> là hợp nhất nhưng không có tùy chọn -m nào được đưa ra.

Điều đó nghĩa là gì? Khi tôi hợp nhất và cam kết, tôi đã sử dụng tùy chọn -m để nói "Đã hợp nhất với <tên người dùng>".

Tôi làm gì sai ở đây?

Câu trả lời:


215

Theo mặc định, git reverttừ chối hoàn nguyên một cam kết hợp nhất vì điều đó thực sự có nghĩa là mơ hồ. Tôi đoán rằng HEADtrên thực tế bạn là một cam kết hợp nhất.

Nếu bạn muốn hoàn nguyên cam kết hợp nhất, bạn phải chỉ định cha mẹ của hợp nhất mà bạn muốn coi là thân chính, tức là những gì bạn muốn hoàn nguyên.

Thường thì đây sẽ là cha mẹ số một, ví dụ nếu bạn đã mastervà đang làm git merge unwantedvà sau đó quyết định hoàn nguyên việc hợp nhất unwanted. Cha mẹ đầu tiên sẽ là masternhánh hợp nhất trước của bạn và cha mẹ thứ hai sẽ là tiền boa của unwanted.

Trong trường hợp này bạn có thể làm:

git revert -m 1 HEAD

4
Được rồi cảm ơn. Tôi thấy dễ dàng hơn khi chỉ thay đổi hai tệp bị ảnh hưởng bởi sự hợp nhất và sau đó cũng cam kết một số thay đổi khác của tôi.
icnhzabot

42
Tôi có thể tìm thông tin ở đâu cho dù tôi phải sử dụng -m1 hay -m2, ...?
Patrick Cornelissen

34
git cat-file -p [MERGE_COMMIT_ID]sẽ hiển thị các nhánh cha theo thứ tự. Cái đầu tiên được liệt kê sẽ là -m 1cái thứ hai -m 2.
lỗ mũi

2
git revert [HASH] -m 2đang nói với tôi Trên nhánh 1.x-1.x không có gì để cam kết, thư mục làm việc sạch sẽ nhưng cam kết của tôi không được hoàn nguyên.
jenlampton

3
Vì vậy, nếu tôi cần hoàn nguyên lại 10 lần hợp nhất (điều này hoàn toàn có khả năng vì git thực hiện hợp nhất tự động mỗi khi tôi thay đổi từ nhà phát triển khác) tôi có phải thực hiện việc này cho mỗi lần hợp nhất không? Đây có phải là lý do tại sao người hâm mộ git rất quan tâm đến việc nổi loạn, bởi vì hoàn nguyên về cơ bản là vô dụng?
Neutrino

45

Giả sử anh chàng kia đã tạo thanh trên đầu foo, nhưng bạn đã tạo baz trong khi đó và sau đó hợp nhất, đưa ra một lịch sử về

$ git lola
* 2582152 (TRỤ, chủ) Hợp nhất chi nhánh 'otherguy'
|  
| * c7256de (otherguy)
* | b7e7176
| /  
* 9968f79 foo

Lưu ý: git lola là một bí danh không chuẩn nhưng hữu ích.

Không có xúc xắc với git revert:

$ git hoàn nguyên
gây tử vong: Cam kết 2582152 ... là một sự hợp nhất nhưng không có tùy chọn -m nào được đưa ra.

Charles Bailey đã đưa ra một câu trả lời xuất sắc như thường lệ. Sử dụng git revertnhư trong

$ git Revert --no-edit -m 1 ĐẦU
[master e900aad] Hoàn nguyên "Hợp nhất chi nhánh 'otherguy'"
 0 tệp đã thay đổi, 0 phần chèn (+), 0 phần xóa (-)
 xóa chế độ 100644 bar

có hiệu quả xóa barvà tạo ra một lịch sử của

$ git lola
* e900aad (CHÍNH, chủ) Hoàn nguyên "Hợp nhất chi nhánh 'otherguy'"
* 2582152 Hợp nhất chi nhánh 'otherguy'
|  
| * c7256de (otherguy)
* | b7e7176
| /  
* 9968f79 foo

Nhưng tôi nghi ngờ bạn muốn vứt bỏ cam kết hợp nhất:

$ git đặt lại - đầu trang ^
Hiện tại đang ở b7e7176 baz

$ git lola
* b7e7176 (TRỤ, chủ)
| * c7256de (otherguy)
| /  
* 9968f79 foo

Như tài liệu git rev-parsehướng dẫn

<rev>^, ví dụ: ĐẦU ^,v1.5.1^0
Hậu tố ^cho tham số sửa đổi có nghĩa là cha mẹ đầu tiên của đối tượng cam kết đó. ^<n>có nghĩa là cha mẹ thứ n ( nghĩa <rev>^ là tương đương với <rev>^1). Như một quy tắc đặc biệt, <rev>^0có nghĩa là bản thân cam kết và được sử dụng khi <rev>là tên đối tượng của đối tượng thẻ tham chiếu đến đối tượng cam kết.

vì vậy trước khi gọi git reset, HEAD^(hoặc HEAD^1) là b7e7176 và HEAD^2là c7256de, tức là , tương ứng là cha mẹ thứ nhất và thứ hai của cam kết hợp nhất.

Hãy cẩn thận với git reset --hardvì nó có thể phá hủy công việc.


3
Đó là một thế giới hỗn hợp, lộn xộn, rung chuyển. Ngoại trừ Lola. Cảm ơn một triệu cho bí danh tuyệt vời này.
Barney

Cách dễ dàng để thêm lolavào lệnh git của bạn:git config --global alias.lola "log --graph --decorate --pretty=oneline --abbrev-commit --all"
D. Gibbs

8

Tôi đã có vấn đề này, giải pháp là nhìn vào biểu đồ cam kết (sử dụng gitk) và thấy rằng tôi có những điều sau đây:

*   commit I want to cherry-pick (x)
|\  
| * branch I want to cherry-pick to (y)
* | 
|/  
* common parent (x)

Bây giờ tôi hiểu rằng tôi muốn làm

git cherry-pick -m 2 mycommitsha

Điều này là do -m 1sẽ hợp nhất dựa trên cha mẹ chung, nơi -m 2hợp nhất dựa trên nhánh y, đó là thứ tôi muốn chọn.


1
Có thể bởi vì nó không liên quan đến git-revert, đó là những gì câu hỏi này là về.
pnomolos

1
Tôi nghĩ rằng câu hỏi này là về -mtùy chọn, không chỉ riêng về git merge. Tức là, lý do đằng sau việc sử dụng -mtùy chọn này có vẻ giống nhau đối với hoàn nguyên và cherry-picks. Nếu điều đó không đúng, xin vui lòng cho chúng tôi biết. Vì tôi không tìm thấy bất kỳ câu hỏi nào khác giải quyết cụ thể việc sử dụng cherry-pick của nó, cảm ơn vì câu trả lời này, có lẽ đã dẫn google để giúp tôi tìm câu hỏi này và thảo luận hữu ích, có liên quan!
nealmcb
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.