Как отменить действие команды git add на файл
Перейти к содержимому

Как отменить действие команды git add на файл

  • автор:

2.4 Основы Git — Операции отмены

В любой момент вам может потребоваться что-либо отменить. Здесь мы рассмотрим несколько основных способов отмены сделанных изменений. Будьте осторожны, не все операции отмены в свою очередь можно отменить! Это одна из редких областей Git, где неверными действиями можно необратимо удалить результаты своей работы.

Отмена может потребоваться, если вы сделали коммит слишком рано, например, забыв добавить какие-то файлы или комментарий к коммиту. Если вы хотите переделать коммит — внесите необходимые изменения, добавьте их в индекс и сделайте коммит ещё раз, указав параметр —amend :

$ git commit --amend

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

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

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

$ git commit -m 'Initial commit' $ git add forgotten_file $ git commit --amend

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

Примечание

Очень важно понимать, что когда вы вносите правки в последний коммит, вы не столько исправляете его, сколько заменяете новым, который полностью его перезаписывает. В результате всё выглядит так, будто первоначальный коммит никогда не существовал, а так же он больше не появится в истории вашего репозитория.

Очевидно, смысл изменения коммитов в добавлении незначительных правок в последние коммиты и, при этом, в избежании засорения истории сообщениями вида «Ой, забыл добавить файл» или «Исправление грамматической ошибки».

Отмена индексации файла

Следующие два раздела демонстрируют как работать с индексом и изменениями в рабочем каталоге. Радует, что команда, которой вы определяете состояние этих областей, также подсказывает вам как отменять изменения в них. Например, вы изменили два файла и хотите добавить их в разные коммиты, но случайно выполнили команду git add * и добавили в индекс оба. Как исключить из индекса один из них? Команда git status напомнит вам:

$ git add * $ git status On branch master Changes to be committed: (use "git reset HEAD . " to unstage) renamed: README.md -> README modified: CONTRIBUTING.md

Прямо под текстом «Changes to be committed» говорится: используйте git reset HEAD …​ для исключения из индекса. Давайте последуем этому совету и отменим индексирование файла CONTRIBUTING.md :

$ git reset HEAD CONTRIBUTING.md Unstaged changes after reset: M CONTRIBUTING.md $ git status On branch master Changes to be committed: (use "git reset HEAD . " to unstage) renamed: README.md -> README Changes not staged for commit: (use "git add . " to update what will be committed) (use "git checkout -- . " to discard changes in working directory) modified: CONTRIBUTING.md

Команда выглядит несколько странно, но — работает! Файл CONTRIBUTING.md изменен, но больше не добавлен в индекс.

Примечание

Команда git reset может быть опасной если вызвать её с параметром —hard . В приведённом примере файл не был затронут, следовательно команда относительно безопасна.

На текущий момент этот магический вызов — всё, что вам нужно знать о команде git reset . Мы рассмотрим в деталях что именно делает reset и как с её помощью делать действительно интересные вещи в разделе Раскрытие тайн reset главы 7.

Отмена изменений в файле

Что делать, если вы поняли, что не хотите сохранять свои изменения файла CONTRIBUTING.md ? Как можно просто отменить изменения в нём — вернуть к тому состоянию, которое было в последнем коммите (или к начальному после клонирования, или ещё как-то полученному)? Нам повезло, что git status подсказывает и это тоже.

В выводе команды из последнего примера список изменений выглядит примерно так:

Changes not staged for commit: (use "git add . " to update what will be committed) (use "git checkout -- . " to discard changes in working directory) modified: CONTRIBUTING.md

Здесь явно сказано как отменить существующие изменения. Давайте так и сделаем:

$ git checkout -- CONTRIBUTING.md $ git status On branch master Changes to be committed: (use "git reset HEAD . " to unstage) renamed: README.md -> README

Как видите, откат изменений выполнен.

