Видаліть файл із сховища Git, не видаляючи його з локальної файлової системи


3043

Моя початкова комісія містила деякі файли журналів. Я додав *logдо свого .gitignore, і тепер я хочу видалити файли журналів зі свого сховища.

git rm mylogfile.log

видалить файл із сховища, але також видалить його з локальної файлової системи.

Як я можу видалити цей файл із репо, не видаляючи свою локальну копію файлу?



14
Варто відзначити, що відповідь, яка найбільше сприймається, є небезпечною для деяких. Якщо ви використовуєте віддалений репо, ніж тоді, коли ви натискаєте локальну, тоді витягніть в інше місце ті файли, які ви видалили лише з git, БУДУТЬСЯ . Про це йдеться в одній з відповідей, але не коментується.
RichieHH

Відповіді:


4348

З файлу man :

Коли --cachedзадано, поетапний вміст повинен відповідати або кінчику гілки, або файлу на диску, що дозволяє видалити файл із простого індексу.

Отже, для одного файлу:

git rm --cached mylogfile.log

і для одного каталогу:

git rm --cached -r mydirectory

150
Легко пропускається, тому що це не так пояснюється, як svn rm --keep-local.
Мартін

114
Але як зберегти файли на віддалених серверах? Це зберігає мій локальний, але якщо я натискаю і тягну з іншого сервера, файл видаляється. Я також додав файл .gitignore для файлу, але він все одно буде видалений
spankmaster79

6
Це все ще видаляє файли, git pullякщо ви стоїте за фіксацією післяgit rm
Петро Пеллер

9
Варто зауважити, що, виконавши команду у відповіді, потрібно використовувати git commit -m "Commit message"і git push. Якщо у вас є якісь інші поетапні зміни (зверніться до git status), вони також будуть здійснені в цей час.
Сінджай

9
Оскільки це найбільш прийнятна відповідь і не робить, те, що просять, я скажу, що я роблю. Я використовую команду git rm --cached mylogfile.logі видаляю файл із сховища. Щоб уникнути втрати файлу на продуктивній системі, я роблю резервну копію файлу і тягну за цим. Файл видаляється, як згадувалося раніше, і його потрібно скопіювати назад із резервної копії. Це досить болісно, ​​але я не знайшов кращого рішення для цієї проблеми.
Marcel Grolms

275

Щоб видалити всю папку з репо (як файли Resharper), виконайте це:

git rm -r --cached folderName

Я створив декілька файлів перерозподілу, і не хотів, щоб вони зберігалися для інших користувачів проекту.


13
Лише додана примітка для майбутніх відвідувачів: не використовуйте графічний інтерфейс, щоб "синхронізувати" комісію назад до репо. Це перетягне файли назад у місцеве репо. Ви повинні зробити a, Git Push repo branchщоб фактично видалити файли з пульта.
RubberDuck

211

Ви також можете видалити файли з сховища на основі .gitignore, не видаляючи їх з локальної файлової системи:

git rm --cached `git ls-files -i -X .gitignore`

Або, як варіант, у Windows Powershell:

git rm --cached $(git ls-files -i -X .gitignore)

7
Не працює в Windows. git ls-files -i -X ​​.gitignore працює, але я не знаю, як надіслати файли до 'git rm'. Ви знаєте, як це зробити?
Ерік Z

17
Працює в Windows, якщо ви використовуєте Git Bash замість cmd-консолі
Andreas Zita

17
Люблю це. Працювало, за винятком того, що у мене були деякі файли, які мали пробіли у імені файлу. Я змінив рішення тут це: git ls-files -i -X .gitignore | xargs -I{} git rm --cached "{}". Будь ласка, подумайте про те, щоб змінити або додати це рішення до відповіді тут, тому що це чудовий інструмент, щоб ...
mpettis

Я не намагався, але це слід перевірити, чи видалить він також файли, на зразок .gitkeepяких зберігається порожня папка у сховищі. Напр. .gitignoreмістити папку uploadsі репо змушений вести облік .gitkeep. Видаливши все з репо, під uploadsним також буде видалено .gitkeep.
Володимир Вуканак

Ця пропозиція чудово спрацювала в powershell: git rm --cached $ (git ls-files -i -X ​​.gitignore)
geekandglitter

89

Відповідно до мого відповіді тут: /programming/6313126/how-to-remove-a-directory-in-my-github-repository

Щоб видалити папку / каталог або файл лише з сховища git, а не з локального, спробуйте 3 прості дії.


Кроки для видалення каталогу

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

Крок ігнорувати цю папку в наступних вчинках

Щоб ігнорувати цю папку з наступних комісій, зробіть один файл у корені з іменем .gitignore та вставте ім'я цієї папки в нього. Ви можете покласти скільки завгодно

Файл .gitignore буде виглядати приблизно так

/FolderName

видалити каталог


@gaurav радий, що це допомогло!
eirenaios

69

Крім того, якщо ви скористалися конфіденційними даними (наприклад, файлом, що містить паролі), слід повністю видалити його з історії сховища. Ось посібник, що пояснює, як це зробити: http://help.github.com/remove-sensitive-data/


13
Ця відповідь повинна містити необхідні команди для виконання цього завдання замість посилання на інший веб-сайт.
Флоріан Лемайтр

1
Я також зазначу, що я знайшов використання інструменту для чищення git bfg repo легше та швидше.
Закуповував Слуг

64

Більш загальне рішення:

  1. Редагувати .gitignoreфайл.

    ECHO mylogfile.log >> .gitignore

  2. Видаліть усі елементи з індексу.

    git rm -r -f --cached .

  3. Перебудувати індекс.

    git add .

  4. Зробіть нові зобов’язання

    git commit -m "Removed mylogfile.log"


2
Чи дійсно це видалить файл?
Mr_and_Mrs_D

6
Від GitHub? НІ. Якщо ви вже натиснули на github, він не видалить його з сайту. Але він оновить ваше місцеве сховище git.
mAsT3RpEE

5
Коментар, який ви видалили, фактично був усунутий :) Проблема з рішенням rm --cashedполягає в тому, що він з часом видалить файл, коли один витягне - так? І це не те, чого люди хочуть сказати "Видаліть файл із сховища, не видаляючи його з локальної файлової системи ". Тепер, чому рішення, прийняте вище, було прийнято поза мною - напевно, ОП працювала сама і ніколи не тягнула? Данно. Я розумію, github "колись штовхнув завжди туди" issue ofc
Mr_and_Mrs_D

Я не думаю, що існує 100% рішення, якщо ви не запитаєте самого github. Поки що дотримуйтесь цього. Скопіюйте файл, додайте до gitignore, зробіть фактичний git rm -r, здійснити, натиснути, відновити файл. Чи вдалося вам знайти інше рішення?
mAsT3RpEE

9
Моя проблема не в github - це те, що файл насправді буде видалено з колег, коли вони потягнуть . Я не хочу, щоб файл видалявся. Це викликало у мене величезні проблеми в минулому. Тож мені було цікаво, чи дійсно є рішення, яке дійсно не видаляє файл. Дивіться також коментар по МНН прийнятий відповідь: stackoverflow.com/questions/1143796 / ...
Mr_and_Mrs_D

24

Git дозволяє ігнорувати ці файли, вважаючи, що вони незмінні. Це робиться шляхом запуску git update-index --assume-unchanged path/to/file.txtкоманди. Після позначення файлу як такого, git повністю ігнорує будь-які зміни у цьому файлі; вони не з’являться під час запуску статусу git або git diff, і ніколи не будуть вчинені.

https://help.github.com/articles/ignoring-files )

Отже, не видаляти його, а ігнорувати зміни до нього назавжди. Я думаю, що це працює лише локально, тому співробітники все ще можуть бачити зміни, якщо вони не виконають таку ж команду, як вище. (Однак це все ще потрібно перевірити.)

Примітка. Це питання не відповідає безпосередньо на питання, а базується на подальших запитаннях у коментарях інших відповідей.


2
Гм, я це роблю, але я бачу, що файл можна перезаписати, якщо хтось інший внесе зміни до нього на репо.
AlxVallejo

17

Якщо ви хочете просто зняти файл, а не видалити з локального та віддаленого репо, скористайтеся цією командою:

git update-index --assume-unchanged  file_name_with_path

2
Хоча це хороша відповідь, важливо зауважити, що це не "відстежує" файл у тому сенсі, що люди зазвичай використовують це слово разом із Git, де незавершений файл - це той, який відсутній в історії сховища і ніколи не був . Ця відповідь робить це зберігати файл у сховищі, але заважає Git помічати, що в ньому внесені зміни. Це має деякі суттєві відмінності - найголовніше, що файл все ще присутній для інших, і якщо хтось ще вносить зміни до нього, і ви потягнете, ваша локальна копія може бути перезаписана без підтвердження.
Сорен Бьорнстад

8

Наведені вище відповіді не працювали для мене. Я використовував filter-branchдля видалення всіх скоєних файлів.

Видаліть файл із сховища git за допомогою:

git filter-branch --tree-filter 'rm  file'

Видаліть папку з сховища git за допомогою:

git filter-branch --tree-filter 'rm -rf directory'

Це видаляє каталог або файл з усіх комітів.

Ви можете вказати комісію за допомогою:

git filter-branch --tree-filter 'rm -rf directory' HEAD

Або діапазон:

git filter-branch --tree-filter 'rm -rf vendor/gems' t49dse..HEAD

Щоб натиснути все на віддалений, ви можете:

git push origin master --force

2
Це в поєднанні з git rm -r --cached NAMEтрюком, щоб вилучити його з локального git repo і не допустити впливу на тих, хто витягне пізніше (видаливши історію файлу чи каталогу з git.)
notbad.jpeg

1
Це переписує історію git, і вам потрібно буде натиснути - примусово після, це трохи виходить за рамки питання, який я думаю. На відомому загальнодоступному репо не можна просто змінити такий рядок історії, як кожен, хто вже клонував репо, отримає проблеми при витягуванні.
Гійом Перро

0

Ігноруйте файли, видаліть файли з git, оновіть git (для видалення).

Примітка: ця інформація не стосується історії конфіденційної інформації.

Цей процес, безумовно, потребує певного виконання того, що відбувається з git. З часом, здобувши це, я навчився робити такі процеси, як:

1) Ігноруйте файли

  • Додайте або оновіть проект, .gitignoreщоб ігнорувати їх - у багатьох випадках, таких як ваш, батьківський каталог, наприклад, log/буде використовуватися регулярний вираз.
  • здійснити та натиснути цю .gitignoreзміну файлу (не впевнений, чи потрібен тобі поштовх, не шкода, якщо буде зроблено)

2) Видаліть файли з git (тільки).

  • Тепер видаліть файли з git (тільки) за допомогою git remove --cached some_dir/
  • Перевірте, чи вони все ще залишаються локально (вони повинні!).

3) Додайте та введіть ці зміни (по суті це зміна для "додавання" видалення матеріалів, незважаючи на інакше заплутану команду "додати"!)

  • git add .
  • git commit -m"removal"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.