Xóa thư mục khỏi kho lưu trữ từ xa sau khi thêm chúng vào .gitignore


599

Tôi cam kết và đẩy một số thư mục để github. Sau đó, tôi đã thay đổi .gitignoretập tin thêm một thư mục nên được bỏ qua. Mọi thứ đều hoạt động tốt, nhưng thư mục (hiện bị bỏ qua) vẫn nằm trên github.

Làm cách nào để xóa thư mục đó khỏi github và lịch sử kho lưu trữ?


Câu trả lời:


1067

Các quy tắc trong .gitignoretệp của bạn chỉ áp dụng cho các tệp không bị theo dõi. Vì các tệp trong thư mục đó đã được cam kết trong kho lưu trữ của bạn, bạn phải hủy kích hoạt chúng, tạo một cam kết và đẩy tệp đó đến GitHub:

git rm -r --cached some-directory
git commit -m 'Remove the now ignored directory "some-directory"'
git push origin master

Bạn không thể xóa tệp khỏi lịch sử của mình mà không viết lại lịch sử của kho lưu trữ - bạn không nên làm điều này nếu có ai khác đang làm việc với kho lưu trữ của bạn hoặc bạn đang sử dụng nó từ nhiều máy tính. Nếu bạn vẫn muốn làm điều đó, bạn có thể sử dụng git filter-branchđể viết lại lịch sử - có một hướng dẫn hữu ích cho vấn đề đó ở đây .

Ngoài ra, lưu ý đầu ra từ git rm -r --cached some-directorysẽ giống như:

rm 'some-directory/product/cache/1/small_image/130x130/small_image.jpg'
rm 'some-directory/product/cache/1/small_image/135x/small_image.jpg'
rm 'some-directory/.htaccess'
rm 'some-directory/logo.jpg'

Đây rmlà phản hồi từ git về kho lưu trữ; các tập tin vẫn còn trong thư mục làm việc.


3
Nếu có người khác kéo, các tệp hiện bị bỏ qua sẽ bị xóa cho họ hoặc không bị ảnh hưởng?
Martin Konicek

3
@Martin Konicek: nếu người dùng đang thực hiện các thay đổi đó không có sửa đổi đối với các tệp đó, thì chúng sẽ bị xóa.
Đánh dấu Longair

@MarkLongair Cái gì -r--cached. Cảm ơn.
Labanino

13
@Labanino: -rcó nghĩa là đệ quy, cần thiết nếu bạn đang thực hiện toàn bộ thư mục. --cachedghi đè hành vi bình thường của git là xóa chúng khỏi thư mục làm việc và sắp xếp việc xóa để thực hiện và làm cho git chỉ hoạt động trên khu vực tổ chức sẵn sàng để thực hiện. Đó là cách bạn nói với git mà bạn muốn giữ các bản sao cục bộ của tệp.
entheh

2
Điều này hoạt động tốt, nhưng trước tiên tôi phải làm: git reset name_of_fileđể những gì được mô tả ở trên hoạt động
Edvard Haugland

248

Tôi làm việc này:

git rm --cached `git ls-files -i --exclude-from=.gitignore` 
git commit -m 'Removed all files that are in the .gitignore' 
git push origin master

Việc này sẽ xóa tất cả các tệp / thư mục trong git của bạn bỏ qua, tiết kiệm bạn phải chọn từng tệp theo cách thủ công


Điều này dường như đã ngừng làm việc cho tôi, bây giờ tôi làm:

 git rm -r --cached . 
 git add .
 git commit -m 'Removed all files that are in the .gitignore' 
 git push origin master

4
Cảm ơn, điều này đã giúp tôi rất nhiều! Nếu bạn đang sử dụng windows powershell, bạn có thể làmforeach ($i in iex 'git ls-files -i --exclude-from=.gitignore') { git rm --cached $i }
Matthew

10
Đã thử cách tiếp cận thứ hai của bạn, nó đã xóa tất cả các tệp khỏi git cục bộ của tôi!
artnikpro

2
Tôi nghĩ rằng bạn phải điều hướng đến thư mục con và làm điều đó. Sửa tôi nếu tôi sai.

Vậy hôm nay chúng ta đã học được gì? "Đừng chạy mã ngẫu nhiên bạn tìm thấy trên Stack Overflow!"
Jonathan Landrum

49

Theo câu trả lời của tôi ở đây: Làm thế nào để xóa một thư mục khỏi kho git?

Để xóa thư mục / thư mục chỉ từ kho git chứ không xóa khỏi cục bộ, hãy thử 3 bước đơn giản.


Các bước để loại bỏ thư mục

git rm -r --cached FolderName
git commit -m "Removed folder from repository"
git push origin master

Các bước để bỏ qua thư mục đó trong các lần xác nhận tiếp theo

Để bỏ qua thư mục đó từ các lần xác nhận tiếp theo, hãy tạo một tệp trong thư mục gốc có tên .gitignore và đặt tên thư mục đó vào đó. Bạn có thể đặt bao nhiêu tùy thích

