Làm cách nào để buộc tôi git kéo chà để ghi đè lên các tệp cục bộ?


7187

Làm cách nào để tôi ghi đè lên các tệp cục bộ trên a 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ọ đang gửi hình ảnh qua thư, sau đó, cho tôi
  • Tôi đang thêm 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ể lấy 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:

lỗi: Tập tin cây làm việc chưa được đóng gói 'công khai / hình ảnh / icon.gif' sẽ bị ghi đè bằng cách hợp nhất

Làm cách nào để buộc Git ghi đè lên chúng? Người này là một nhà thiết kế - thông 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ọ.


17
Bất cứ ai đọc cái này đều nghĩ rằng họ có thể bị 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ì đó, thì vô tình xóa mọi thứ bằng cách cố gắng giải quyết vấn đề tương tự với vấn đề này hoặc bằng cách sử dụng một câu trả lời cho câu hỏi này và đã mở các tệp trong Sublime (có cơ hội tốt) thì các tệp sẽ vẫn ở đó là Sublime, hoặc ở đó, hoặc trong lịch sử hoàn tác
Toni Leigh

62
git reset --hard origin/branch_to_overwrite
Andrew Atkinson

1
về cơ bản, chỉ thực hiện một động tác phát triển sau khi thanh toán ban đầu -b. làm công việc của bạn, sau đó đẩy trở lại.
ldgorman

1
Câu trả lời ngắn: xóa và tạo lại chi nhánh. 1. Xóa chi nhánh: git branch <branch> -D2. Đặt lại về một cam kết trước khi xung đột: git reset <commit> --hard3. Tạo lại chi nhánh: git branch <branch>4. Đặt theo dõi cho máy chủ: git --set-upstream-to=origin/<branch> <branch> 5. Pull: git pull`
Nino Filiu

1
Để thay đổi tất cả các kết thúc CRLF thành LF, (bắt đầu xóa)git config core.autocrlf false; git ls-files -z | xargs -0 rm; git checkout .
Chloe

Câu trả lời:


10039

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ó hoặc không có --hardtù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 được Git theo dõi (ví dụ: nội dung người dùng đã tải lên), các tệp này sẽ không bị ảnh hưởng.


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

git fetch --all

Sau đó, bạn có hai lựa chọn:

git reset --hard origin/master

HOẶC Nếu bạn đang ở 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 resetthiết lập lại nhánh chính đến những gì bạn vừa tìm nạp. Các --hardtùy chọn thay đổi tất cả các file trong cây làm việc của bạn để phù hợp với các tập tin trongorigin/master


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

[*] : Điều đáng chú ý là có thể duy trì các cam kết cục bộ hiện tại bằng cách tạo một nhánh từ mastertrướ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 này, tất cả các cam kết cũ sẽ được giữ lại 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 dàn dựng) 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

14
Coi chừng! Nếu bạn có các cam kết chưa được xử lý cục bộ, điều này sẽ xóa chúng khỏi chi nhánh của bạn! Giải pháp này giữ cho các tệp không bị theo dõi không còn trong kho lưu trữ, nhưng ghi đè lên mọi thứ khác.
Matthijs P

479
Đây là một câu hỏi phổ biến, vì vậy tôi muốn làm rõ về nhận xét 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 xóa TẤT CẢ các tệp cục bộ. Chỉ các tệp được theo dõi từ xa đã bị ghi đè và mọi tệp cục bộ ở đây đều bị bỏ hoang.
Đỏ

14
trong trường hợp bạn đang kéo từ một repo có tên chi nhánh từ xa khác với "chủ", hãy sử dụnggit reset --hard origin/branch-name
Nerrve 17/12/13

97
Với số lượng upvote 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

7
Các cam kết không được đẩy trước khi thiết lập lại cứng có thể được phục hồi bằng cách sử dụng git reflog, liệt kê tất cả các cam kết, cũng như các cam kết không có cơ sở. Cho đến khi bạn dọn sạch bản sao cục bộ của mình bằng cách sử dụng git gc, thì tất cả sẽ bị mất
Koen.

934

Thử cái này:

git reset --hard HEAD
git pull

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


16
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

26
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 đè được yêu cầu trong câu hỏi: "Làm thế nào để buộc git ghi đè lên chúng?" Tôi không có câu trả lời, hiện tại tôi đang tìm kiếm nó .. hiện tại 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 "kiểm tra git -b BranchToOverwrite". bây giờ bạn sẽ có mã chính xác từ BranchWithCodeToKeep trên nhánh BranchToOverwrite mà không phải thực hiện hợp nhất.
felbus

252
thay vì hợp nhất bằng cách sử dụng 'git pull', hãy thử git fetch - sau đó là 'git reset --hard origin / master'
Lloyd Moore

5
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 thay vì chỉ là một nhận xét.
Max Williams

2
Điều này sẽ thiết lập lại các thay đổi hiện tại trở lại cam kết chi nhánh cuối cùng được kéo. Sau đó git pull hợp nhất các thay đổi từ chi 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!
Đã sửa đổi

459

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


Đôi khi clean -fkhông giúp được gì. Trong trường hợp bạn có các GIÁM ĐỐC chưa được theo dõi, tùy chọn -d cũng cần thiết:

# WARNING: this can't be undone!

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

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

Trước tiên hãy xem xét sử dụng cờ -n( --dry-run). Điều này sẽ cho bạn thấy những gì sẽ bị xóa mà không thực sự xóa bất cứ điều gì:

git clean -n -f -d

Ví dụ đầu ra:

Would remove untracked-file-1.txt
Would remove untracked-file-2.txt
Would remove untracked/folder
...

33
Tuyệt vời ... Ran cái này chống lại repfiles của tôi ... Trong thư mục nhà của tôi. Thật tốt là tôi không thực sự có bất cứ điều gì quan trọng ở đó ...
Lauri

7
Tôi nghĩ rằng mô tả kịch bản cho thấy rõ rằng anh ta 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 trong việc ghi đè 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ư đã đọc sai bản chất của mô tả kịch bản - xem đề xuất của tôi.
Nhím

19
CUỐI CÙNG . git clean -f -d rất tiện lợi khi dọn dẹp không làm sạch mọi thứ.
earthmeLon

7
@crizCraig trừ khi chúng được thêm vào.gitignore
Chảy máu ngón tay

5
@earthmeLon, cho rằng bạn có thể muốn git clean -dfx. Việc -xbỏ qua .gitignore. Thông thường các sản phẩm xây dựng của bạn sẽ ở .gitignore.
Paul Draper

384

Giống như Hedgekey 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 Hedgekey có thể tốt hơn, tôi không nghĩ nó thanh lịch như nó có thể. Cách tôi tìm thấy để làm điều này là bằng cách sử dụng "tìm nạp" và "hợp nhất" với một chiến lược đã xác định. Điều này sẽ làm cho nó để các thay đổi cục bộ của bạn được bảo tồn miễn là chúng không phải là một trong những tệp mà bạn đang cố gắng ghi đè lên.

Trước tiên hãy cam kết về những 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ì thay đổi "của bạn" nếu có xung đột.


56
Đây là câu trả lời tốt nhất tôi từng thấy cho đến nay. Tôi đã không thử nó, nhưng không giống như các 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 chưa được theo dõi của bạn, điều này rất nguy hiểm vì những lý do rõ ràng.
huyz

5
Ditto - điều này hiệu quả với tôi khi thực hiện một sự 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

2
Điều này sẽ ghi đè bất kỳ xung đột với các tệp lưu trữ và không phải các tệp cục bộ của bạn, đúng không?
Nathan F.

2
Câu trả lời tốt nhất. Câu trả lời được chấp nhận cao nhất để lại cho tôi trong trường hợp của tôi trên đầu tách ra. Tôi quay trở lại chi nhánh chính địa phương và chạygit merge -X theirs origin/master
petergus 11/03/2016

2
Vấn đề với câu trả lời (xuất sắc) này là nó bổ sung tất cả các tệp cục bộ, đôi khi có thể không phải là những gì bạn muốn. Bạn có thể chỉ muốn thêm các tệp cụ thể đã bị bỏ qua. Nhưng điều tốt nhất về nó là, nó khiến anh ta phải làm những gì anh ta nên làm - thêm chúng vào địa phương. Bạn có thể sẽ không cần chiến lược -X của họ, vì chúng là cùng một hình ảnh. Trên thực tế, ban đầu tôi khuyên bạn nên bỏ nó đi, chỉ để tìm hiểu xem có bất kỳ sự bất thường nào không, và thêm nó vào nếu có, sau khi xem xét rằng 'của họ' luôn là lựa chọn chính xác. Nhưng sau đó, tôi bị hoang tưởng.
Bob Kerns

279

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 tìm nạp tất cả các điều khiển từ xa và các nhánh nếu bạn sẽ thiết lập lại nhánh gốc / nhánh phải không?


3
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 hỏi, điều này cũng loại bỏ tất cả các tập tin chưa được theo dõi?
Nicolas De Jay

5
Vâng, 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 chưa được theo dõi. Một cái gì đó tôi đã quên và đã được nhắc nhở một cách đau đớn chỉ 2 ngày trước ...
Johanneke

1
Xem các bình luận 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 chưa đượ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ó có thể cho một số người và không cho những người khác?
arichards

Các tệp không bị theo dõi không bị ảnh hưởng bởi git reset. Nếu bạn cũng muốn xóa chúng, hãy làm git add .trước, trướcgit reset --hard
Johanneke

131

Có vẻ như cách tốt nhất là trước tiên hãy làm:

git clean

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


4
Tôi đã thử sử dụng "git clean" để giải quyết vấn đề tương tự, nhưng nó không giải quyết được. trạng thái git cho biết "Chi nhánh và 'nguồn gốc / chủ' của bạn đã chuyển hướng, lần lượt là # và có 2 và 9 cam kết khác nhau." và git pull nói điều gì đó tương tự như những gì bạn có ở trên.
slacy

43
git sạch là một công cụ khá cùn, và có thể vứt bỏ 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 việc kéo thành công.
Neil Mayhew

2
Tôi không nghĩ rằng điều này nói chung hoạt động. Về cơ bản, không có cách nào để thực hiện một điều khiển từ xa git thông qua việc kéo git bắt buộc?
mathtick

10
@mathick:git fetch origin && git reset --hard origin/master
Arrowmaster 23/211

3
git cleancâu trả lời tốt nhất ở đây? Có vẻ như loại bỏ các tập tin không nhất thiết là những gì OP muốn. Họ yêu cầu 'ghi đè lên các tệp cục bộ' không xóa.
John ALLen

111

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 dường như là khủng khiếp. Kinh khủng theo nghĩa những gì đã xảy ra với @Lauri bằng cách làm theo đề nghị của David Avsaj Biếnvili.

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

git stash --include-untracked
git pull

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

Thủ công, từng cá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}

Một cách tàn bạo, tất cả cùng một lúc:

$ git stash clear

Tất nhiên nếu bạn muốn quay lại với những gì bạn đã đặt:

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

2
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 đường đi. Ở trên cũng di chuyển (stash) các tệp mà git không theo dõi. Điều này ngăn các tệp đã được thêm vào điều khiển từ xa chưa được kéo xuống máy của bạn - nhưng bạn đã tạo (!) - để được kéo xuống. Tất cả mà không phá hủy các công việc không cam kết. Hy vọng điều đó có ý nghĩa?
Hedgekey

3
Nếu bạn không có 1.7.6, bạn có thể bắt chước --include-untrackedđơn giản bằng cách tạm thời sử dụng git addtoàn bộ repo của mình, sau đó lập tức xóa nó.
chiến lược

3
Tôi đồng ý với Hedgehog. Nếu bạn thực hiện các câu trả lời phổ biến ở đây, nhiều khả năng bạn sẽ thấy mình đã vô tình giết rất nhiều thứ mà bạn không thực sự muốn mất.
Guardius

1
Tôi đã có các tệp không bị theo dõi khác - ngoài tệp được hợp nhất / muốn ghi đè lên, 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 chưa đượ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ó kiểm tra." Làm việc hoàn hảo.
BigBlueHat

2
Đây là câu trả lời rõ ràng nhất, và nên được chấp nhận. Để lưu một số cách gõ, bạn có thể sử dụng mẫu ngắn : git stash -u.
ccpizza

93

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

git checkout <your-branch> -f

Và sau đó thực hiện dọn dẹp (loại bỏ các tệp không bị theo dõi khỏi cây làm việc):

git clean -f

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

git clean -fd

Tôi nghĩ rằng mô tả kịch bản cho thấy rõ rằng anh ta 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 trong việc ghi đè các tập tin. Xem đề nghị của tôi.
nhím

3
Mặc dù câu trả lời đó có thể không phù hợp với mô tả chính xác, nhưng nó vẫn cứu tôi khỏi sự thất vọng của việc git twiddling với trả về vận chuyển (sự kiện với autocrlf sai). Khi git reset - ĐẦU TIÊN không để lại cho bạn các tệp đã sửa đổi "không", các cờ "-f" này khá hữu ích. Cảm ơn nhiều.
Kellindil

88

Thay vì hợp nhất với git pull, hãy thử điều này:

git fetch --all

theo dõi bởi:

git reset --hard origin/master.


61

Điều duy nhất làm việc cho tôi là:

git reset --hard HEAD~5

Điều này sẽ đưa bạn trở lại năm cam kết và sau đó với

git pull

Tôi thấy rằng bằng cách tìm kiếm cách hoàn tác hợp nhất Git .


Đây là những gì cuối cùng đã làm việc cho tôi khi tôi buộc phải đẩy chi nhánh của mình đến repo gốc và tiếp tục bị xung đột khi cố gắng kéo nó đến repo từ xa của mình ..
jwfbler

Xin chào, thực sự đây là một mẹo cho một work aroundnhưng thực sự hiệu quả. Bởi vì một số xung đột có thể xảy ra chỉ trong một vài lần xác nhận, sau đó hoàn nguyên 5 lần xác nhận sẽ đảm bảo không có xung đột với mã từ xa.
Hoàng Lê

54

Vấn đề với tất cả các giải pháp này là tất cả chúng đều quá phức tạp, hoặc, một vấn đề thậm chí còn lớn hơn, là chúng loại bỏ tất cả các tệp không được theo dõi khỏi máy chủ web, điều mà chúng tôi không muốn vì luôn có các tệp cấu hình cần thiết được bật máy chủ và không có trong kho Git.

Đây là giải pháp sạch nhất mà chúng tôi đang sử dụng:

# Fetch the newest code
git fetch

# Delete all files which are being added, so there
# are no conflicts with untracked files
for file in `git diff HEAD..origin/master --name-status | awk '/^A/ {print $2}'`
do
    rm -f -- "$file"
done

# Checkout all files which were locally modified
for file in `git diff --name-status | awk '/^[CDMRTUX]/ {print $2}'`
do
    git checkout -- "$file"
done

# Finally pull all the changes
# (you could merge as well e.g. 'merge origin/master')
git pull
  • Lệnh đầu tiên lấy dữ liệu mới nhất.

  • Lệnh thứ hai kiểm tra nếu có bất kỳ tệp nào đang được thêm vào kho lưu trữ và xóa các tệp không bị theo dõi khỏi kho lưu trữ cục bộ sẽ gây ra xung đột.

  • Lệnh thứ ba kiểm tra tất cả các tệp đã được sửa đổi cục bộ.

  • Cuối cùng, chúng tôi cố gắng cập nhật lên phiên bản mới nhất, nhưng lần này không có bất kỳ xung đột nào, vì các tệp không được theo dõi trong repo không tồn tại nữa và tất cả các tệp được sửa đổi cục bộ đều giống như trong kho lưu trữ.


Sử dụng "git merge origin / master" làm dòng cuối cùng (như bạn nói trong ghi chú của bạn) thay vì "git pull" sẽ nhanh hơn vì bạn đã kéo xuống bất kỳ thay đổi nào từ repo git.
Josh

1
Tất nhiên, git merge origin/mastersẽ nhanh hơn và thậm chí có thể an toàn hơn. Vì nếu ai đó đã đẩy các thay đổi mới trong quá trình xóa tệp của tập lệnh này (điều này không có khả năng xảy ra, nhưng có thể), toàn bộ lực kéo có thể thất bại. Lý do duy nhất tôi đưa pullvào đó là vì ai đó có thể không làm việc trên nhánh chính, nhưng một số nhánh khác và tôi muốn kịch bản là phổ quát.
Strahinja Kustudic

Nếu bạn có các tệp được tạo cục bộ như các tệp tùy chọn, hãy đặt chúng vào .gitignore.
Sebi

52

Trước hết, hãy thử cách tiêu chuẩn:

git reset HEAD --hard # To remove all not committed changes!
git clean -fd         # To remove all untracked (non-git) files and folders!

Cảnh báo : Các lệnh trên có thể dẫn đến mất dữ liệu / tệp chỉ khi bạn không cam kết chúng! Nếu bạn không chắc chắn, hãy tạo bản sao lưu trước trong toàn bộ thư mục kho lưu trữ của bạn.

Sau đó kéo nó một lần nữa.

Nếu ở trên sẽ không giúp ích và bạn không quan tâm đến các tệp / thư mục chưa được theo dõi của mình (tạo bản sao lưu trước chỉ trong trường hợp), hãy thử các bước đơn giản sau:

cd your_git_repo  # where 'your_git_repo' is your git repository folder
rm -rfv *         # WARNING: only run inside your git repository!
git pull          # pull the sources again

Điều này sẽ XÓA tất cả các tệp git (miễn trừ .git/dir, nơi bạn có tất cả các cam kết) và kéo lại.


Tại sao git reset HEAD --hardcó thể thất bại trong một số trường hợp?

  1. Quy tắc tùy chỉnh trong .gitattributes file

    Đang có eol=lf quy tắc trong .gitattribut có thể khiến git sửa đổi một số thay đổi tệp bằng cách chuyển đổi kết thúc dòng CRLF thành LF trong một số tệp văn bản.

    Nếu đó là trường hợp, bạn đã cam kết những thay đổi CRLF / LF này (bằng cách xem xét chúng git status) hoặc thử: git config core.autcrlf falsetạm thời bỏ qua chúng.

  2. Không tương thích hệ thống tập tin

    Khi bạn đang sử dụng hệ thống tệp không hỗ trợ các thuộc tính quyền. Ví dụ: bạn có hai kho lưu trữ, một trên Linux / Mac ( ext3/ hfs+) và một kho khác trên hệ thống tệp dựa trên FAT32 / NTFS.

    Như bạn chú ý, có hai loại hệ thống tệp khác nhau, do đó, hệ thống không hỗ trợ quyền Unix về cơ bản không thể đặt lại quyền truy cập tệp trên hệ thống không hỗ trợ loại quyền đó, vì vậy, dù --hardbạn có cố gắng thế nào , git luôn luôn phát hiện một số "thay đổi".


47

Tôi đã từng gặp vấn đề tương tự. Không ai cho tôi giải pháp này, nhưng nó hiệu quả với tôi.

Tôi đã giải quyết nó bằng cách:

  1. Xóa tất cả các tập tin. Chỉ để lại .gitthư mục.
  2. git reset --hard HEAD
  3. git pull
  4. git push

Bây giờ nó hoạt động.


1
Tương tự ở đây. Đôi khi chỉ có giải pháp rất khó hoạt động, nó thường xảy ra mà chỉ thiết lập lại và làm sạch không đủ bằng cách nào đó ...
jdehaan

41

Tặng kem:

Khi nói về pull / fetch / merge trong các câu trả lời trước, tôi muốn chia sẻ một mẹo thú vị và hiệu quả,

git pull --rebase

Lệnh trên là lệnh hữu ích nhất trong cuộc sống Git của tôi giúp tiết kiệm rất nhiều thời gian.

Trước khi đẩy cam kết mới của bạn đến máy chủ, hãy thử lệnh này và nó sẽ tự động đồng bộ hóa các thay đổi máy chủ mới nhất (với fetch + merge) và sẽ đặt cam kết của bạn ở đầu trong nhật ký Git. Không cần phải lo lắng về việc kéo / hợp nhất thủ công.

Tìm chi tiết trong "Git pull --rebase" làm gì? .


3
Tóm lại : git pull -r.
kenorb

29

Tôi đã có một vấn đề tương tự. Tôi phải làm điều này:

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

6
sử dụng git cleanmột cách thận trọng
chiến lược

29

Tôi tóm tắt các câu trả lời khác. Bạn có thể thực hiện git pullmà không có lỗi:

git fetch --all
git reset --hard origin/master
git reset --hard HEAD
git clean -f -d
git pull

Cảnh báo : Kịch bản này rất mạnh mẽ, vì vậy bạn có thể mất các thay đổi của mình.


2
Điều này sẽ ghi đè lên các tệp đã sửa đổi (các tệp đã được kiểm tra trước đó) và nó sẽ xóa các tệp không bị theo dõi (các tệp chưa bao giờ được kiểm tra). Chính xác những gì tôi đang tìm kiếm, cảm ơn!
styfle

3
Tôi nghi ngờ dòng thứ ba git reset --hard HEADcó thể là dư thừa; trang người đàn ông địa phương của tôi (2.6.3) nói rằng resettrong dòng thứ hai git reset --hard origin/master "mặc định là ĐẦU dưới mọi hình thức."
arichards

2
@arichards Tôi nghĩ rằng nghi ngờ của bạn là đúng nhưng nếu dòng thứ hai sẽ không hoạt động (bởi bất kỳ lý do nào) dòng thứ ba hoạt động tốt để thiết lập lại. Giải pháp này không cần phải được tối ưu hóa. Tôi chỉ tóm tắt các câu trả lời khác. Đó là tất cả. Cảm ơn bình luận của bạn. :)
Robert Moon

28

Dựa trên kinh nghiệm tương tự của riêng tôi, giải pháp được cung cấp bởi Strahinja Kustudic ở trên cho đến nay là tốt nhất. Như những người khác đã chỉ ra, chỉ cần thực hiện thiết lập lại cứng sẽ loại bỏ tất cả các tệp không bị theo dõi có thể bao gồm nhiều thứ mà bạn không muốn xóa, chẳng hạn như các tệp cấu hình. Điều an toàn hơn là chỉ xóa các tệp sắp được thêm vào và đối với vấn đề đó, bạn cũng có thể muốn kiểm tra bất kỳ tệp nào được sửa đổi cục bộ sắp được cập nhật.

Điều đó trong tâm trí, tôi đã cập nhật kịch bản của Kustudic để làm điều đó. Tôi cũng đã sửa một lỗi đánh máy (thiếu 'trong bản gốc).

#/bin/sh

# Fetch the newest code
git fetch

# Delete all files which are being added,
# so there are no conflicts with untracked files
for file in `git diff HEAD..origin/master --name-status | awk '/^A/ {print $2}'`
do
    echo "Deleting untracked file $file..."
    rm -vf "$file"
done

# Checkout all files which have been locally modified
for file in `git diff HEAD..origin/master --name-status | awk '/^M/ {print $2}'`
do
    echo "Checking out modified file $file..."
    git checkout $file
done

# Finally merge all the changes (you could use merge here as well)
git pull

Sử dụng "git merge origin / master" làm dòng cuối cùng (như bạn nói trong ghi chú của bạn) thay vì "git pull" sẽ nhanh hơn vì bạn đã kéo xuống bất kỳ thay đổi nào từ repo git.
Josh

Việc kiểm tra các tập tin sửa đổi là cần thiết, vì vậy điều này hoạt động 100% lần. Tôi đã cập nhật kịch bản của mình với điều đó từ lâu, nhưng cũng quên cập nhật ở đây. Tôi cũng sử dụng nó một chút khác nhau so với bạn. Tôi kiểm tra các tệp có bất kỳ loại sửa đổi nào, không chỉ M, vì vậy nó hoạt động mọi lúc.
Strahinja Kustudic

24

Tôi tin rằng có hai nguyên nhân có thể gây ra xung đột, phải được giải quyết riêng và theo như tôi có thể nói không có câu trả lời nào ở trên giải quyết cả hai:

  • Các tệp cục bộ không bị theo dõi cần phải được xóa, bằng tay (an toàn hơn) hoặc như được đề xuất trong các câu trả lời khác, bởi git clean -f -d

  • Các xác nhận cục bộ không nằm trên nhánh từ xa cũng cần phải bị xóa. IMO cách dễ nhất để đạt được điều này là: git reset --hard origin/master(thay thế 'chủ nhân' bằng bất kỳ nhánh nào bạn đang làm việc và chạy git fetch originđầu tiên)


22

Một cách dễ dàng hơn là:

git checkout --theirs /path/to/file.extension
git pull origin master

Điều này sẽ ghi đè tệp cục bộ của bạn với tệp trên git


21

Có vẻ như hầu hết các câu trả lời ở đây đều tập trung vào master chi nhánh; tuy nhiên, có những lúc tôi làm việc trên cùng một nhánh tính năng ở hai nơi khác nhau và tôi muốn một cuộc nổi loạn ở một nơi sẽ được phản ánh ở nơi khác mà không cần phải nhảy qua nhiều vòng.

Dựa trên sự kết hợp giữa câu trả lời của RNAcâu trả lời của torek cho một câu hỏi tương tự , tôi đã đưa ra câu trả lời tuyệt vời này:

git fetch
git reset --hard @{u}

Chạy cái này từ một nhánh và nó sẽ chỉ đặt lại nhánh cục bộ của bạn thành phiên bản ngược dòng.

Điều này cũng có thể được đưa vào một bí danh git ( git forcepull):

git config alias.forcepull "!git fetch ; git reset --hard @{u}"

Hoặc, trong .gitconfigtệp của bạn :

[alias]
  forcepull = "!git fetch ; git reset --hard @{u}"

Thưởng thức!


Câu trả lời này cũng tốt bởi vì nó hoạt động bất kể bạn đang ở chi nhánh nào!
bột lá

19

Tôi đã có cùng một vấn đề và vì một số lý do, thậm chí git clean -f -dsẽ không làm điều đó. Đây là lý do: Vì một số lý do, nếu tệp của bạn bị Git bỏ qua (thông qua mục .gitignore, tôi giả sử), nó vẫn phiền về việc ghi đè lên điều này bằng một lần kéo sau , nhưng sạch sẽ không xóa nó, trừ khi bạn thêm -x.


19

Tôi biết một phương pháp dễ dàng hơn và ít đau đớn hơn:

$ git branch -m [branch_to_force_pull] tmp
$ git fetch
$ git checkout [branch_to_force_pull]
$ git branch -D tmp

Đó là nó!


18

Tôi chỉ tự giải quyết điều này bằng cách:

git checkout -b tmp # "tmp" or pick a better name for your local changes branch
git add -A
git commit -m 'tmp'
git pull
git checkout master # Or whatever branch you were on originally
git pull
git diff tmp

trong đó lệnh cuối cùng đưa ra một danh sách những thay đổi cục bộ của bạn. Tiếp tục sửa đổi nhánh "tmp" cho đến khi được chấp nhận và sau đó hợp nhất trở lại vào master với:

git checkout master && git merge tmp

Lần tới, có lẽ bạn có thể xử lý việc này theo cách sạch hơn bằng cách tra cứu "nhánh git stash" mặc dù stash có thể gây rắc rối cho bạn trong vài lần thử đầu tiên, vì vậy hãy thử nghiệm đầu tiên trên một dự án không quan trọng ...


17

Tôi có một tình huống kỳ lạ mà không git cleanhoặc không git resethoạt động. Tôi phải xóa tệp xung đột khỏi git indexbằng cách sử dụng tập lệnh sau trên mỗi tệp không bị theo dõi:

git rm [file]

Sau đó tôi có thể kéo tốt.


16

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


14

Mặc dù câu hỏi ban đầu, các câu trả lời hàng đầu có thể gây ra vấn đề cho những người gặp vấn đề tương tự, nhưng không muốn mất các tệp cục bộ của họ. Ví dụ: xem ý kiến ​​của Al-Punk và crizCraig.

Phiên bản sau đây cam kết các thay đổi cục bộ của bạn thành một nhánh tạm thời ( tmp), kiểm tra nhánh ban đầu (mà tôi giả sử là master) và hợp nhất các bản cập nhật. Bạn có thể làm điều này với stash, nhưng tôi thấy việc sử dụng phương pháp hợp nhất / hợp nhất thường dễ dàng hơn.

git checkout -b tmp
git add *; git commit -am "my temporary files"
git checkout master

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

nơi chúng tôi giả định các kho lưu trữ khácorigin master.


13

Bốn lệnh này làm việc cho tôi.

git reset --hard HEAD
git checkout origin/master
git branch -D master
git checkout -b master

Để kiểm tra / kéo sau khi thực hiện các lệnh này

git pull origin master

Tôi đã thử rất nhiều nhưng cuối cùng cũng thành công với những lệnh này.


2
"Git chi nhánh -D master" xóa chi nhánh. vì vậy hãy cẩn thận với nó Tôi thích sử dụng "git checkout origin / master -b <new Branch name>" để tạo một nhánh mới với một tên mới và bạn đã thực hiện cần 3,4 dòng. Cũng nên sử dụng "git clean -f".
Chand Priyankara

13

Cứ làm đi

git fetch origin branchname
git checkout -f origin/branchname // This will overwrite ONLY new included files
git checkout branchname
git merge origin/branchname

Vì vậy, bạn tránh tất cả các tác dụng phụ không mong muốn, như xóa các tệp hoặc thư mục bạn muốn giữ, v.v.


12

Đặt lại chỉ mục và phần đầu thành origin/master, nhưng không đặt lại cây làm việc:

git reset origin/master

Cá nhân tôi thấy điều này là hữu ích nhất. Sau đó nó giữ cây làm việc của bạn để bạn có thể kiểm tra lại. Đối với vấn đề của tôi, tôi đã xóa các tệp tương tự như đã được thêm vào để nó bị kẹt. Lạ, tôi biết.
Jason Sebring

12

Yêu cầu:

  1. Theo dõi những thay đổi cục bộ để không ai ở đây mất chúng.
  2. Làm cho kho lưu trữ cục bộ khớp với kho lưu trữ gốc từ xa.

Giải pháp:

  1. Stash những thay đổi địa phương.
  2. Fetch với một sạch của filethư mục phớt lờ .gitignorehard reset để nguồn gốc .

    git stash --include-untracked
    git fetch --all
    git clean -fdx
    git reset --hard origin/master
    
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.