Важно понимать, что git checkout — — опасная команда. Все локальные изменения в файле пропадут — Git просто заменит его версией из последнего коммита. Ни в коем случае не используйте эту команду, если вы не уверены, что изменения в файле вам не нужны.

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

Помните, всё что попало в коммит почти всегда Git может восстановить. Можно восстановить даже коммиты из веток, которые были удалены, или коммиты, перезаписанные параметром —amend (см. Восстановление данных). Но всё, что не было включено в коммит и потеряно — скорее всего, потеряно навсегда.

Отмена действий с помощью git restore

Git версии 2.23.0 представил новую команду: git restore . По сути, это альтернатива git reset, которую мы только что рассмотрели. Начиная с версии 2.23.0, Git будет использовать git restore вместо git reset для многих операций отмены.

Давайте проследим наши шаги и отменим действия с помощью git restore вместо git reset .

Отмена индексации файла с помощью git restore

В следующих двух разделах показано, как работать с индексом и изменениями рабочей копии с помощью git restore . Приятно то, что команда, которую вы используете для определения состояния этих двух областей, также напоминает вам, как отменить изменения в них. Например, предположим, что вы изменили два файла и хотите зафиксировать их как два отдельных изменения, но случайно набираете git add * и индексируете их оба. Как вы можете убрать из индекса один из двух? Команда git status напоминает вам:

$ git add * $ git status On branch master Changes to be committed: (use "git restore --staged . " to unstage) modified: CONTRIBUTING.md renamed: README.md -> README

Прямо под текстом «Changes to be committed», написано использовать git restore —staged …​ для отмены индексации файла. Итак, давайте воспользуемся этим советом, чтобы убрать из индекса файл CONTRIBUTING.md :

$ git restore --staged CONTRIBUTING.md $ git status On branch master Changes to be committed: (use "git restore --staged . " to unstage) renamed: README.md -> README Changes not staged for commit: (use "git add . " to update what will be committed) (use "git restore . " to discard changes in working directory) modified: CONTRIBUTING.md

Файл CONTRIBUTING.md изменен, но снова не индексирован.

Откат изменённого файла с помощью git restore

Что, если вы поймете, что не хотите сохранять изменения в файле CONTRIBUTING.md ? Как легко его откатить — вернуть обратно к тому, как он выглядел при последнем коммите (или изначально клонирован, или каким-либо образом помещён в рабочий каталог)? К счастью, git status тоже говорит, как это сделать. В выводе последнего примера, неиндексированная область выглядит следующим образом:

Changes not staged for commit: (use "git add . " to update what will be committed) (use "git restore . " to discard changes in working directory) modified: CONTRIBUTING.md

Он довольно недвусмысленно говорит, как отменить сделанные вами изменения. Давайте сделаем то, что написано:

$ git restore CONTRIBUTING.md $ git status On branch master Changes to be committed: (use "git restore --staged . " to unstage) renamed: README.md -> README

Важно понимать, что git restore — опасная команда. Любые локальные изменения, внесённые в этот файл, исчезнут — Git просто заменит файл последней зафиксированной версией. Никогда не используйте эту команду, если точно не знаете, нужны ли вам эти несохранённые локальные изменения.

Как отменить команду git add * [дубликат]

Следующей командой были добавлены все файлы с основной папки: git add * Вопрос: как очистить все добавленные файлы? Коммит еще не был сделан. Просто удалить проиндексированные файлы?

Отслеживать
user262779
задан 10 дек 2018 в 8:38
81 1 1 серебряный знак 10 10 бронзовых знаков
git rm —cached <имя файла>(С) stackoverflow.com/questions/348170/…
10 дек 2018 в 9:18

@Lexx918 Вы ссылку дали на один ответ а написали другой в комментарии. Не вводите в заблуждение. Топикстартеру явно нужно убрать файл из индекса а не из репозитория

10 дек 2018 в 10:08

