git checkout
có --ours
tù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 --theirs
phiên bản mà bạn đã kéo vào). Bạn có thể vượt qua .
để git checkout
bả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 add
và 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 checkout
lệnh. Điều đó rất quan trọng và dễ bỏ lỡ. git checkout
có 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 checkout
lệ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 HEAD
chỉ đượ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-commit
nếu bạn cần chỉnh sửa trước (ví dụ: nếu bạn đổi tên hàm foo
thành bar
và 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 (<<<<<<<
, =======
và >>>>>>>
) 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 add
trướ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 --ours
hoặ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
.