git rm - Fat: pathspec không khớp với bất kỳ tệp nào


87

Tôi đã tình cờ thêm hơn 9000 ảnh vào thư mục dự án của mình. Và cam kết chúng. Sau đó, xóa chúng khỏi đĩa. Cam kết.

Bây giờ tôi cố gắng đẩy các thay đổi lên máy chủ git. Nhưng nó mất quá nhiều thời gian và cố gắng gửi 12 Gb dữ liệu.

Tôi đã kiểm tra kích thước tệp trên đĩa và thấy rằng .gitthư mục thực sự chiếm 12 Gb.

Làm cách nào để xóa ảnh khỏi đó? Tôi đã thử git rm, nhưng không thành công:

❯ git rm public/photos
fatal: pathspec 'public/photos' did not match any files

Bởi vì tôi đã xóa tất cả chúng khỏi đĩa, nhưng chúng vẫn còn trong .gitthư mục.

Tôi đã cố gắng thêm public/photosvào .gitignore:

public/photos/
*.zip

Nhưng không có kết quả. Tất nhiên tôi có thể ghi hard reset headlại khoảnh khắc khi tôi không có quá nhiều ảnh rác trong dự án của mình. Nhưng kể từ thời điểm đó, tôi đã cam kết nhiều lần và thực hiện rất nhiều thay đổi trong mã.

Câu trả lời:


86

Trong trường hợp của bạn, hãy sử dụng git filter-branchthay vì git rm.

git rm sẽ xóa các tệp theo nghĩa là chúng sẽ không được git theo dõi nữa, nhưng điều đó không xóa các đối tượng cam kết cũ tương ứng với các hình ảnh đó, và vì vậy bạn vẫn sẽ gặp khó khăn với việc đẩy các cam kết trước đó tương ứng với 12GB hình ảnh.

Mặt git filter-branchkhác, cũng có thể xóa các tệp đó khỏi tất cả các cam kết trước đó, do đó không cần phải đẩy bất kỳ tệp nào trong số đó.

  1. Sử dụng lệnh

    git filter-branch --force --index-filter \
      'git rm -r --cached --ignore-unmatch public/photos' \
      --prune-empty --tag-name-filter cat -- --all
    
  2. Sau khi nhánh bộ lọc hoàn tất, hãy xác minh rằng không có tệp ngoài ý muốn nào bị mất.

  3. Bây giờ hãy thêm quy tắc .gitignore

    echo public/photos >> .gitignore
    git add .gitignore && git commit -m "ignore rule for photos"
    
  4. Bây giờ hãy đẩy mạnh

    git push -f origin branch
    

Kiểm tra cái này , cái nàycái này để được trợ giúp thêm. Để an toàn hơn, tôi khuyên bạn nên tạo một bản sao lưu của kho lưu trữ trên hệ thống của bạn trước khi tiếp tục các hướng dẫn này.

Đối với thông báo lỗi gốc của bạn, nó đang xảy ra bởi vì bạn đã bỏ theo dõi chúng bằng cách sử dụng git rmvà do đó git đang phàn nàn vì nó không thể xóa tệp mà nó không theo dõi. Đọc thêm về điều này ở đây .


2
Này, tôi đang gặp vấn đề tương tự nhưng khi nhập lệnh ở bước 1, tôi gặp lỗi: death: bad revise '--prune-blank'. Có manh mối nào không?
kevin

@kevin xin lỗi, đã bỏ lỡ bình luận này. Bạn có thể chạy nó mà không cần cờ đó. Việc cắt tỉa sẽ loại bỏ bất kỳ đối tượng cam kết trống nào.
mu 無

1
Không nên dòng này git add .gitignore && commit -m "ignore rule for photos"đượcgit add .gitignore && git commit -m "ignore rule for photos"
Clone

@Clone vâng, lẽ ra là như vậy, đã sửa nó ngay bây giờ :)
mu 無

1
Đây là một câu trả lời cực kỳ tuyệt vời. Đã khắc phục sự cố mà tôi đã gặp phải với repo của mình trong vài năm. Cảm ơn!
Moshe

18

Một câu trả lời rất đơn giản là.

Bước 1:

Trước hết hãy thêm các tệp chưa được theo dõi của bạn mà bạn muốn xóa:

sử dụng git add .hoặc git add <filename>.

Bước 2:

Sau đó, xóa chúng một cách dễ dàng bằng lệnh git rm -f <filename>tại đây rm = remove and -f = forcely.


điều này sẽ không thực hiện những gì OP muốn, đó là xóa các tệp có trong các cam kết trước đó. Bạn cần sử dụng git filter-branchnhư đã đề cập ở những nơi khác.
Simon Stevens

9

Bước 1

Thêm (các) tên tệp vào .gitignoretệp của bạn .

Bước 2

git filter-branch --force --index-filter \
    'git rm -r --cached --ignore-unmatch YOURFILE' \
    --prune-empty --tag-name-filter cat -- --all

Bước 3

git push -f origin branch

Xin gửi lời cảm ơn sâu sắc tới @mu.


7
... tôi luôn nghĩ git khó hơn nó nên điều này chứng minh điều đó. Không có cách nào mà bất kỳ ai thậm chí có thể nhớ được sự tồn tại của hầu hết các lệnh git, chứ đừng nói đến các cờ và câu lệnh của chúng. Mô hình Git có ý nghĩa và nó hoạt động cho đến khi bạn tuân theo quy trình đơn giản, và ngay khi bạn gặp khó khăn, bạn sẽ gặp khó khăn.
Muhammad Umer

2
Đây là giải pháp phù hợp với tôi, tôi cần--ignore-unmatch
guhur


1

Chuỗi này hoạt động trong trường hợp của tôi:

  1. git rm -r WebApplication/packages

Đã có hộp thoại git xác nhận. Bạn nên chọn tùy chọn "y".

  1. git commit -m "blabla"
  2. git push -f origin <ur_branch>

0
git stash 

đã thực hiện công việc, Nó khôi phục các tệp mà tôi đã xóa bằng cách sử dụng rmthay thế git rm.

Trước tiên, tôi đã kiểm tra băm cuối cùng, nhưng tôi không tin rằng nó là bắt buộc.


0

Để xóa tệp đã theo dõi và đã cam kết cũ khỏi git, bạn có thể sử dụng lệnh dưới đây. Ở đây trong trường hợp của tôi, tôi muốn gỡ theo dõi và xóa tất cả tệp khỏi distthư mục.

git filter-branch --force --index-filter 'git rm -r --cached --ignore-unmatch dist' --tag-name-filter cat -- --all

Sau đó, bạn cần thêm nó vào của bạn .gitignoređể nó không bị theo dõi thêm.


-1

Tôi có một thư mục trùng lặp (~ web / web) và nó đã loại bỏ bản sao lồng nhau khi tôi chạy rm -rf webtrong thư mục web đầu tiên.


Lấy làm tiếc! Chắc tôi đã đọc nhầm câu hỏi. Tôi nghĩ đó là những gì mục tiêu là
ccsinsf
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.