@tutankhamun я дал ссылку на аналогичный вопрос, а не на ответ. среди ответов там есть и тот что я процитировал.

10 дек 2018 в 14:19

@Ross, ваш вопрос содержит неоднозначную формулировку. «. Просто удалить проиндексированные файлы» — удалить именно файлы или удалить из индекса?

11 дек 2018 в 9:10

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

Обратной к add является команда git rm

UPD

Помятуя о том, что не все советы одинаково полезны, сначала стоит заглянуть в man

git-rm

Remove files from the index, or from the working tree and the index. … When —cached is given … allowing the file to be removed from just the index.

—cached Use this option to unstage and remove paths only from the index. Working tree files, whether modified or not, will be left alone.

Перевожу на русский: git rm —cached удаляет файлы только из индекса.

14. Отмена локальных изменений (до индексации)

Убедитесь, что вы находитесь на последнем коммите ветки master, прежде чем продолжить работу.

Выполните:
git checkout master

02 Измените hello.html

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

Внесите изменение в файл hello.html в виде нежелательного комментария.

Файл: hello.html
  

Hello, World!

03 Проверьте состояние

Сначала проверьте состояние рабочего каталога.

Выполните:
git status
Результат:
$ git status # On branch master # Changes not staged for commit: # (use "git add . " to update what will be committed) # (use "git checkout -- . " to discard changes in working directory) # # modified: hello.html # no changes added to commit (use "git add" and/or "git commit -a")

Мы видим, что файл hello.html был изменен, но еще не проиндексирован.

04 Отмена изменений в рабочем каталоге

Используйте команду checkout для переключения в версию файла hello.html в репозитории.

Выполните:
git checkout hello.html git status cat hello.html
Результат:
$ git checkout hello.html $ git status # On branch master nothing to commit (working directory clean) $ cat hello.html  

Hello, World!

Команда status показывает нам, что не было произведено никаких изменений, не зафиксированных в рабочем каталоге. И «нежелательный комментарий» больше не является частью содержимого файла.

Обзор команд Git для отмены изменений

Предположим, что мы случайно удалили файл, например myfile.txt :

git rm myfile.txt
git status

Для его восстановления выполняем команду:

git restore myfile.txt

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

Допустим, мы по ошибке проиндексировали файл, выполнив команду git add myfilename . Для отмены этого действия воспользуемся командой:

git reset HEAD myfilename

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

Посмотрим, как восстановить более ранние версии в случае необходимости. С помощью команды git log переходим в историю коммитов, выбираем код SHA ранней версии (достаточно первых символов) и выполняем команду git checkout :

git checkout 0dd6680

Получаем следующее сообщение:

Внимание: переключение на '0dd6680'.Вы находитесь в состоянии 'detached HEAD'("отсоединенный указатель HEAD"). Осмотритесь, внесите пробные изменения и зафиксируйте их. Вы можете отменить любые коммиты, выполненные в этом состоянии, ни на что не влияя при переключении обратно на ветку.При желании можете создать новую ветку и сохранить свежие коммиты. Для этого понадобится команда switch и -c: 
Пример:
git switch -c Для отмены этой операции существует команда: git switch -Для отключения данного сообщения установите переменную конфигурации advice.detachedHead в значение false. На данный момент HEAD указывает на коммит 0dd6680.
cat myfile.txt

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

Оказавшись в состоянии “detached HEAD” вполне можно запаниковать, не зная, как вернуться к последней версии в главной ветке master . Посмотрим, как это сделать:

git checkout main
Предыдущее положение HEAD указывало на коммит 0dd6680.
Переключение на ветку 'main'.
Состояние вашей ветки обновлено на 'origin/main'.

Откатываем изменения на один коммит

Для отмены предыдущего коммита выполняем команду:

git revert

Удаляем неотслеживаемый файл

Допустим, вы добавили файлы, которые еще не подготовлены к коммиту. Чтобы от них избавиться, выполняем команду:

git clean -n

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

git clean -f

Отменяем git init

Работая с Git, вы инициализируете проект с помощью git init . Для отмены данной операции просто удаляем файл .git из каталога.

rm -rf .git

Дополнительные команды: удаляем файл из удаленного репозитория

При работе с Git и GitHub/GitLab можно случайно отправить файл в удаленный репозиторий. В таком случае возникает необходимость его удалить. Рассмотрим ситуацию на примерах. Создаем удаленный репозиторий GitHub и локально его клонируем:

Меняем рабочий каталог на клонированный репозиторий. Как видно, здесь есть файлы README.md и .git .

Далее создаем файл wrong.txt , который мы отправим в удаленный репозиторий:

ls -ltra
total 6
drwxr-xr-x 1 gpipis 1049089 0 Jan 13 18:57 ../
-rw-r--r-- 1 gpipis 1049089 16 Jan 13 18:57 README.md
drwxr-xr-x 1 gpipis 1049089 0 Jan 13 18:57 .git/
drwxr-xr-x 1 gpipis 1049089 0 Jan 13 19:12 ./
-rw-r--r-- 1 gpipis 1049089 21 Jan 13 19:12 wrong.txt
git add wrong.txt
git commit -m "pushing the wrong.txt file"
git push origin main

Файл wrong.txt добавлен в удаленный репозиторий.

Удаляем файл

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

git rm wrong.txt
git commit -m "remove the wrong.txt file"
git push origin main

Как видим, цель достигнута:

ls -ltratotal 5
drwxr-xr-x 1 gpipis 1049089 0 Jan 13 18:57 ../
-rw-r--r-- 1 gpipis 1049089 16 Jan 13 18:57 README.md
drwxr-xr-x 1 gpipis 1049089 0 Jan 13 19:23 ./
drwxr-xr-x 1 gpipis 1049089 0 Jan 13 19:24 .git/

Удаляем файл из удаленного репозитория Git, но сохраняем его локально

Повторяем последовательность действий по созданию файла wrong.txt , который на этот раз мы удалим только из удаленного репозитория:

ls -ltratotal 6
drwxr-xr-x 1 gpipis 1049089 0 Jan 13 18:57 ../
-rw-r--r-- 1 gpipis 1049089 16 Jan 13 18:57 README.md
drwxr-xr-x 1 gpipis 1049089 0 Jan 13 19:24 .git/
drwxr-xr-x 1 gpipis 1049089 0 Jan 13 19:33 ./
-rw-r--r-- 1 gpipis 1049089 13 Jan 13 19:33 wrong.txt

Отправляем файл wrong.txt :

git add wrong.txt
git commit -m "pushing the wrong.txt file again"
git push origin main

Удаляем wrong.txt только из удаленного репозитория. Для этого используем тег cached .

git rm --cached wrong.txt
git commit -m "remove the wrong.txt file only from remote repo"
git push origin main

Проверяем локальный репозиторий:

$ ls -ltratotal 6
drwxr-xr-x 1 gpipis 1049089 0 Jan 13 18:57 ../
-rw-r--r-- 1 gpipis 1049089 16 Jan 13 18:57 README.md
drwxr-xr-x 1 gpipis 1049089 0 Jan 13 19:33 ./
-rw-r--r-- 1 gpipis 1049089 13 Jan 13 19:33 wrong.txt
drwxr-xr-x 1 gpipis 1049089 0 Jan 13 19:38 .git/

Проверяем удаленный каталог:

wrong.txt успешно удален из удаленного репозитория!

Со списком наиболее распространенных команд Git и GitHub вы можете ознакомиться по ссылке Git and GitHub Cheatsheet.

  • Полезные команды Git
  • 3 верных способа оптимизировать ревью на GitHub
  • Как настроить отдельные SSH-ключи для нескольких учётных записей GitLab

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *