a

Câu hỏi Làm cách nào để buộc "git pull" ghi đè lên các tệp cục bộ?


Làm cách nào để buộc ghi đè tệp cục bộ trên git pull?

Kịch bản như sau:

  • Một thành viên trong nhóm đang sửa đổi các mẫu cho một trang web mà chúng tôi đang làm việc
  • Họ đang thêm một số hình ảnh vào thư mục hình ảnh (nhưng quên thêm chúng dưới sự kiểm soát nguồn)
  • Họ gửi hình ảnh qua thư, sau đó, với tôi
  • Tôi đang thêm các hình ảnh dưới sự kiểm soát nguồn và đẩy chúng vào GitHub cùng với các thay đổi khác
  • Họ không thể kéo các bản cập nhật từ GitHub vì Git không muốn ghi đè lên các tệp của họ.

Đây là lỗi tôi nhận được:

error: Untracked working tree file 'public/images/icon.gif' would be overwritten by merge

Làm cách nào để buộc Git ghi đè lên chúng? Người đó là một nhà thiết kế - thường tôi giải quyết tất cả các xung đột bằng tay, vì vậy máy chủ có phiên bản mới nhất mà họ chỉ cần cập nhật trên máy tính của họ.


5217
2017-07-14 14:58


gốc


bất cứ ai đọc điều này nghĩ rằng họ có thể mất tập tin, tôi đã ở vị trí này và thấy bộ đệm của Sublime Text đã cứu tôi - nếu tôi đang làm việc gì đó, sau đó vô tình xóa mọi thứ bằng cách cố gắng giải quyết vấn đề tương tự cho vấn đề này hoặc bằng cách sử dụng một câu trả lời về câu hỏi này và đã có các tập tin mở trong Sublime (trong đó có một cơ hội tốt) sau đó các tập tin vẫn sẽ ở đó là tuyệt vời, hoặc chỉ có ở đó, hoặc trong lịch sử hoàn tác - Toni Leigh
git reset --hard origin/branch_to_overwrite - Andrew Atkinson


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


Quan trọng: Nếu bạn có bất kỳ thay đổi cục bộ nào, chúng sẽ bị mất. Có hay không --hard tùy chọn, mọi cam kết cục bộ chưa được đẩy sẽ bị mất.[*]

Nếu bạn có bất kỳ tệp nào không phải được theo dõi bởi Git (ví dụ: nội dung người dùng được tải lên), những tệp này sẽ không bị ảnh hưởng.


Tôi nghĩ đây là cách đúng:

git fetch --all

Sau đó, bạn có hai tùy chọn:

git reset --hard origin/master

HOẶC Nếu bạn đang ở trên một số chi nhánh khác:

git reset --hard origin/<branch_name>

Giải trình:

git fetch tải xuống mới nhất từ ​​xa mà không cố gắng hợp nhất hoặc rebase bất cứ điều gì.

Sau đó, git reset đặt lại nhánh chính thành nhánh bạn vừa tìm nạp. Các --hard tùy chọn thay đổi tất cả các tệp trong cây đang hoạt động của bạn để khớp với các tệp trong origin/master


Duy trì các cam kết địa phương hiện tại

[*]: Cần lưu ý rằng có thể duy trì các cam kết địa phương hiện tại bằng cách tạo chi nhánh từ master trước khi đặt lại:

git checkout master
git branch new-branch-to-save-current-commits
git fetch --all
git reset --hard origin/master

Sau đó, tất cả các cam kết cũ sẽ được lưu giữ trong new-branch-to-save-current-commits.

Những thay đổi không được cam kết

Tuy nhiên, những thay đổi không được cam kết (thậm chí được tổ chức) sẽ bị mất. Hãy chắc chắn để stash và cam kết bất cứ điều gì bạn cần. Cho rằng bạn có thể chạy như sau:

git stash

Và sau đó áp dụng lại những thay đổi không được cam kết này:

git stash pop

7301
2018-01-17 00:02



