Git удалить файл из фиксации

Обновлено: 05.07.2024

Если вы фиксируете конфиденциальные данные, такие как пароль или ключ SSH, в репозиторий Git, вы можете удалить их из истории. Чтобы полностью удалить ненужные файлы из истории репозитория, вы можете использовать инструмент git filter-repo или инструмент с открытым исходным кодом BFG Repo-Cleaner.

Инструмент git filter-repo и BFG Repo-Cleaner переписывают историю вашего репозитория, что изменяет SHA для существующих коммитов, которые вы изменяете, и любых зависимых коммитов. Измененные SHA фиксации могут повлиять на открытые запросы на вытягивание в вашем репозитории. Мы рекомендуем объединять или закрывать все открытые пулл-реквесты перед удалением файлов из репозитория.

Вы можете удалить файл из последней фиксации с помощью git rm . Информацию об удалении файла, добавленного с последней фиксацией, см. в разделе «О больших файлах на GitHub».

Предупреждение. После того как вы отправили фиксацию на GitHub, вы должны считать, что любые конфиденциальные данные в фиксации скомпрометированы. Если вы зафиксировали пароль, измените его! Если вы зафиксировали ключ, сгенерируйте новый. Удаление скомпрометированных данных не устраняет их первоначальную уязвимость, особенно в существующих клонах или ответвлениях вашего репозитория. Учитывайте эти ограничения при принятии решения о перезаписи истории вашего репозитория.

Очистка файла из истории репозитория

Вы можете удалить файл из истории репозитория с помощью инструмента git filter-repo или инструмента с открытым исходным кодом BFG Repo-Cleaner.

BFG Repo-Cleaner – это инструмент, созданный и поддерживаемый сообществом открытого исходного кода. Это более быстрая и простая альтернатива git filter-branch для удаления нежелательных данных.

Например, чтобы удалить файл с конфиденциальными данными и оставить нетронутым последний коммит, выполните:

Чтобы заменить весь текст, указанный в файле passwords.txt, везде, где он встречается в истории вашего репозитория, выполните:

После удаления конфиденциальных данных необходимо принудительно отправить изменения на GitHub. Принудительное нажатие перезаписывает историю репозитория, что удаляет конфиденциальные данные из истории коммитов. Если вы принудительно отправите запрос, он может перезаписать коммиты, на которых другие люди основывали свою работу.

Полные инструкции по использованию и загрузке см. в документации BFG Repo-Cleaner.

Использование git filter-repo

Предупреждение. Если вы запустите git filter-repo после сохранения изменений, вы не сможете получить свои изменения с помощью других команд хранения. Перед запуском git filter-repo мы рекомендуем удалить все сделанные вами изменения. Чтобы удалить последний набор изменений, которые вы спрятали, запустите git stash show -p | git применить -R . Дополнительные сведения см. в разделе Инструменты Git — хранение и очистка.

Чтобы проиллюстрировать, как работает git filter-repo, мы покажем вам, как удалить файл с конфиденциальными данными из истории вашего репозитория и добавить его в .gitignore, чтобы гарантировать, что он не будет случайно повторно зафиксирован.

Установите последнюю версию инструмента git filter-repo. Вы можете установить git-filter-repo вручную или с помощью менеджера пакетов. Например, чтобы установить инструмент вместе с HomeBrew, используйте команду brew install.

Для получения дополнительной информации см. INSTALL.md в репозитории newren/git-filter-repo.

Если у вас еще нет локальной копии репозитория с конфиденциальными данными в его истории, клонируйте репозиторий на свой локальный компьютер.

Перейдите в рабочий каталог репозитория.

Выполните следующую команду, заменив PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA на путь к файлу, который вы хотите удалить, а не только на его имя. Эти аргументы будут:

  • Заставить Git обрабатывать, но не извлекать всю историю каждой ветки и тега
  • Удалить указанный файл, а также любые пустые коммиты, сгенерированные в результате.
  • Удалите некоторые конфигурации, такие как удаленный URL, сохраненный в файле .git/config. Вы можете заранее создать резервную копию этого файла для последующего восстановления.
  • Перезаписать существующие теги

Примечание. Если файл с конфиденциальными данными раньше существовал по каким-либо другим путям (из-за того, что он был перемещен или переименован), вы должны выполнить эту команду и по этим путям.

Добавьте файл с конфиденциальными данными в .gitignore, чтобы случайно не зафиксировать его снова.

Перепроверьте, что вы удалили все, что хотели, из истории вашего репозитория, и что все ваши ветки извлечены.

Чтобы удалить конфиденциальный файл из выпусков с тегами, вам также потребуется принудительно отправить теги Git:

Полное удаление данных с GitHub

После использования инструмента BFG или git filter-repo для удаления конфиденциальных данных и отправки изменений на GitHub необходимо выполнить еще несколько шагов, чтобы полностью удалить данные с GitHub.

Обратитесь в службу поддержки GitHub и попросите их удалить кешированные представления и ссылки на конфиденциальные данные в запросах на вытягивание на GitHub. Укажите название репозитория и/или ссылку на фиксацию, которую нужно удалить.

Скажите своим соавторам перебазировать, не объединять любые ветки, которые они создали из вашей старой (испорченной) истории репозитория. Один коммит слияния может восстановить часть или всю испорченную историю, которую вы только что потрудились очистить.

По прошествии некоторого времени, когда вы уверены, что инструмент BFG / git filter-repo не имеет непреднамеренных побочных эффектов, вы можете принудительно разыменовать все объекты в вашем локальном репозитории и собрать мусор с помощью следующих команд (используя Git 1.8.5 или новее):

Примечание. Этого также можно добиться, отправив отфильтрованную историю в новый или пустой репозиторий, а затем создав новый клон с GitHub.

Предотвращение случайных коммитов в будущем

Есть несколько простых приемов, позволяющих избежать совершения нежелательных действий:

  • Используйте визуальную программу, например GitHub Desktop или gitk, для фиксации изменений. Визуальные программы обычно упрощают просмотр того, какие именно файлы будут добавлены, удалены и изменены при каждой фиксации.
  • Избегайте универсальных команд git add . и git commit -a в командной строке — вместо этого используйте git add filename и git rm filename для отдельных промежуточных файлов.
  • Используйте git add --interactive для индивидуального просмотра и внесения изменений в каждый файл.
  • Используйте команду git diff --cached для просмотра изменений, подготовленных для фиксации. Это именно тот diff, который git commit создаст, если вы не используете флаг -a.

Помогите нам сделать эти документы лучше!

Все документы GitHub имеют открытый исходный код. Видите что-то неправильное или непонятное? Отправьте запрос на вытягивание.

Иногда вы готовите свои файлы для фиксации и хотите удалить файлы из фиксации, чтобы внести дополнительные изменения. В этом руководстве мы покажем, как эффективно удалять файлы из ваших коммитов Git, обсуждая некоторые сценарии.

Удаление файла из предыдущей фиксации

Давайте обсудим наш первый сценарий. Вот что вам нужно сделать:

Удалить файл и оставить на рабочем столе

Если вы хотите только удалить файл из предыдущей фиксации и оставить его на диске, может помочь команда git reset:

Сброс файлов

Затем вы можете сбросить файлы, которые вам больше не нужны, чтобы удалить их из коммита:

Совершение

Вы можете снова выполнить git commit и даже использовать то же самое сообщение фиксации:

Удаление файла из последней фиксации

Во втором сценарии обсуждается ситуация, когда это ваша последняя фиксация, и вы хотите удалить файл.

Удаление файла из индекса

Вы можете использовать команду git rm, чтобы удалить файл из промежуточной области. Опция --cached указывает, что файл нужно удалить из кэшированной области:

Фиксация изменений

После внесения изменений вы можете снова зафиксировать их с помощью параметра --amend:

Проверка файлов

Если работа завершена, вы можете проверить, удаляются ли файлы из репозитория и не появляются ли в новом файле:

Команда git reset

Команда git reset используется для отмены изменений. Он передает указатель ссылки HEAD и указатель ссылки текущей ветки.

Аргумент --soft обновляет ссылочные указатели и останавливает сброс. Однако это не влияет на промежуточный индекс и рабочий каталог. Мягкий сброс сбрасывает только историю коммитов. По умолчанию он вызывается с HEAD в качестве целевого коммита.

Команда git rm

Команда git rm удаляет определенные файлы или набор файлов из репозитория git. Основная функция git rm — удаление отслеживаемых файлов из промежуточной области (также называемой индексом). git rm также используется для удаления файлов как из промежуточного индекса, так и из рабочего каталога. Но файл нельзя удалить только из рабочего каталога. Однако git rm не удаляет ветки.