tập tin .gitignore sẽ trông như thế này

/FolderName

xóa thư mục


1
Điều này thật đúng với gì mà tôi đã tìm kiếm. Cảm ơn :)
Rohit Singh

Tôi rất vui vì nó đã giúp @Rohit Singh
eirenaios

9

Câu trả lời đầu tiên của Blundell không hiệu quả với tôi. Tuy nhiên nó cho tôi thấy cách đúng đắn. Tôi đã làm điều tương tự như thế này:

> for i in `git ls-files -i --exclude-from=.gitignore`; do git rm --cached $i; done
> git commit -m 'Removed all files that are in the .gitignore'
> git push origin master

Tôi khuyên bạn nên kiểm tra các tệp sẽ bị xóa trước bằng cách chạy câu lệnh dưới đây:

git ls-files -i --exclude-from=.gitignore

Tôi đã sử dụng tệp .gitignore mặc định cho visual studio và tôi nhận thấy rằng nó đang xóa tất cả các thư mục log và bin trong dự án không phải là hành động của tôi.


5

Lưu ý: Giải pháp này chỉ hoạt động với Github Desktop GUI .

Bằng cách sử dụng Github Desktop GUI, nó rất đơn giản.

  1. Tạm thời chuyển thư mục sang vị trí khác (ra khỏi thư mục dự án).

  2. Chỉnh sửa .gitignoretệp của bạn và xóa mục nhập thư mục sẽ xóa kho lưu trữ chính trên trang github.

  3. Cam kết và Đồng bộ thư mục dự án.

  4. Di chuyển lại thư mục vào thư mục dự án

  5. Chỉnh sửa lại .gitignoretập tin.

Đó là tất cả.


5

Câu trả lời từ Blundell sẽ có hiệu quả, nhưng vì một số lý do kỳ quái, nó đã không làm với tôi. Trước tiên tôi phải đặt tên tệp được xuất ra bởi lệnh đầu tiên vào một tệp và sau đó lặp qua tệp đó và xóa từng tệp một.

git ls-files -i --exclude-from=.gitignore > to_remove.txt
while read line; do `git rm -r --cached "$line"`; done < to_remove.txt
rm to_remove.txt
git commit -m 'Removed all files that are in the .gitignore' 
git push origin master

4

Phương pháp này áp dụng hành vi .gitignore tiêu chuẩn và không yêu cầu chỉ định thủ công các tệp cần bỏ qua .

Không thể sử dụng --exclude-from=.gitignore nữa: / - Đây là phương pháp được cập nhật:

Lời khuyên chung: bắt đầu với một repo sạch - mọi thứ đã cam kết, không có gì đang chờ xử lý trong thư mục hoặc chỉ mục làm việc và tạo bản sao lưu !

#commit up-to-date .gitignore (if not already existing)
#this command must be run on each branch
git add .gitignore
git commit -m "Create .gitignore"

#apply standard git ignore behavior only to current index, not working directory (--cached)
#if this command returns nothing, ensure /.git/info/exclude AND/OR .gitignore exist
#this command must be run on each branch
git ls-files -z --ignored --exclude-standard | xargs -0 git rm --cached

#optionally add anything to the index that was previously ignored but now shouldn't be:
git add *

#commit again
#optionally use the --amend flag to merge this commit with the previous one instead of creating 2 commits.

git commit -m "re-applied modified .gitignore"

#other devs who pull after this commit is pushed will see the  newly-.gitignored files DELETED

Nếu bạn cũng cần xóa các tệp mới bị bỏ qua khỏi lịch sử cam kết của chi nhánh hoặc nếu bạn không muốn các tệp mới bị bỏ qua bị xóa khỏi các lần kéo trong tương lai , hãy xem câu trả lời này .


0

Nếu bạn đang làm việc từ PowerShell, hãy thử làm như sau một lệnh.

PS MyRepo> git filter-branch --force --index-filter
>> "git rm --cached --ignore-unmatch -r .\\\path\\\to\\\directory"
>> --prune-empty --tag-name-filter cat -- --all

Sau đó , git push --force --all.

Tài liệu: https://git-scm.com/docs/git-filter-branch


Sử dụng git filter-branchkhác với sử dụng git rmnhư thế nào? Ban đầu tôi nghĩ mình phải sử dụng một phiên bản git filter-branchnhưng hầu hết các ý kiến ​​ở đây đều khuyên bạn nên sử dụng git rm. Từ những gì tôi hiểu git rmchỉ loại bỏ nó khỏi thư mục và chỉ mục làm việc hiện tại. Nhưng nếu nó được thêm nhiều lần xác nhận trước đó, nó vẫn sẽ nằm trong kho lưu trữ.
alpha_989

Đúng. git rmsẽ xóa tệp khỏi cam kết mới nhất trong tương lai. git filter-branchcho phép chúng tôi loại bỏ nó khỏi toàn bộ lịch sử. Xem thêm: help.github.com/articles/ trên
Shaun Luttin
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.