Xem ra! Nếu bạn có cam kết không được sửa chữa cục bộ, việc này sẽ xóa chúng khỏi chi nhánh của bạn! Giải pháp này giữ các tập tin không được theo dõi không có trong kho lưu trữ còn nguyên vẹn, nhưng sẽ ghi đè mọi thứ khác. - Matthijs P
Đó là một câu hỏi phổ biến, vì vậy tôi muốn làm rõ trên bình luận hàng đầu ở đây. Tôi chỉ thực hiện các lệnh như được mô tả trong câu trả lời này và nó đã không loại bỏ TẤT CẢ các tệp cục bộ. Chỉ các tệp được theo dõi từ xa mới bị ghi đè và mọi tệp cục bộ đã ở đây không được chạm vào. - Red
Điều này làm việc cho tôi và các tập tin địa phương của tôi đã không bị xóa. - Tastybrownies
trong trường hợp bạn đang kéo từ một repo có tên nhánh từ xa khác với "master", sử dụng git reset --hard origin/branch-name - Nerrve
Với số lượng upvotes cho câu hỏi và câu trả lời này, tôi nghĩ rằng git nên kết hợp một lệnh như git pull -f - Sophivorus


Thử cái này:

git reset --hard HEAD
git pull

Nó sẽ làm những gì bạn muốn.


761
2018-05-09 19:45



Tôi đã thực hiện điều này và một số tệp cục bộ không còn trong repo được để lại trên đĩa. - Piotr Owsiak
Tôi không nghĩ rằng điều này là chính xác. ở trên sẽ thực hiện hợp nhất, không ghi đè lên được yêu cầu trong câu hỏi: "Làm thế nào để ép git ghi đè lên chúng?" Tôi không có câu trả lời, tôi hiện đang tìm kiếm nó .. tại thời điểm tôi chuyển sang chi nhánh với mã mà tôi muốn giữ "git checkout BranchWithCodeToKeep", sau đó thực hiện "git branch -D BranchToOverwrite" và cuối cùng là "git checkout -b BranchToOverwrite". bây giờ bạn sẽ có mã chính xác từ BranchWithCodeToKeep trên BranchToOverwrite nhánh mà không cần phải thực hiện hợp nhất. - felbus
thay vì hợp nhất bằng cách sử dụng 'git pull', hãy thử git fetch --all theo sau là 'git reset --hard origin / master' - Lloyd Moore
vâng, giải pháp @lloydmoore làm việc cho tôi. Có thể làm với một câu trả lời chứ không chỉ là một bình luận. - Max Williams
Điều này sẽ thiết lập lại các thay đổi hiện tại trở lại nhánh cam kết cuối cùng được kéo. Sau đó, git pull hợp nhất các thay đổi từ nhánh mới nhất. Điều này đã làm chính xác những gì tôi muốn nó làm .. Cảm ơn! - Codeversed


CẢNH BÁO: git clean xóa tất cả các tệp / thư mục không được theo dõi của bạn và không thể hoàn tác.


Đôi khi chỉ clean -f không giúp được gì. Trong trường hợp bạn có DIRECTORIES không được ủy quyền, tùy chọn -d cũng cần:

git reset --hard HEAD
git clean -f -d
git pull

CẢNH BÁO: git clean xóa tất cả các tệp / thư mục không được theo dõi của bạn và không thể hoàn tác.


381
2018-03-19 09:10



Tuyệt vời ... Chạy cái này chống lại dấu chấm của tôi ... Trong thư mục chính của tôi. Tốt mà tôi không thực sự có bất cứ điều gì quan trọng ở đó ... - Lauri
Tôi nghĩ rằng mô tả kịch bản làm cho nó rõ ràng rằng ông không thực sự muốn vứt bỏ nội dung. Thay vào đó, những gì anh ta muốn là ngừng git baulking khi ghi đè lên các tập tin. @ Lauri, điều này không nên xảy ra với bạn. Thật không may mọi người dường như đã hiểu sai bản chất của mô tả kịch bản - xem đề xuất của tôi. - Hedgehog
CUỐI CÙNG. git clean -f -d rất tiện lợi khi dọn dẹp sạch sẽ mọi thứ. - earthmeLon
@crizCraig trừ khi chúng được thêm vào .gitignore - Bleeding Fingers
@earthmeLon, cho rằng bạn có thể muốn git clean -dfx. Các -x bỏ qua .gitignore. Thông thường các sản phẩm xây dựng của bạn sẽ có trong .gitignore. - Paul Draper