Команда git commit

Команда git commit сохраняет все текущие промежуточные изменения. Коммиты предназначены для фиксации текущего состояния проекта. Зафиксированные моментальные снимки считаются безопасными версиями проекта, поскольку Git спрашивает перед их изменением. Команда git add продвигает изменения в проекте, которые затем будут сохранены в коммите перед выполнением команды git commit. Опция --amend изменяет последний коммит. Поэтапные модификации добавляются к предыдущему коммиту. Этот аргумент открывает настроенный текстовый редактор системы и изменяет указанное ранее сообщение фиксации.

Установка и настройка

Получение и создание проектов

Базовый снимок

Ветвление и слияние

Обмен проектами и их обновление

Осмотр и сравнение

Исправление

Отладка

Электронная почта

Внешние системы

Администратор сервера

Руководства

Администрирование

Связные команды

Проверьте свою версию git, запустив

git-rm - Удалить файлы из рабочего дерева и из индекса

ОБЗОР

ОПИСАНИЕ

Удалить файлы, соответствующие пути, из индекса или из рабочего дерева и индекса. git rm не удалит файл только из вашего рабочего каталога. (Нет возможности удалить файл только из рабочего дерева и при этом сохранить его в индексе; используйте /bin/rm, если вы хотите это сделать.) Удаляемые файлы должны быть идентичны вершине ветви, и никакие обновления их содержимого не могут быть размещены в индексе, хотя это поведение по умолчанию можно переопределить с помощью параметра -f. Если задан параметр --cached, подготовленное содержимое должно соответствовать либо концу ветки, либо файлу на диске, что позволяет удалить файл только из индекса. Когда используются разреженные проверки (см. git-sparse-checkout[1]), git rm удалит только пути в шаблонах разреженных проверок.

ВАРИАНТЫ

Файлы для удаления. Начальное имя каталога (например, dir для удаления dir/file1 и dir/file2 ) может быть задано для удаления всех файлов в каталоге и рекурсивно всех подкаталогов, но для этого требуется явный указанный параметр -r.

Команда удаляет только те пути, которые известны Git.

Подстановка файлов соответствует границам каталогов. Таким образом, при наличии двух каталогов d и d2 существует разница между использованием git rm 'd*' и git rm 'd/*' , так как первый также удалит весь каталог d2 .

Подробнее см. в записи pathspec в gitglossary[7].

Переопределить проверку актуальности.

На самом деле не удаляйте файлы. Вместо этого просто покажите, существуют ли они в индексе и в противном случае были бы удалены командой.

Разрешить рекурсивное удаление, если задано начальное имя каталога.

Этот параметр можно использовать для отделения параметров командной строки от списка файлов (полезно, когда имена файлов могут быть ошибочно приняты за параметры командной строки).

Используйте этот параметр, чтобы отменить постановку и удалить пути только из индекса. Файлы рабочего дерева, независимо от того, изменены они или нет, останутся нетронутыми.

Выйти с нулевым статусом, даже если не найдено ни одного файла.

Разрешить обновление записей индекса за пределами конуса разреженной проверки. Обычно git rm отказывается обновлять записи индекса, пути которых не соответствуют конусу разреженной проверки. См. git-sparse-checkout[1] для получения дополнительной информации.

git rm обычно выводит одну строку (в виде команды rm) для каждого удаленного файла. Этот параметр подавляет этот вывод.

Pathspec передается вместо аргументов командной строки. Если точно - то используется стандартный ввод. Элементы Pathspec разделяются символами LF или CR/LF. Элементы Pathspec можно заключать в кавычки, как описано для переменной конфигурации core.quotePath (см. git-config[1]). См. также --pathspec-file-nul и global --literal-pathspecs .

Имеет смысл только с параметром --pathspec-from-file . Элементы Pathspec разделяются символом NUL, а все остальные символы воспринимаются буквально (включая символы новой строки и кавычки).

УДАЛЕНИЕ ФАЙЛОВ, ИСЧЕЗНУВШИХ ИЗ ФАЙЛОВОЙ СИСТЕМЫ

У git rm нет возможности удалить из индекса только те пути, которые исчезли из файловой системы. Однако, в зависимости от варианта использования, есть несколько способов сделать это.

Использование «git commit -a»

