Làm cách nào tôi có thể loại bỏ các thay đổi từ xa và đánh dấu một tệp là đã giải quyết được cải tiến?


197

Tôi có một số tệp cục bộ, tôi lấy từ chi nhánh từ xa và có xung đột. Tôi biết rằng tôi muốn giữ các thay đổi cục bộ của mình và bỏ qua các thay đổi từ xa gây ra xung đột. Có một lệnh tôi có thể sử dụng để thực hiện nói "đánh dấu tất cả các xung đột là đã được giải quyết, sử dụng cục bộ" không?


1
Câu trả lời dưới đây đã được chiếu sáng cho tôi. Có một vài điểm tinh tế đã làm cho tôi thực sự rõ ràng, tôi khuyên mọi người dùng GIT không phải là chuyên gia nên đọc tất cả các bình luận bên dưới bài viết dưới đây, và cảm ơn Brian!
Tom DeMille

Câu trả lời:


332

git checkout--ourstùy chọn để kiểm tra phiên bản của tệp mà bạn có cục bộ (trái ngược với --theirsphiên bản mà bạn đã kéo vào). Bạn có thể vượt qua .để git checkoutbảo nó kiểm tra mọi thứ trên cây. Sau đó, bạn cần đánh dấu các xung đột là đã được giải quyết, điều bạn có thể làm git addvà cam kết công việc của mình sau khi hoàn thành:

git checkout --ours .  # checkout our local version of all files
git add -u             # mark all conflicted files as merged
git commit             # commit the merge

Lưu ý .trong git checkoutlệnh. Điều đó rất quan trọng và dễ bỏ lỡ. git checkoutcó hai chế độ; một trong đó nó chuyển các nhánh và một trong đó nó kiểm tra các tệp ra khỏi chỉ mục thành bản sao làm việc (đôi khi kéo chúng vào chỉ mục từ lần sửa đổi khác trước). Cách nó phân biệt là bằng cách bạn đã chuyển tên tệp vào; nếu bạn chưa chuyển tên tệp, nó sẽ thử chuyển nhánh (mặc dù nếu bạn không chuyển qua nhánh, nó sẽ thử kiểm tra nhánh hiện tại một lần nữa), nhưng nó từ chối làm như vậy nếu có tệp sửa đổi Điều đó sẽ có hiệu lực. Vì vậy, nếu bạn muốn một hành vi sẽ ghi đè lên các tệp hiện có, bạn cần chuyển vào .hoặc một tên tệp để có được hành vi thứ hai từ đó git checkout.

Đó cũng là một thói quen tốt khi có tên tệp để bù lại --, chẳng hạn như git checkout --ours -- <filename>. Nếu bạn không làm điều này và tên tệp xảy ra khớp với tên của nhánh hoặc thẻ, Git sẽ nghĩ rằng bạn muốn kiểm tra sửa đổi đó, thay vì kiểm tra tên tệp đó, và vì vậy hãy sử dụng dạng đầu tiên của checkoutlệnh .

Tôi sẽ mở rộng một chút về cách xung đột và hợp nhất hoạt động trong Git. Khi bạn hợp nhất mã của người khác (cũng xảy ra trong quá trình kéo; kéo về cơ bản là tìm nạp theo sau là hợp nhất), có một vài tình huống có thể xảy ra.

Đơn giản nhất là bạn đang sửa đổi. Trong trường hợp này, bạn "đã cập nhật" và không có gì xảy ra.

Một khả năng khác là bản sửa đổi của họ chỉ đơn giản là hậu duệ của bạn, trong trường hợp đó bạn sẽ mặc định có "hợp nhất chuyển tiếp nhanh", trong đó bạn HEADchỉ được cập nhật vào cam kết của họ, không có sự hợp nhất nào xảy ra (điều này có thể bị vô hiệu hóa nếu bạn thực sự muốn ghi lại một sự hợp nhất, sử dụng --no-ff).

Sau đó, bạn nhận được vào các tình huống mà bạn thực sự cần phải hợp nhất hai phiên bản. Trong trường hợp này, có hai kết quả có thể xảy ra. Một là sự hợp nhất diễn ra sạch sẽ; tất cả các thay đổi nằm trong các tệp khác nhau hoặc trong cùng một tệp nhưng cách nhau đủ xa để cả hai bộ thay đổi có thể được áp dụng mà không gặp sự cố. Theo mặc định, khi hợp nhất sạch xảy ra, nó sẽ tự động được cam kết, mặc dù bạn có thể vô hiệu hóa điều này --no-commitnếu bạn cần chỉnh sửa trước (ví dụ: nếu bạn đổi tên hàm foothành barvà ai đó thêm mã mới gọi foo, nó sẽ hợp nhất sạch , nhưng tạo ra một cây bị hỏng, vì vậy bạn có thể muốn dọn sạch nó như là một phần của cam kết hợp nhất để tránh có bất kỳ cam kết bị hỏng nào).