Giống như Hedgehog tôi nghĩ rằng câu trả lời là khủng khiếp. Nhưng mặc dù câu trả lời của Hedgehog có thể tốt hơn, tôi không nghĩ rằng nó là thanh lịch như nó có thể được. Cách tôi tìm thấy để làm điều này là bằng cách sử dụng "lấy" và "hợp nhất" với một chiến lược được xác định. Mà nên làm cho nó để thay đổi địa phương của bạn được bảo quản miễn là họ không phải là một trong các tập tin mà bạn đang cố gắng để buộc một ghi đè với.

Trước tiên hãy cam kết thay đổi của bạn

 git add *
 git commit -a -m "local file server commit message"

Sau đó tìm nạp các thay đổi và ghi đè nếu có xung đột

 git fetch origin master
 git merge -s recursive -X theirs origin/master

"-X" là tên tùy chọn và "của họ" là giá trị cho tùy chọn đó. Bạn đang chọn sử dụng thay đổi "của họ" thay vì "của bạn" thay đổi nếu có xung đột.


335
2018-04-11 20:13



Đây là câu trả lời tốt nhất mà tôi đã nhìn thấy cho đến nay. Tôi đã không thử nó, nhưng không giống như câu trả lời khác, điều này không cố gắng nuke tất cả các tập tin untracked của bạn, đó là rất nguy hiểm vì lý do rõ ràng. - huyz
Ditto - điều này làm việc cho tôi khi thực hiện một hợp nhất rất lớn (yêu cầu kéo GitHub), nơi tôi chỉ muốn chấp nhận tất cả trên đầu trang của những gì tôi đã có. Câu trả lời tốt! Trong trường hợp của tôi hai lệnh cuối cùng là: 1) get fetch other-repo; 2) git merge -s recursive -X theirs other-repo/master - quux00
Câu hỏi: -X là gì? 'Của họ' là gì? - AlxVallejo
Thao tác này sẽ ghi đè bất kỳ xung đột nào với các tệp kho lưu trữ chứ không phải các tệp cục bộ của bạn, đúng không? - Nathan Fiscaletti
"-X" là tên tùy chọn và "của họ" là giá trị cho tùy chọn đó. Bạn đang chọn sử dụng thay đổi "của họ" thay vì "của bạn" thay đổi nếu có xung đột. - Richard Kersey


Thay vì làm:

git fetch --all
git reset --hard origin/master

Tôi khuyên bạn nên làm như sau:

git fetch origin master
git reset --hard origin/master

Không cần phải lấy tất cả các điều khiển từ xa và các nhánh nếu bạn định thiết lập lại nhánh gốc / master đúng không?


237
2018-04-26 13:48



Câu trả lời của bạn chỉ là những gì bạn cần cho đại diện của bạn. Tôi phải yêu cầu, điều này cũng loại bỏ tất cả các tập tin untracked? - Nicolas De Jay
Yeah, hầu hết các đại diện của tôi đến từ đây :) Điều này cũng sẽ loại bỏ tất cả các tập tin untracked. Một cái gì đó tôi đã quên và được nhắc nhở đau đớn chỉ 2 ngày trước ... - Johanneke
Xem nhận xét về câu trả lời khác này: stackoverflow.com/a/8888015/2151700 - Johanneke
Điều này đã không loại bỏ các tập tin không được theo dõi của tôi; đó thực sự là những gì tôi mong đợi. Có một lý do nào đó có thể cho một số người chứ không phải cho người khác? - arichards
Các tập tin không được theo dõi sẽ không bị ảnh hưởng bởi thiết lập lại git. Nếu bạn muốn chúng bị xóa, hãy làm git add . đầu tiên, trước git reset --hard - Johanneke


Dường như cách tốt nhất là làm trước:

git clean

Để xóa tất cả các tệp không được theo dõi và sau đó tiếp tục với thông thường git pull...


122
2017-07-14 15:16



Tôi đã thử sử dụng "git clean" để giải quyết cùng một vấn đề, nhưng nó không giải quyết được. trạng thái git nói "Nhánh của bạn và" origin / master "đã phân tách, # và có 2 và 9 commit khác nhau tương ứng." và git pull nói điều gì đó tương tự như những gì bạn có ở trên. - slacy
git clean là một công cụ khá cùn, và có thể vứt đi rất nhiều thứ mà bạn có thể muốn giữ lại. Tốt hơn là xóa hoặc đổi tên các tệp mà git đang phàn nàn cho đến khi quá trình kéo thành công. - Neil Mayhew
Tôi không nghĩ rằng công trình này nói chung. Không phải là có một cách để làm cơ bản một git clone từ xa thông qua một git kéo buộc? - mathtick
@mathick: git fetch origin && git reset --hard origin/master - Arrowmaster
Là git clean câu trả lời tốt nhất ở đây? Có vẻ như việc xóa các tệp không nhất thiết là những gì OP muốn. Họ yêu cầu 'ghi đè các tập tin cục bộ' không bị xóa. - JohnAllen


