Cách xóa nhiều tệp đã xóa trong kho Git


236

Tôi đã xóa một số tập tin và trạng thái git hiển thị như dưới đây.

Tôi đã cam kết và thúc đẩy.

GitHub vẫn hiển thị các tệp đã bị xóa trong kho lưu trữ. Làm cách nào để xóa các tệp trong kho GitHub?

# On branch master
# Changes not staged for commit:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   deleted:    modules/welcome/language/english/kaimonokago_lang.php
#   deleted:    modules/welcome/language/french/kaimonokago_lang.php
#   deleted:    modules/welcome/language/german/kaimonokago_lang.php
#   deleted:    modules/welcome/language/norwegian/kaimonokago_lang.php

Nếu tôi sử dụng git rm, nó cung cấp cho sau đây.

usage: git rm [options] [--] <file>...

-n, --dry-run         dry run
-q, --quiet           do not list removed files
--cached              only remove from the index
-f, --force           override the up-to-date check
-r                    allow recursive removal
--ignore-unmatch      exit with a zero status even if nothing matched


Câu trả lời:


637
git add -u 

cập nhật tất cả các thay đổi của bạn


31
Hoạt động một sự quyến rũ. Khi bạn thấy một cái gì đó như "git status | sed -n '/ ^ # * đã xóa: / s /// p' | xargs git rm" như một giải pháp được đề xuất cho một yêu cầu đơn giản nhưng thường xuyên như vậy thì bạn biết một giải pháp tốt hơn là, hoặc sẽ sớm, xung quanh góc.
arcseldon

đơn giản là tốt hơn, điều này thực sự tiện dụng theo cách "bash"
castiel

1
Tác giả hỏi làm thế nào để loại bỏ các tập tin, tại sao thêm các tập tin là câu trả lời chính xác?
kelin

3
@kelin: từ git docs ( git-scm.com/docs/git-add ): "-u --update Cập nhật chỉ mục khi nó đã có mục nhập khớp với <pathspec>. Điều này sẽ xóa cũng như sửa đổi các mục nhập chỉ mục thành khớp với cây làm việc, nhưng không thêm tệp mới. Nếu không có <pathspec> được đưa ra khi sử dụng tùy chọn -u, tất cả các tệp được theo dõi trong toàn bộ cây làm việc đều được cập nhật (các phiên bản cũ của Git được sử dụng để giới hạn cập nhật vào thư mục hiện tại và thư mục con của nó). "
HEDMON

92

Hãy rất thận trọng về git rm .; nó có thể loại bỏ nhiều hơn bạn muốn. Tất nhiên, bạn có thể phục hồi, nhưng đơn giản hơn là không phải làm như vậy.

Đơn giản nhất sẽ là:

git rm modules/welcome/language/english/kaimonokago_lang.php \
       modules/welcome/language/french/kaimonokago_lang.php \
       modules/welcome/language/german/kaimonokago_lang.php \
       modules/welcome/language/norwegian/kaimonokago_lang.php

Bạn không thể sử dụng ký tự đại diện vì các tệp không tồn tại, nhưng bạn có thể sử dụng (ít nhất là trong Bash):

git rm modules/welcome/language/{english,french,german,norwegian}/kaimonokago_lang.php

Hoặc xem xét:

git status | sed -n '/^# *deleted:/s///p' | xargs git rm

Cái này lấy đầu ra của git status, không in bất cứ thứ gì theo mặc định ( sed -n), nhưng trên các dòng bắt đầu # deleted:, nó sẽ loại bỏ #deleted:và in những gì còn lại; xargstập hợp các đối số và cung cấp cho chúng một git rmlệnh. Điều này hoạt động cho bất kỳ số lượng tệp bất kể sự giống nhau (hoặc không giống nhau) trong tên.


6
Bạn có thể sử dụng các ký tự đại diện (mặc dù bạn có thể cần phải thoát chúng) và git sẽ khớp với các đường dẫn trong chỉ mục, không chỉ các đường dẫn trong cây làm việc, vì vậy không có vấn đề gì khi chúng không tồn tại trên hệ thống tệp.
Ben James

109
git diff --diff-filter=D --name-only -z | xargs -0 git rmlà một cách tiếp cận đáng tin cậy hơn là cố gắng phân tích git statustheo hướng người dùng và không được đảm bảo để ổn định so với các phiên bản trong tương lai.
CB Bailey

@Charles: điều đó chắc chắn tốt hơn, nhưng nó đòi hỏi khá nhiều kiến ​​thức về những lựa chọn có sẵn git diff(mà tôi không có, không có nhu cầu trước đó). Cảm ơn!
Jonathan Leffler

8
Lưu ý rằng cũng có "git ls-files - đã xóa"
Petr Gladkikh

1
vì vậy, git ls-files --deleted | xargs git rmđã lừa tôi
fiacobelli

50

Một phiên bản khác cho câu trả lời của ByScripts là

git rm $(git ls-files --deleted)

Điều này sẽ CHỈ xóa các tập tin bị xóa khỏi git.

Nó cũng có thể được sử dụng để thêm các tệp sửa đổi CHỈ.

git add $(git ls-files --modified)

Các lệnh này cũng hoạt động trên gitbash cho windows.


2
Vô giá, git ls-filesvới trạng thái bị xóa hoặc sửa đổi là rất hữu ích.
Mario Peshev

1
Hành vi 'git add --update (or -u)'không có đối số đường dẫn từ thư mục con của cây sẽ thay đổi trong Git 2.0 và không nên được sử dụng nữa. Để thêm nội dung cho toàn bộ cây, hãy chạy: git add --update :/ (hoặc git add -u: /) Để giới hạn lệnh trong thư mục hiện tại, hãy chạy: git add --update . (hoặc git add -u.) Với phiên bản Git hiện tại, lệnh bị giới hạn ở thư mục hiện tại
Ans

1
Bất kỳ ý tưởng làm thế nào để xử lý các đường dẫn với không gian trong đó? Ví dụ : src/my spaced directory/myfile. Điều này có thể được xử lý riêng lẻ nhưng làm thế nào nó có thể được xử lý bằng cách sử dụng các lệnh trong câu trả lời này?
Muhammad Gelbana

35

Cập nhật tất cả các thay đổi bạn đã thực hiện:

git add -u

Các tập tin bị xóa nên thay đổi từ không theo giai đoạn (thường là màu đỏ) sang giai đoạn (màu xanh lá cây). Sau đó cam kết xóa các tệp đã xóa:

git commit -m "note"

1
Xứng đáng với huy hiệu dân túy.
Giăng

1
Đây là giải pháp tốt nhất. Không có hack script, không có quá trình dài, chỉ là một cờ để nói với git để cập nhật chỉ mục của nó một cách kỹ lưỡng.
Ron Dahlgren

Xuất sắc! Cứu tôi khỏi phải gõ 20+ đường dẫn tệp. Cảm ơn!
allardbrain

12

Giải pháp tốt nhất nếu bạn không quan tâm đến việc sắp xếp các tệp đã sửa đổi là sử dụng git add -unhư đã nói bởi mshameers và / hoặc pb2q .

Nếu bạn chỉ muốn xóa các tệp đã xóa, nhưng không xử lý bất kỳ tệp nào đã sửa đổi, tôi nghĩ bạn nên sử dụng ls-filesđối số với --deletedtùy chọn (không cần sử dụng regex hoặc các đối số / tùy chọn phức tạp khác):

git ls-files --deleted | xargs git rm

1
git add -Agiải quyết vấn đề này ... chỉ trong trường hợp bất kỳ ai muốn biết trong tương lai. kiểm tra câu trả lời dưới đây
Ja8zyjits

8

Có, git rm <filename>sẽ xử lý trạng thái đã xóa của một tệp, trong đó <filename>có thể là mẫu toàn cục:

$ git rm modules/welcome/language/*/kaimonokago_lang.php
rm modules/welcome/language/english/kaimonokago_lang.php
rm modules/welcome/language/french/kaimonokago_lang.php
rm modules/welcome/language/german/kaimonokago_lang.php
rm modules/welcome/language/norwegian/kaimonokago_lang.php

$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       deleted:    modules/welcome/language/english/kaimonokago_lang.php
#       ...

Sau đó, bạn có thể cam kết.

git commit -a sẽ làm điều này trong một lần, nếu bạn muốn.

Bạn cũng có thể sử dụng git add -uđể xử lý tất cả các thay đổi, bao gồm tất cả các tệp đã xóa, sau đó cam kết.


vậy rm (dừng hoàn toàn) xóa chúng cùng một lúc?
shin

vậy chỉ cần git rm sẽ loại bỏ tất cả cùng một lúc?
shin

1
Bạn có thể sử dụng mẫu kiểu toàn cầu để xóa nhiều tệp; Tôi cập nhật câu trả lời của tôi để hiển thị một ví dụ.
Ben James

5
Dường như đó git add -uchính xác là những gì chúng tôi đang tìm kiếm - nếu bạn thực hiện nhiều thao tác xóa, sau đó muốn thực hiện tất cả các thao tác xóa, đó dường như là cách dễ nhất và 'tiêu chuẩn' nhất (nghĩa là không có các trường hợp cụ thể theo trường hợp cụ thể hoặc phân tích cú pháp phức tạp xargs). Có một lý do nào chúng ta không muốn sử dụng nó, ngoài thực tế là nó bổ sung tất cả các thay đổi cùng một lúc?
trisweb

7

Khi tôi có rất nhiều tệp tôi đã xóa chưa được xác nhận để cam kết, bạn có thể gửi git rmtất cả chúng trong một chương trình với:

for i in `git status | grep deleted | awk '{print $3}'`; do git rm $i; done

Như người trả lời câu hỏi đã đề cập, hãy cẩn thận với git rm.


5

Thử cái này:

 git rm `git ls-files -d`

Điều này đã giải quyết vấn đề dàn dựng của tôi chỉ xóa các tập lệnh (sử dụng bash)
Mariano Argañaraz

3

Bạn có thể dùng

git commit -m "remove files" -a
git push

Sau khi bạn đã xóa các tập tin bằng tay.


1
Hoặc giống hệt nhưng ngắn gọn hơn: git commit -am "xóa tệp"
BradChesney79

3

Bạn có thể tạo tập lệnh shell sẽ xóa tất cả các tệp của bạn khi chạy:

git status | grep deleted | awk '{print "git rm " $3;}' > ../remove.sh

Kịch bản được tạo là remove.shvà nó chứa danh sách đầy đủ các git rmlệnh.


2
git status | sed 's/^#\s*deleted:\s*//' | sed 's/^#.*//' | xargs git rm -rf


2

Nếu bạn muốn xóa tất cả chúng bằng cách sử dụng "git rm". Đây là những gì tôi làm:

git ls-files --deleted -z | xargs -0 git rm

Truy vấn này liệt kê tất cả các tệp đã bị xóa và xóa chúng khỏi kho git của bạn. Hy vọng nó giúp.


1

Chức năng sạch được tích hợp cũng có thể hữu ích ...

git clean -fd

1
Điều này chỉ áp dụng cho các tập tin chưa được theo dõi.
Elijah Lynn

1

Tôi gặp vấn đề về các tập tin ma xuất hiện trong repo của mình sau khi tôi xóa chúng và bắt gặp lệnh gọn gàng này!

git add -A

Về cơ bản, nó giống git add -avà được git add -ukết hợp, nhưng nó phân biệt chữ hoa chữ thường. Tôi đã nhận được nó từ liên kết tuyệt vời này ( liên kết này trỏ đến phiên bản trên archive.org ngay bây giờ, vì bản gốc đã được chuyển đổi thành trang spam / lừa đảo kể từ tháng 6 năm 2016)


0

Dưới đây là cách phát hiện các tệp đã bị xóa và giai đoạn xóa chúng như là một phần của cam kết tiếp theo. Tất cả các giải pháp về chủ đề này có giá trị khác nhau. Giải pháp này dưới đây đặc biệt giải quyết vấn đề tên tệp có khoảng trắng trong đó.

git status --porcelain | awk '/^.D .*$/ {print $0}' | sed 's/.D \(.*\)/\1/' | tr -d '"' | xargs -I {} git rm '{}'

đảm bảo bạn kiểm tra điều này với tùy chọn --dry-run của git trước khi chạy nó bằng cách sau:

git status --porcelain | awk '/^.D .*$/ {print $0}' | sed 's/.D \(.*\)/\1/' | tr -d '"' | xargs -I {} git rm --dry-run '{}'

giải trình:

git status --porcelain

Điều này in ra một cái gì đó như D "/ đường dẫn đến thư mục / đường dẫn đến tệp" chỉ xảy ra khi có khoảng trắng trong tên đường dẫn

awk '/^.D .*$/ {print $0}'

chỉ khớp các dòng bắt đầu bằng "D"

sed 's/ D \(.*\)/\1/'

xóa "D" khỏi mặt trước của mỗi chuỗi

tr -d '"'

xóa dấu ngoặc kép, nếu có

xargs -I {} git rm '{}'

định nghĩa các biến tên tệp là {} chạy tên tệp theo git rm được đặt trong các dấu ngoặc đơn để đảm bảo rằng nó hỗ trợ tên tệp có dấu cách.

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.