Câu hỏi Tôi chạy vào một cuộc xung đột hợp nhất. Làm thế nào tôi có thể hủy hợp nhất?


Tôi đã sử dụng git pull và có xung đột hợp nhất:

unmerged:   _widget.html.erb

You are in the middle of a conflicted merge.

Tôi biết rằng các phiên bản khác của tập tin là tốt và rằng tôi là xấu vì vậy tất cả các thay đổi của tôi nên bị bỏ rơi. Tôi có thể làm cái này như thế nào?


1913
2017-09-19 13:21


gốc


Tôi nhận ra đây là một câu hỏi rất cũ, nhưng bạn có muốn hủy bỏ toàn thể hợp nhất và rời khỏi nhánh bạn đã hợp nhất chưa được nhúng hoặc chỉ bỏ qua một tệp này như một phần của hợp nhất lớn hơn, cho phép tất cả các tệp khác hợp nhất như bình thường? Đối với tôi, tựa đề của bạn ám chỉ cái cũ, cơ thể câu hỏi của bạn muốn cái sau. Các câu trả lời làm cả hai, mà không làm cho mọi thứ rõ ràng. - rjmunro
Tôi nhận được trường hợp tương tự trên cam kết nói rằng hợp nhất tự động không thành công; khắc phục xung đột và sau đó cam kết kết quả: [rejected] gh-pages -> gh-pages (non-fast-forward) - Chetabahana
Gwyn, có thể hữu ích khi chọn một câu trả lời được chấp nhận ở đây. Người bình chọn hàng đầu ít an toàn hơn một số giải pháp cập nhật hơn, vì vậy tôi nghĩ nó sẽ giúp làm nổi bật những người khác trên nó :) - Amicable


Các câu trả lời:


Vì bạn pull đã không thành công HEAD (không phải HEAD^) là lần commit "hợp lệ" cuối cùng trên nhánh của bạn:

git reset --hard HEAD

Phần khác bạn muốn là để cho những thay đổi của họ vượt qua những thay đổi của bạn.

Các phiên bản cũ hơn của git cho phép bạn sử dụng chiến lược hợp nhất "của họ":

git pull --strategy=theirs remote_branch

Nhưng điều này đã được gỡ bỏ, như đã giải thích trong thông điệp này của Junio ​​Hamano (người bảo trì Git). Như đã nói trong liên kết, thay vào đó bạn sẽ làm điều này:

git fetch origin
git reset --hard origin

1731
2017-09-19 14:33



Thay vì thực hiện khôi phục cài đặt gốc, bạn có thể mang lại mức chi tiết hơn bằng cách thực hiện: git fetch origin  -> git reset origin (soft reset, your changes are still present)  -> git checkout file_to_use_their_version_of another_file (steamroll your own changes back to match the origin)    Tôi không bao giờ sử dụng git kéo nữa. Vì trong cuộc chiến giữa mã mới nhất của tôi và nguồn gốc, nguồn gốc luôn luôn nên giành chiến thắng, tôi luôn git fetch và git rebase origin. Điều này thực sự làm cho sự hợp nhất của tôi và xung đột ít và xa. - Kzqai
Tôi đồng ý. Tôi cũng muốn tìm nạp trước, và sau đó kiểm tra các thay đổi ngược dòng (git log ..@{upstream} hoặc là git diff ..@{upstream}). Sau đó, giống như bạn, tôi sẽ rebase công việc của tôi. - Pat Notz
Như đã lưu ý trong câu trả lời gần đây hơn, kể từ phiên bản 1.6.1, bạn có thể sử dụng 'git reset --merge' - Matt Ball
Tôi đã sử dụng git merge -X theirs remote_branch thay vì git pull --strategy=theirs remote_branch như theirs trông giống như một lựa chọn recursive - mlt
Không có chiến lược theirs. - srcspider


Nếu phiên bản git của bạn là> = 1.6.1, bạn có thể sử dụng git reset --merge.

Ngoài ra, như @Michael Johnson đề cập, nếu phiên bản git của bạn là> = 1.7.4, bạn cũng có thể sử dụng git merge --abort.

Như mọi khi, hãy đảm bảo bạn không có thay đổi không được cam kết trước khi bạn bắt đầu hợp nhất.

Từ git merge man page

git merge --abort tương đương với git reset --merge khi nào MERGE_HEAD là món quà.

MERGE_HEAD có mặt khi hợp nhất đang được tiến hành.

Ngoài ra, về các thay đổi không được cam kết khi bắt đầu hợp nhất:

Nếu bạn có thay đổi bạn không muốn cam kết trước khi bắt đầu hợp nhất, chỉ cần git stash trước khi hợp nhất và git stash pop sau khi kết thúc hợp nhất hoặc hủy bỏ nó.


1592
2018-03-28 23:16



Thú vị - nhưng hướng dẫn sử dụng làm tôi sợ. Khi nào chính xác là nó thích hợp để sử dụng? Khi nào bạn phải chỉ định tùy chọn <commit>? #GitMoment: -o - conny
Bạn thường sử dụng điều này khi bạn muốn làm lại hợp nhất từ ​​đầu. Tôi chưa bao giờ phải chỉ định cam kết tùy chọn, vì vậy mặc định (không có tùy chọn <commit>) là tốt. - Carl
Tôi muốn câu trả lời này có nhiều phiếu bầu hơn! Tại thời điểm này, nó có vẻ như là giải pháp có liên quan nhất trong nhiều trường hợp. - Jay Taylor
Vì git v1.7.4 git merge --abort cũng hoạt động. - Michael Johnson
Ngay cả với những thay đổi không được sửa đổi, git có thể khôi phục trạng thái trước khi hợp nhất. Tốt đẹp! - T3rm1


git merge --abort

Hủy bỏ quy trình giải quyết xung đột hiện tại và cố gắng tái tạo lại   trạng thái hợp nhất trước.

Nếu có những thay đổi về worktree không cam kết hiện diện khi hợp nhất   bắt đầu, git merge --abort trong một số trường hợp sẽ không thể   tái tạo lại những thay đổi này. Do đó, chúng tôi khuyên bạn nên luôn   cam kết hoặc stash thay đổi của bạn trước khi chạy git merge.

git merge --abort tương đương với git reset --merge khi nào    MERGE_HEAD là món quà.

http://www.git-scm.com/docs/git-merge


378
2017-11-12 21:40



Điều này đã có từ git v1.7.4. Đó là bí danh cho git reset --merge. - Michael Johnson
Không hoạt động với xung đột hợp nhất bạch tuộc. - ks1322


Trong trường hợp sử dụng cụ thể này, bạn không thực sự muốn hủy hợp nhất, chỉ giải quyết xung đột theo một cách cụ thể.

Không có nhu cầu cụ thể để thiết lập lại và thực hiện một hợp nhất với một chiến lược khác nhau, một trong hai. Các xung đột đã được git đánh dấu chính xác và yêu cầu chấp nhận các thay đổi bên kia chỉ dành cho một tệp này.

Đối với một tệp chưa được nhúng trong một git xung đột, hãy tạo sẵn các phiên bản cơ bản, cục bộ và từ xa của tệp trong chỉ mục. (Đây là nơi chúng được đọc để sử dụng trong công cụ tìm khác biệt 3 chiều git mergetool.) Bạn có thể dùng git show để xem chúng.

# common base:
git show :1:_widget.html.erb

# 'ours'
git show :2:_widget.html.erb

# 'theirs'
git show :3:_widget.html.erb

Cách đơn giản nhất để giải quyết xung đột để sử dụng nguyên văn phiên bản từ xa là:

git show :3:_widget.html.erb >_widget.html.erb
git add _widget.html.erb

Hoặc, với git> = 1.6.1:

git checkout --theirs _widget.html.erb

73
2017-09-20 10:41



cảm ơn cho gợi ý. Tuy nhiên, cái này không phải là một giao diện người dùng git nghèo nàn? - Peter
@ Peter: Tôi không bị thuyết phục. Kết quả mong muốn có thể đạt được với một vài lệnh cơ bản với các tùy chọn đơn giản. Bạn sẽ đề xuất cải tiến nào? - CB Bailey
Tôi nghĩ rằng git 1.6.1 lệnh làm cho rất nhiều ý nghĩa, và là tốt. Đó chính là điều tôi muốn. Tôi nghĩ rằng các giải pháp trước 1.6.1 là không phù hợp và đòi hỏi kiến ​​thức về các phần khác của git nên được tách ra từ quá trình giải quyết hợp nhất. Nhưng phiên bản mới thật tuyệt vời! - Peter


tôi nghĩ nó là git reset bạn cần.

Hãy coi chừng điều đó git revert có nghĩa là một cái gì đó rất khác với svn revert - trong Subversion, việc hoàn nguyên sẽ hủy bỏ các thay đổi (không được cam kết) của bạn, trả lại tệp cho phiên bản hiện tại từ kho lưu trữ, trong khi git revert "hoàn tác" một cam kết.

git reset nên làm tương đương với svn revert, nghĩa là loại bỏ các thay đổi không mong muốn của bạn.


72
2017-09-19 13:25





Vì nhận xét cho rằng git reset --merge là bí danh cho git merge --abort, đáng chú ý là git merge --abort chỉ tương đương với git reset --mergecho rằng một MERGE_HEAD là món quà. Điều này có thể được đọc trong git help cho lệnh merge.

git merge --abort is equivalent to git reset --merge when MERGE_HEAD is present.

Sau khi hợp nhất không thành công, khi không có MERGE_HEAD, hợp nhất không thành công có thể được hoàn tác với git reset --merge nhưng không nhất thiết với git merge --abort, do đó, họ không chỉ là cú pháp cũ và mới cho cùng một điều.

Cá nhân tôi tìm thấy git reset --merge mạnh mẽ hơn nhiều cho các kịch bản tương tự như kịch bản được mô tả và các lần kết hợp không thành công nói chung.


29
2018-04-02 12:16



điều gì ở đây thực sự có nghĩa là "hợp nhất không thành công"? Hợp nhất với các xung đột hoặc cái gì khác? Hoặc để nói lại nó: khi nào thì MERGE_HEAD không có mặt? Câu hỏi tiếp theo của tôi là để hiểu rõ hơn cách sử dụng "git reset --merge". - Ewoks


Kể từ Git 1.6.1.3 git checkout đã có thể thanh toán từ hai bên của hợp nhất:

git checkout --theirs _widget.html.erb

16
2017-07-17 01:29