Cảnh báo, làm điều này sẽ xóa vĩnh viễn các tệp của bạn nếu bạn có bất kỳ thư mục / * mục nào trong tệp gitignore của bạn.

Một số câu trả lời có vẻ khủng khiếp. Khủng khiếp trong ý nghĩa của những gì đã xảy ra với @ Lauri bằng cách làm theo David Avsajanishvili gợi ý.

Thay vào đó (git> v1.7.6):

git stash --include-untracked
git pull

Sau đó bạn có thể làm sạch lịch sử stash.

Theo cách thủ công, từng người một:

$ git stash list
stash@{0}: WIP on <branch>: ...
stash@{1}: WIP on <branch>: ...

$ git stash drop stash@{0}
$ git stash drop stash@{1}

Đột nhiên, tất cả cùng một lúc:

$ git stash clear

Tất nhiên nếu bạn muốn quay trở lại những gì bạn đã cất giấu:

$ git stash list
...
$ git stash apply stash@{5}

97
2018-02-11 23:00



Không, tôi không nghĩ vậy. Stashing chỉ di chuyển các tập tin không được cam kết ra khỏi con đường. Ở trên cũng di chuyển (stashes) tập tin mà git không theo dõi. Điều này ngăn chặn các tệp đã được thêm vào điều khiển từ xa mà chưa được kéo xuống máy của bạn - nhưng bạn đã tạo (!) - để kéo xuống. Tất cả mà không phá hủy công việc không được cam kết. Hy vọng rằng có ý nghĩa? - Hedgehog
Nếu bạn không có 1.7.6, bạn có thể bắt chước --include-untracked chỉ đơn giản bằng tạm thời git add- toàn bộ repo của bạn, sau đó ngay lập tức stashing nó. - nategood
Tôi đồng ý với Hedgehog. Nếu bạn làm các câu trả lời phổ biến ở đây, bạn có nhiều khả năng sẽ tìm thấy bạn đã vô tình giết chết rất nhiều thứ mà bạn không thực sự muốn mất. - Guardius
Tôi đã có các tệp không được theo dõi khác - bên cạnh tệp hợp nhất / kéo muốn ghi đè, vì vậy giải pháp này hoạt động tốt nhất. git stash apply đã mang lại tất cả các tệp không được theo dõi của tôi với ngoại lệ (đúng) của các tệp mà hợp nhất đã tạo: "đã tồn tại, không có thanh toán". Làm việc hoàn hảo. - BigBlueHat
Đây là câu trả lời rõ ràng nhất và phải là câu trả lời được chấp nhận. Để lưu một số thao tác nhập, bạn có thể sử dụng biểu mẫu ngắn: git stash -u. - ccpizza


Bạn có thể thấy lệnh này hữu ích để vứt bỏ các thay đổi cục bộ:

git checkout <your-branch> -f

Và sau đó thực hiện dọn dẹp (xóa các tập tin không được theo dõi khỏi cây đang hoạt động):

git clean -f

Nếu bạn muốn xóa các thư mục không được theo dõi ngoài các tệp không được theo dõi:

git clean -fd

86
2017-08-05 18:06



Tôi nghĩ rằng mô tả kịch bản làm cho nó rõ ràng rằng ông không thực sự muốn vứt bỏ nội dung. Thay vào đó, những gì anh ta muốn là ngừng git baulking khi ghi đè lên các tập tin. Xem đề nghị của tôi. - Hedgehog
Mặc dù câu trả lời đó có thể không phù hợp chính xác với mô tả, nó vẫn lưu tôi khỏi sự thất vọng của git twiddling với các vận chuyển trở lại (sự kiện với autocrlf false). Khi git reset --hard HEAD không để lại cho bạn các tệp "không" được sửa đổi, các cờ "-f" này khá hữu ích. Cảm ơn nhiều. - Kellindil