Если вы предполагаете, что ваша следующая фиксация должна записывать все изменения отслеживаемых файлов в рабочем дереве и записывать все удаления файлов, которые были удалены из рабочего дерева с помощью rm (в отличие от git rm ), используйте git commit -a , так как он автоматически заметит и запишет все удаления. Вы также можете получить аналогичный эффект без фиксации, используя git add -u .

Использование «git add -A»

Принимая новый код для ветки поставщика, вы, вероятно, захотите записать как удаление путей, так и добавление новых путей, а также изменения существующих путей.

Обычно сначала необходимо удалить все отслеживаемые файлы из рабочего дерева с помощью этой команды:

а затем распакуйте новый код в рабочем дереве. В качестве альтернативы вы можете rsync внести изменения в рабочее дерево.

После этого проще всего записать все удаления, добавления и изменения в рабочем дереве:

Другие способы

Если все, что вы действительно хотите сделать, это удалить из индекса файлы, которых больше нет в рабочем дереве (возможно, из-за того, что ваше рабочее дерево грязное и вы не можете использовать git commit -a ), используйте следующую команду :

ПОДМОДУЛИ

Только подмодули, использующие git-файл (что означает, что они были клонированы с помощью Git версии 1.7.8 или новее), будут удалены из рабочего дерева, поскольку их репозиторий находится внутри каталога .git суперпроекта. Если подмодуль (или один из вложенных в него) по-прежнему использует каталог .git, git rm переместит каталог git подмодулей в каталог git суперпроектов, чтобы защитить историю подмодуля. Если он существует, то подмодуль. раздел в файле gitmodules[5] также будет удален, а этот файл будет помещен в промежуточное состояние (если только не используются --cached или -n).

Подмодуль считается обновленным, если HEAD совпадает с записанным в индексе, никакие отслеживаемые файлы не изменяются и в рабочем дереве подмодулей нет неотслеживаемых файлов, которые не игнорируются. Игнорируемые файлы считаются расходными и не останавливают удаление рабочего дерева подмодуля.

Если вы хотите удалить только локальное извлечение подмодуля из вашего рабочего дерева без фиксации удаления, используйте вместо этого git-submodule[1] deinit. Также см. gitsubmodules[7] для получения подробной информации об удалении подмодуля.

ПРИМЕРЫ

Удаляет из индекса все файлы *.txt, находящиеся в каталоге Documentation и любых его подкаталогах.

Обратите внимание, что в этом примере звездочка * взята из оболочки; это позволяет Git, а не оболочке, расширять пути к файлам и подкаталогам в каталоге Documentation/.

Позже я обнаружил, что в фиксацию по ошибке был добавлен файл.

Как удалить файл из последней фиксации?


33 Ответа 33

Я думаю, что другие ответы здесь неверны, потому что речь идет о перемещении ошибочно зафиксированных файлов обратно в промежуточную область из предыдущей фиксации без отмены внесенных в них изменений. Это можно сделать, как предложил Паритош Сингх:

Затем сбросьте ненужные файлы, чтобы исключить их из коммита (по-старому):

Обратите внимание, что начиная с Git 2.23.0 можно (по-новому):

Теперь зафиксируйте снова, вы даже можете повторно использовать одно и то же сообщение фиксации:

Спасибо за это. Стоит добавить, что если вы уже отправили свою предыдущую (неправильную) фиксацию и теперь пытаетесь git отправить исправление в свое репо, он будет жаловаться, что обновления были отклонены, потому что кончик вашей текущей ветки находится позади ее удаленного аналога. . Если вы уверены, что хотите отправить их (например, это ваша вилка), вы можете использовать параметр -f для принудительного нажатия, например. git push origin master -f . (Не делайте этого с вышестоящим репозиторием, из которого другие получают данные)

@PabloFernandez в верхней части всех ответов есть три вкладки, которые позволяют вам управлять порядком ответов: активные, самые старые и голоса. Я предполагаю, что у вас установлен самый старый. Переключите его на голосование, даже если принятый ответ все равно будет вверху, этот ответ будет вторым.

Я много знал о git reset, но хотел найти способ повлиять на существующий коммит "на месте". Я только что узнал о git commit -C . Так что для меня то, что я хочу, это ваш точный рецепт с еще одним шагом, «новая фиксация снова», изложенная как git commit -C [хеш оригинальной фиксации HEAD с первого шага] .

