Как заставить Git "забыть" о файле, который был отслежен, но теперь находится.гитюдного?
есть файл, который отслеживается git, но теперь файл находится на .gitignore список.
однако этот файл продолжает отображаться в git status после редактирования. Как вы заставляете git чтобы совсем забыть об этом?
20 ответов:
.gitignoreпозволит предотвратить неотслеживаемые файлы могут быть добавлены (безadd -f) к набору файлов, отслеживаемых git, однако git будет продолжать отслеживать любые файлы, которые уже отслеживаются.чтобы остановить отслеживание файла, необходимо удалить его из индекса. Это может быть достигнуто с помощью этой команды.
git rm --cached <file>удаление файла из Главной редакции произойдет при следующем коммите.
серия команд ниже удалит все элементы из индекса Git (не из рабочего каталога или локального РЕПО), а затем обновит индекс Git, соблюдая при этом git игнорирует. PS. Index = Cache
первый:
git rm -r --cached . git add .затем:
git commit -am "Remove ignored files"
git update-index делает работу за меня:
git update-index --assume-unchanged <file>Примечание: это решение фактически не зависит от
.gitignoreкак пример только для неотслеживаемый файлы.edit: поскольку этот ответ был опубликован, была создана новая опция, и это следует предпочесть. Вы должны использовать
--skip-worktreeкоторый предназначен для измененных отслеживаемых файлов, которые пользователь больше не хочет фиксировать и сохранять--assume-unchangedдля исполнения, чтобы предотвратить git для проверки состояния больших отслеживаемых файлов. Смотрите https://stackoverflow.com/a/13631525/717372 для более подробной информации...
git ls-files --ignored --exclude-standard -z | xargs -0 git rm --cached git commit -am "Remove ignored files"Это принимает список игнорируемых файлов и удаляет их из индекса, а затем вносятся изменения.
Я всегда использую эту команду, чтобы удалить эти неотслеживаемые файлы. Однострочный, Unix-стиль, чистый вывод:
git ls-files --ignored --exclude-standard | sed 's/.*/"&"/' | xargs git rm -r --cachedон перечисляет все ваши игнорируемые файлы, заменяет каждую выходную строку на строку в кавычках вместо того, чтобы обрабатывать пути с пробелами внутри, и передает все в
git rm -r --cachedчтобы удалить пути / файлы / dirs из индекса.
Если вы не можете
git rmотслеживаемый файл, потому что он может понадобиться другим людям (предупреждение, даже если выgit rm --cached, когда кто-то другой получает это изменение, их файлы будут удалены в их файловой системе). Это часто делается из-за переопределений файла конфигурации, учетных данных аутентификации и т. д. Пожалуйста, посмотрите на https://gist.github.com/1423106 для того, как люди работали вокруг этой проблемы.подведем итоги:
- ваш приложения для игнорируемых файлов конфигурации-высшую.ini и использовать более совершенные файл config.ini (или поочередно, ищите~/.config / myapp.ini, или $MYCONFIGFILE)
- Commit file config-sample.ini и игнорировать файл config.ini, есть скрипт или аналогичная копия файла по мере необходимости, если это необходимо.
- попробуйте использовать gitattributes clean/smudge magic, чтобы применить и удалить изменения для вас, например смазать файл конфигурации в качестве проверки из альтернативной ветви и очистить файл конфигурации как проверка от головы. Это сложный материал, я не рекомендую его для начинающего пользователя.
- сохраните файл конфигурации в ветке развертывания, выделенной для него, которая никогда не объединяется с master. Когда вы хотите развернуть / скомпилировать / протестировать, вы сливаетесь с этой ветвью и получаете этот файл. Это, по сути, грязный / чистый подход, за исключением использования политик слияния людей и дополнительных модулей git.
- Anti-recommentation: не используйте assume-unchanged, это закончится только слезами.
переместить его, зафиксировать, а затем переместить его обратно. Это работало для меня в прошлом. Вероятно, есть более "хитрый" способ добиться этого.
что не сработало для меня
(под Linux), я хотел использовать сообщения здесь предлагая
ls-files --ignored --exclude-standard | xargs git rm -r --cachedподход. Однако (некоторые из) файлов, которые будут удалены, имели встроенную новую строку/LF/\nв их имена. Ни одно из решений:git ls-files --ignored --exclude-standard | xargs -d"\n" git rm --cached git ls-files --ignored --exclude-standard | sed 's/.*/"&"/' | xargs git rm -r --cachedсправиться с этой ситуацией (получаете ошибки о файлах не нашел).
поэтому я предлагаю
git ls-files -z --ignored --exclude-standard | xargs -0 git rm -r --cachedиспользует до ls-files и
Я сделал это с помощью git filter-branch. Точная команда, которую я использовал, была взята из man-страницы:
предупреждение: это приведет к удалению файла из всей вашей истории
git filter-branch --index-filter 'git rm --cached --ignore-unmatch filename' HEADэта команда воссоздаст всю историю фиксации, выполнив
git rmперед каждой фиксацией и так избавится от указанного файла. Не забудьте создать резервную копию перед запуском команды как это будет будут потеряны.
использовать это, когда:
1. Вы хотите, чтобы отследить много файлов, или
2. Вы обновили свой файл gitignore
ссылка на источник: http://www.codeblocq.com/2016/01/Untrack-files-already-added-to-git-repository-based-on-gitignore/
допустим, вы уже добавили/зафиксировали некоторые файлы в свой репозиторий git, а затем добавили их в свой .гитюдного; эти файлы будут по-прежнему присутствовать в ваш индекс репозитория. В этой статье мы увидим, как от них избавиться.
Шаг 1: зафиксируйте все ваши изменения
прежде чем продолжить, убедитесь, что все ваши изменения зафиксированы, включая ваши .файла.gitignore
Шаг 2: Удалите все из репозитория
чтобы очистить РЕПО, используйте:
git rm -r --cached .
- rm это команда удалить
- - r позволит рекурсивный удаление
- - cached будут удалены только файлы из индекса. Ваши файлы все еще будут там.
The
rmкоманда может быть неумолимой. Если вы хотите попробовать то, что он делает заранее, добавить-nили--dry-runфлаг, чтобы проверить вещи.Шаг 3: Re добавить все
git add .Шаг 4: Commit
git commit -m ".gitignore fix"ваш репозиторий чистые :)
нажмите изменения на пульте дистанционного управления, чтобы увидеть изменения действуют и там.
обновить
.gitignorefile-например, добавьте папку, которую вы не хотите отслеживать в.gitignore.
git rm -r --cached .- удалить все отслеживаемые файлы, в том числе разыскиваемые и нежелательные. Ваш код будет в безопасности, пока вы сохранили локально.
git add .– все файлы будут добавлены обратно, за исключением.gitignore.
Hat tip to @AkiraYamamoto для указания нам в правильном направлении.
Я думаю, что, возможно, git не может полностью забыть о файле из-за его концепции (раздел "снимки, а не различия").
эта проблема отсутствует, например, при использовании CVS. CVS хранит информацию в виде списка изменений на основе файлов. Информация для CVS представляет собой набор файлов и изменений, внесенных в каждый файл с течением времени.
но в Git каждый раз, когда вы совершаете или сохраняете состояние своего проекта, он в основном делает снимок того, что все ваши файлы выглядеть в этот момент и сохраняет ссылку на этот снимок. Поэтому, если вы добавили файл один раз, он всегда будет присутствовать в этом снимке.
эти 2 статьи были полезны для меня:
git предположим-без изменений против skip-worktree и как игнорировать изменения в отслеживаемых файлах с Git
исходя из этого я делаю следующее, если файл уже отслеживается:
git update-index --skip-worktree <file>от в этот момент все локальные изменения в этом файле будут проигнорированы и не перейдут на удаленный. Если файл изменяется на удаленном, конфликт произойдет, когда
git pull. Тайник не сработает. Чтобы решить ее, скопируйте содержимое файла в безопасное место и выполните следующие действия:git update-index --no-skip-worktree <file> git stash git pullсодержимое файла будет заменено удаленным содержимым. Вставьте изменения из безопасного места в файл и выполните еще раз:
git update-index --skip-worktree <file>если все, кто работает с проектом, будет выполнять
git update-index --skip-worktree <file>, проблемы сpullдолжен отсутствовать. Это решение подходит для файлов конфигураций, когда каждый разработчик имеет свою собственную конфигурацию проекта.это не очень удобно делать каждый раз, когда файл был изменен на удаленном, но может защитить его от перезаписи удаленным контентом.
переместить или скопировать файл в безопасном месте, так что вы не потеряете его. Затем git rm файл и фиксация. Файл по-прежнему будет отображаться, если вы вернетесь к одному из этих предыдущих коммитов или другой ветви, где он не был удален. Однако во всех последующих коммитах вы больше не увидите этот файл. Если файл находится в Git ignore, вы можете переместить его обратно в папку, и git не увидит его.
ответ от Мэтта страха был самым эффективным ИМХО. Ниже приведен только сценарий PowerShell для тех, кто в windows, чтобы удалить только файлы из своего репозитория git, который соответствует их списку исключений.
# Get files matching exclusionsfrom .gitignore # Excluding comments and empty lines $ignoreFiles = gc .gitignore | ?{$_ -notmatch "#"} | ?{$_ -match "\S"} | % { $ignore = "*" + $_ + "*" (gci -r -i $ignore).FullName } $ignoreFiles = $ignoreFiles| ?{$_ -match "\S"} # Remove each of these file from Git $ignoreFiles | % { git rm $_} git add .
The BFG специально разработан для удаления нежелательных данных, таких как большие файлы или пароли из репозиториев Git, поэтому он имеет простой флаг, который удалит любые большие исторические (не в вашей текущей фиксации) файлы: '-- strip-blobs-bigger-than'
$ java -jar bfg.jar --strip-blobs-bigger-than 100MЕсли вы хотите, чтобы указать файлы по имени, вы можете сделать это:
$ java -jar bfg.jar --delete-files *.mp4BFG 10-1000x быстрее, чем git filter-branch, и, как правило, гораздо проще в использовании-проверьте полное использование инструкции и примеры для более подробной информации.
Источник: https://confluence.atlassian.com/bitbucket/reduce-repository-size-321848262.html
Если вы не хотите использовать CLI и работаете в Windows, очень простое решение-использовать TortoiseGit, Он имеет действие "удалить (сохранить локальный)" в меню, которое отлично работает.
Мне понравился ответ JonBrave, но у меня достаточно грязные рабочие каталоги, которые commit-a немного пугают меня, поэтому вот что я сделал:
git config --глобальный псевдоним.исключить-игнорируется '!ГИТ ЛС-файлы -з --игнорировать --исключить-стандарт | команды xargs -0 ГИТ РМ -Р --кэшированные && Git в ЛС-файлы -з --игнорировать --исключить-стандарт | команды xargs -0 ГИТ этап && Git на сцене .gitignore & & git commit-m "создать gitignore и удалить игнорируемые файлы из индекса"'
ломать его вниз:
git ls-files -z --ignored --exclude-standard | xargs -0 git rm -r --cached git ls-files -z --ignored --exclude-standard | xargs -0 git stage git stage .gitignore git commit -m "new gitignore and remove ignored files from index"
- удалить игнорируемые файлы из индекса
- этап .gitignore и файлы, которые вы только что удалили
- commit
Это больше не проблема в последнем git (v2.17.1 на момент написания статьи).
The
.gitignoreнаконец игнорирует отслеживаемые, но удаленные файлы. Вы можете проверить это для себя, выполнив следующий сценарий. Финалgit statusзаявление должно сообщать "ничего не совершать".# Create empty repo mkdir gitignore-test cd gitignore-test git init # Create a file and commit it echo "hello" > file git add file git commit -m initial # Add the file to gitignore and commit echo "file" > .gitignore git add .gitignore git commit -m gitignore # Remove the file and commit git rm file git commit -m "removed file" # Reintroduce the file and check status. # .gitignore is now respected - status reports "nothing to commit". echo "hello" > file git status
В случае уже совершенного
DS_Store:find . -name .DS_Store -print0 | xargs -0 git rm --ignore-unmatchигнорировать их:
echo ".DS_Store" >> ~/.gitignore_global echo "._.DS_Store" >> ~/.gitignore_global echo "**/.DS_Store" >> ~/.gitignore_global echo "**/._.DS_Store" >> ~/.gitignore_global git config --global core.excludesfile ~/.gitignore_globalнаконец, сделайте коммит!
выполните следующие шаги последовательно, вы будете в порядке.
1.удалить ошибочно добавленные файлы из справочника/хранения. Вы можете использовать команду "rm-r"(для linux) или удалить их, просмотрев каталоги.
2.добавить файлы / каталоги в
gitignoreфайл сейчас и сохраните его.3.сейчас удалить из них git cache С помощью этих команд (если есть несколько каталогов, удалите их один по одному, многократно выпуская эту команду)
git rm -r --cached path-to-those-files4.сейчас do a commit и push используйте эти команды. Это будет удалите эти файлы из git remote и сделать git остановить отслеживание эти файлы.
git add . git commit -m "removed unnecessary files from git" git push origin
Comments