Khả năng cuối cùng là có một sự hợp nhất thực sự, và có những xung đột. Trong trường hợp này, Git sẽ thực hiện càng nhiều việc hợp nhất càng tốt và tạo ra các tệp có dấu xung đột (<<<<<<< , =======>>>>>>>) trong bản sao làm việc của bạn. Trong chỉ mục (còn được gọi là "khu vực tổ chức"; nơi lưu trữ các tệp git addtrước khi thực hiện chúng), bạn sẽ có 3 phiên bản của mỗi tệp có xung đột; có phiên bản gốc của tệp từ tổ tiên của hai nhánh bạn đang hợp nhất, phiên bản từ HEAD(phía bạn hợp nhất) và phiên bản từ nhánh từ xa.

Để giải quyết xung đột, bạn có thể chỉnh sửa tệp trong bản sao làm việc của mình, xóa các dấu xung đột và sửa mã lên để nó hoạt động. Hoặc, bạn có thể kiểm tra phiên bản từ một hoặc các mặt khác của hợp nhất, bằng cách sử dụng git checkout --ourshoặc git checkout --theirs. Khi bạn đã đặt tệp vào trạng thái bạn muốn, bạn cho biết rằng bạn đã hoàn tất việc hợp nhất tệp và nó đã sẵn sàng để cam kết sử dụng git add, và sau đó bạn có thể cam kết hợp nhất với git commit.


7
Bạn có thể nên lưu ý rằng git add --allthêm tất cả các tệp vào kho lưu trữ để điều này có thể thêm nhiều tệp hơn dự định trừ khi .gitignorecác mẫu của bạn ở trạng thái hoàn hảo. git add -ucó lẽ phù hợp hơn cho tình huống này, bạn ít có khả năng chỉnh sửa các tệp được theo dõi mà bạn không muốn thêm trong khi giải quyết hợp nhất.
CB Bailey

Ối xin lỗi. Ý tôi là thế Sửa nó ngay.
Brian Campbell

1
cảm ơn câu trả lời chi tiết của bạn Tôi thực sự đã thử kiểm tra git --ours và nhận được thông báo lỗi (hiện tại tôi không nhớ lại). Các tệp trong câu hỏi là dll (chúng tôi có một vài cái mà chúng tôi thực hiện, chủ yếu là các tài liệu tham khảo của bên thứ 3) và tôi chỉ muốn nói 'ok bản sao của tôi là những cái tôi muốn nhưng lỗi là' không thể kiểm tra trong khi hợp nhất ' ..... Tôi sẽ giữ bài viết này làm tài liệu tham khảo và lần tiếp theo nó sẽ thử lại và xem nó có hoạt động không hoặc liệu tôi có thể đăng thông báo đó không. Cảm ơn một lần nữa
Tom DeMille

nhưng lời giải thích của bạn làm sáng tỏ rất nhiều cho tôi về quy trình, cảm ơn một lần nữa ... Câu hỏi tiếp theo: Có cách nào để git xóa các tập tin .orig sau khi tôi xóa hợp nhất không?
Tom DeMille

2
Bạn cần phải làm git checkout --ours .. Điều .quan trọng là; chuyển qua một tên tệp (trong trường hợp này là toàn bộ thư mục) chọn giữa hai chế độ hoạt động khác nhau, một chế độ checkoutchuyển nhánh và một chuyển tệp từ chỉ mục sang bản sao làm việc. Tôi đồng ý, nó rất khó hiểu. Bạn cũng có thể làm git checkout --ours -- <filename>để kiểm tra một tệp riêng lẻ tại một thời điểm.
Brian Campbell

23

Đảm bảo nguồn gốc xung đột: nếu đó là kết quả của một git merge, hãy xem câu trả lời của Brian Campbell .

Nhưng nếu là kết quả của một git rebase, để loại bỏ các thay đổi từ xa (của chúng) và sử dụng các thay đổi cục bộ , bạn sẽ phải thực hiện:

git checkout --theirs -- .

Xem " Tại sao ý nghĩa của phạm vi oursvà phạm lỗi theirsđảo ngược" "để xem cách thức ourstheirsđược hoán đổi trong một cuộc nổi loạn (vì chi nhánh ngược dòng đã được kiểm tra).

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.