Не забудьте сделать фактическую фиксацию, а не исправление. Если вы это сделаете, это будет изменение предыдущего коммита. - упс

ВНИМАНИЕ! Если вы хотите только удалить файл из предыдущей фиксации и оставить его на диске, прочитайте ответ juzzlin чуть выше.

Если это ваша последняя фиксация и вы хотите полностью удалить файл из локального и удаленного репозитория, вы можете:

  1. удалить файл git rm
  2. зафиксировать с флагом изменения: git commit --amend

Флаг исправления указывает git на повторную фиксацию, но "объединяет" (не в смысле слияния двух веток) эту фиксацию с последней фиксацией.

Как указано в комментариях, использование git rm здесь похоже на использование самой команды rm!

Предупреждение для тех, кто просматривает этот ответ: убедитесь, что вы хотите УДАЛИТЬ файл (как в Gone Gone Gone!), а не просто удалить его из списка фиксации.

Чтобы добавить к тому, что говорят другие (и чтобы было легче помнить, что не следует делать этого, если вы действительно этого не хотите): rm в команде git делает то, что делает сам rm!

Обратите внимание, что файлы по-прежнему можно восстановить, если вы передумаете, коммит перед git commit --amend все еще существует и его можно найти, например, с помощью git reflog . Так что все не так плохо, как предполагают другие комментарии.

Все существующие ответы говорят об удалении ненужных файлов из последнего коммита.

Если вы хотите удалить ненужные файлы из старой фиксации (даже отправленной) и не хотите создавать новую фиксацию, которая не нужна из-за действия:

  1. Найдите фиксацию, которой должен соответствовать файл, используя ;

git log --graph --decorate --oneline

вы можете сделать это несколько раз, если хотите удалить много файлов.

git commit -am "удалить ненужные файлы"

Найдите commit_id коммита, в котором файлы были добавлены по ошибке, скажем, здесь "35c23c2"

git rebase 35c23c2~1 -i // обратите внимание: необходимо "~1"

Эта команда открывает редактор в соответствии с вашими настройками. По умолчанию это vim. Если вы хотите изменить глобальный редактор git, используйте;

git config --global core.editor

Переместите последний коммит, который должен быть "удалить ненужные файлы", на следующую строку неправильного коммита ("35c23c2" в нашем случае) и установите команду как fixup :

Вы должны быть в порядке после сохранения файла.

Если у вас, к сожалению, возникают конфликты, вам придется решать их вручную.

Если вы действительно хотите удалить файлы из репозитория (а не из файловой системы), а не просто вернуть их к предыдущей версии, вместо шага 1 выполните git rm --cached .

Этот процесс можно упростить, добавив --fixup=35c23c2 в команду git commit. Это автоматически настроит фиксацию как исправление требуемой фиксации, поэтому вам не нужно будет указывать ее в перебазировании. Кроме того, если вы добавите --autosquash к команде git rebase, git автоматически переместит вашу фиксацию в правильное место, поэтому вам не нужно ничего делать в интерактивной перебазировке — просто сохраните результат (что означает, что вы не даже нужен флаг -i, хотя я все равно предпочитаю его использовать, чтобы убедиться, что все выглядит так, как я ожидаю).

Как указано в принятом ответе, вы можете сделать это, сбросив всю фиксацию. Но это довольно жесткий подход.
Более простой способ сделать это — сохранить фиксацию и просто удалить из нее измененные файлы.

Сброс git возьмет файл, каким он был в предыдущем коммите, и поместит его в индекс. Файл в рабочем каталоге остается нетронутым.
Затем коммит git зафиксирует и включит индекс в текущий коммит.

По сути, это берет версию файла, которая была в предыдущей фиксации, и добавляет ее в текущую фиксацию. Это не приводит к чистому изменению, поэтому файл фактически удаляется из фиксации.

@ThatsAMora действительно :-). Мне интересно, был ли этот вопрос объединен с другим, и поэтому я его не видел. А может я просто слепой. В любом случае, я думаю, что склонен оставить его, поскольку на основании голосов он кажется более популярным (возможно, люди предпочитают краткий и прямой ответ).

Конечно, оставьте это! :) У нас явно была правильная идея, и цель - помочь. Я думаю, что слияние — хорошая теория.

Хороший ответ, но есть один момент, на который вам, возможно, следует обратить внимание: если у вас есть какие-либо добавленные или удаленные файлы, которые в настоящее время находятся на стадии промежуточного хранения, они будут добавлены в фиксацию с помощью команды git commit --amend --no-edit. Не уверен, почему это так, но меня это просто укусило.

Если вы не отправили изменения на сервер, вы можете использовать

Он сбросит все изменения и вернется к одной фиксации назад

Если вы отправили свои изменения, следуйте инструкциям @CharlesB


не имеет большого значения, но потому что OP хочет удалить ненужный файл из последней фиксации, и он просто сбрасывается до состояния перед фиксацией. все равно придется повторить коммит.

Если удалить файл с помощью rm, он будет удален!

Вы всегда добавляете к коммиту в git, а не удаляете, поэтому в этом случае верните файл в состояние, в котором он был до первого коммита (это может быть действие удаления 'rm', если файл новый ), а затем повторно зафиксируйте, и файл будет отправлен.

Чтобы вернуть файл в предыдущее состояние:

или вернуть его в состояние на удаленном HEAD:

затем измените фиксацию, и вы должны обнаружить, что файл исчез из списка (а не удален с вашего диска!)

Я объясню вам на примере.
Пусть A, B, C будут 3 последовательными фиксациями. Фиксация B содержит файл, который не должен быть зафиксирован.


Если конкретный файл отсутствует в последнем или предыдущем коммите, это самый элегантный способ. Я бы даже сказал, что это самый элегантный способ вообще. Мне нравится интерактивное перемещение.

Это лучший способ изменить последнюю фиксацию, которая не была отправлена. Это сбросит изменения в одном файле, эффективно удалив этот файл из последней фиксации.

Следующее удалит только тот файл, который вы планировали, о чем просил OP.

Вы увидите примерно следующее.

Изменения, которые нужно зафиксировать: (используйте "git reset HEAD . ", чтобы отменить стадию)

изменено: /путь/к/файлу

Изменения, не подготовленные для фиксации: (используйте "git add . ", чтобы обновить то, что будет зафиксировано) (используйте "git checkout -- . ", чтобы отменить изменения в рабочем каталоге)

modified: /path/to/file

< /цитата>
  • "Изменения для фиксации" – это предыдущая версия файла перед фиксацией. Это будет выглядеть как удаление, если файл никогда не существовал. Если вы зафиксируете это изменение, появится ревизия, которая отменит изменение файла в вашей ветке.
  • "Изменения, не подготовленные для фиксации" – это зафиксированное вами изменение и текущее состояние файла.

На этом этапе вы можете делать с файлом все, что хотите, например, сбросить его до другой версии.

Когда вы будете готовы зафиксировать:

или (если у вас есть какие-то другие изменения, которые вы пока не хотите фиксировать)


Ответ juzzlin великолепен, но слишком сложно отменить всю фиксацию, если вы хотите удалить только одну. Удаление всего коммита может вызвать проблемы, если у вас есть незафиксированные изменения в файлах в этом коммите, которые вы не хотите потерять.

Вы можете просто попробовать.

и создайте новую фиксацию.

Однако есть классная программа "gitkraken". что упрощает работу с git.


И просто обратите внимание: после этого вы должны выполнить git commit --amend, чтобы обновить удаление файла в вашем последнем коммите; и после этого вы можете проверить, действительно ли он был удален, с помощью git log -1 --stat

оставит вам локальный файл. Если вам также не нужен файл локально, вы можете пропустить опцию --cached.

Если вся работа выполняется в вашей локальной ветке, вам нужно сохранить файл в более позднем коммите, и, как и в случае с чистой историей, я думаю, что более простой способ сделать это может быть:

и вы сможете легко завершить перебазирование без необходимости запоминать более сложные команды или сообщения фиксации или вводить что-либо еще.

Это работает для меня. Я предполагаю, что если вы хотите добавить файлы обратно в микс, просто используйте git add -A или git add . и они вернулись.

Использование git GUI может упростить удаление файла из предыдущей фиксации.

Предполагая, что это не общая ветка и вы не против переписать историю, запустите:

Вы можете снять отметку с ошибочно зафиксированного файла, а затем нажать "Зафиксировать".

введите здесь описание изображения

Файл будет удален из фиксации, но останется на диске. Таким образом, если вы сняли отметку с файла после его ошибочного добавления, он будет отображаться в вашем списке неотслеживаемых файлов (и если вы сняли отметку с файла после его ошибочного изменения, он будет отображаться в ваших изменениях, не подготовленных для фиксации).

Спасибо! Я столкнулся с проблемой (ошибкой?), когда была добавлена ​​папка, содержащая репозиторий .git, и все обычные команды удаления не работали. Это однако помогло. Это было несколько коммитов назад, я сначала использовал git rebase -i HEAD~4, а затем запустил вашу команду, чтобы открыть редактор. Еще одно примечание: параметр «Unstaging» можно найти в меню «Commit».

Самое простое решение. Самый простой для запоминания. И гораздо менее подвержен ошибкам, чем использование git reset --soft HEAD^ (с учетом --soft arg), за которым следует git commit -c ORIG_HEAD (а не --amend, который все портит).

спасибо, в моем последнем коммите было 3 бинарных объекта, и отправка длилась вечность. Ваш ответ помог мне удалить 3 объекта.

Если вы хотите сохранить свой коммит (возможно, вы уже потратили некоторое время на написание подробного сообщения о коммите и не хотите его потерять), и хотите удалить файл только из коммита, а не из репозитория целиком :

Просто хотел дополнить главный ответ, так как мне пришлось запустить дополнительную команду:

Выполните последовательность следующих команд:


Я пытался выполнить эти шаги и вижу эту ошибку: не удалось отправить некоторые ссылки на 'git. ' Чтобы предотвратить потерю истории, обновления без быстрой перемотки вперед были отклонены. Объедините удаленные изменения (например, «git pull») перед повторной отправкой. Дополнительные сведения см. в разделе «Примечание о быстрой перемотке вперед» в «git push --help». (после git pull у меня такие же изменения)

Это означает, что состояние вашего удаленного репозитория изменилось, пока вы выполняли свою локальную работу. И после 'git pull' ваши локальные изменения должны быть объединены с удаленными, вот и все. Конечно, ваши изменения должны остаться.

Если вы хотите удалить файлы из предыдущих коммитов, используйте фильтры

Если вы видите эту ошибку:

Невозможно создать новую резервную копию. Предыдущая резервная копия уже существует в refs/original/ Принудительно перезаписать резервную копию с помощью -f

Просто удалите резервные копии refs из локального репозитория


Обратите внимание, что в случае существующей резервной копии сообщение об ошибке четко указывает решение: добавьте «-f», как в git filter-branch -f [. так далее. ] . Нет необходимости вручную удалять ссылки.

Это отменит последнюю фиксацию в локальных репозиториях и переместит все обратно в рабочую область, как перед выполнением фиксации. Затем просто используйте любой инструмент пользовательского интерфейса Git как обычно (например, TortoiseGit, Git UI, Git Extensions.), чтобы удалить файлы, которые мы не хотим фиксировать, а затем снова выполните фиксацию.


Что-то, что сработало для меня, но я все еще думаю, что должно быть лучшее решение:

Просто оставьте изменение, которое вы хотите отменить, в другом коммите, проверьте другие

git reset --soft HEAD^ возвращает вашу фиксацию, и когда вы набираете git status , она говорит вам, что делать:

У меня была та же проблема, когда у меня были изменения в локальной ветке, где я хотел вернуть только один файл. Что сработало для меня, так это -

(feature/target_branch ниже содержит все мои изменения, включая те, которые я хотел отменить для определенного файла)

(origin/feature/target_branch – это удаленная ветвь, в которую я хочу отправить изменения)

(feature/staging – это моя временная промежуточная ветвь, в которую я буду добавлять все нужные изменения, за исключением изменений в этом файле)

Создать локальную ветку из моего источника/функции/целевой_ветки, назвав ее функцией/промежуточной ветвью

Объединил мою рабочую локальную ветку feature/target_branch с функциональной/промежуточной веткой

Проверил функцию/постановку, затем git reset --soft ORIG_HEAD (Теперь все изменения функции/постановки будут подготовлены, но не зафиксированы.)

Отменено размещение файла, который я ранее зарегистрировал, с ненужными изменениями

Исходящая ветвь для функции/постановки изменена на origin/feature/target_branch

Зафиксировал остальные поэтапные изменения и передал их вверх по течению в мою удаленную origin/feature/target_branch

Читайте также: