it-swarm.com.ru

Как мне отменить 'git add' перед коммитом?

Я по ошибке добавил файлы в git с помощью команды:

git add myfile.txt

Я еще не запускаю git commit. Есть ли способ отменить это, чтобы эти файлы не были включены в коммит?

8265
paxos1977

Вы можете отменить git add перед фиксацией с помощью

git reset <file>

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

Ты можешь использовать

git reset

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

В старых версиях Git приведенные выше команды эквивалентны git reset HEAD <file> и git reset HEAD соответственно и завершатся неудачно, если HEAD не определено (потому что вы еще не сделали никаких коммитов в своем репо), или неоднозначными (потому что вы создали ветку с именем HEAD, которая это глупость, которую вы не должны делать). Это было изменено в Git 1.8.2 , поэтому в современных версиях Git вы можете использовать приведенные выше команды даже до того, как сделать первый коммит:

"git reset" (без опций или параметров) используется для вывода ошибок, когда в вашей истории нет коммитов, но теперь он дает пустой индекс (для соответствия несуществующему коммиту вы даже не используете).

9377
genehack

Ты хочешь:

git rm --cached <added_file_to_undo>

Обоснование:

Когда я был новичком в этом, я впервые попробовал

git reset .

(чтобы отменить все мои начальные добавления), только чтобы получить это (не очень) полезное сообщение:

fatal: Failed to resolve 'HEAD' as a valid ref.

Оказывается, это потому, что HEAD ref (branch?) Не существует до первого коммита. То есть, вы столкнетесь с той же проблемой новичка, что и я, если ваш рабочий процесс, такой как мой, будет выглядеть примерно так:

  1. перейдите в мой новый каталог проектов, чтобы опробовать Git, новую горячность
  2. git init
  3. git add .
  4. git status

    ... много вых свитков ...

    => Черт, я не хотел добавлять все это.

  5. google "отменить git add"

    => найти переполнение стека - ууу

  6. git reset .

    => fatal: Не удалось разрешить 'HEAD' в качестве действительного ссылки.

Далее выясняется, что ошибка зарегистрирована против бесполезности этого в списке рассылки.

И что правильное решение было прямо там, в выводе статуса Git (который, да, я назвал "м")

...
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
...

И решение действительно заключается в использовании git rm --cached FILE.

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

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

Я приступаю к использованию

git rm --cached .

удалить все и начать заново. Однако это не сработало, поскольку, хотя add . является рекурсивным, оказывается, что rm нуждается в -r для рекурсии. Вздох.

git rm -r --cached .

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

git add -n .

Я заархивировал все в безопасное место, прежде чем доверять git help rm о том, что --cached ничего не уничтожает (и что, если я ошибся в этом).

2070
Rhubarb

Если вы введете:

git status

git расскажет вам, что ставится, и т. д., включая инструкции по удалению:

use "git reset HEAD <file>..." to unstage

Я считаю, что Git довольно хорошо подталкивает меня к тому, чтобы делать правильные вещи в подобных ситуациях.

Примечание: последние версии git (1.8.4.x) изменили это сообщение:

(use "git rm --cached <file>..." to unstage)
510
Paul Beckingham

Для пояснения: git add перемещает изменения из текущего рабочего каталога в промежуточная область (индекс).

Этот процесс называется постановка. Таким образом, наиболее естественная команда stage изменения (измененные файлы) является очевидной:

git stage

git add просто проще ввести псевдоним для git stage

Жаль, что нет ни команд git unstage, ни git unadd. Соответствующий труднее угадать или запомнить, но довольно очевиден:

git reset HEAD --

Мы можем легко создать псевдоним для этого:

git config --global alias.unadd 'reset HEAD --'
git config --global alias.unstage 'reset HEAD --'

И, наконец, у нас есть новые команды:

git add file1
git stage file2
git unadd file2
git unstage file1

Лично я использую даже более короткие псевдонимы:

git a #for staging
git u #for unstaging
240
takeshin

В дополнение к принятому ответу, если ваш ошибочно добавленный файл был огромным, вы, вероятно, заметите, что даже после удаления его из индекса с помощью 'git reset', он по-прежнему занимает место в каталоге .git. Это не о чем беспокоиться, файл действительно все еще находится в хранилище, но только как "свободный объект", он не будет скопирован в другие хранилища (через клон, Push), и пространство будет в конечном итоге освобождено - хотя возможно, не очень скоро. Если вы беспокоитесь, вы можете запустить:

git gc --Prune=now

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

Итак, что является реальным отменитьgit add?

git reset HEAD <file>?

или же

git rm --cached <file>?

Собственно говоря, и если я не ошибаюсь: нет.

git addне может быть отменено - в общем, безопасно.

Давайте сначала вспомним, что на самом деле делает git add <file>:

  1. Если <file> был ранее не отслеживался, git addдобавляет его в кеш с его текущим содержимым.

  2. Если <file> был уже отслежен, git addсохраняет текущее содержимое (снимок, версия) в кэш. В GIT это действие по-прежнему называется добавить, (не просто обновить его), потому что две разные версии (снимки) файл рассматривается как два разных элемента: следовательно, мы действительно добавляем новый элемент в кеш, который в конечном итоге будет зафиксирован позже.

В свете этого вопрос несколько двусмысленный:

Я по ошибке добавил файлы с помощью команды ...

Похоже, что сценарий OP является первым (неотслеживаемый файл), мы хотим, чтобы "отмена" удаляла файл (а не только текущее содержимое) из отслеживаемых элементов. Если это так, тогда можно запустить git rm --cached <file>.

И мы могли бы также запустить git reset HEAD <file>. В целом это предпочтительнее, потому что это работает в обоих сценариях: оно также отменяет действия, когда мы ошибочно добавили версию уже отслеженного элемента.

Но есть две оговорки.

Во-первых: Существует (как указано в ответе) только один сценарий, в котором git reset HEAD не работает, но git rm --cached работает: новый репозиторий (без фиксаций). Но, на самом деле, это практически неактуальный случай.

Второе: имейте в виду, что git reset HEAD не может волшебным образом восстановить ранее кэшированное содержимое файла, он просто повторно синхронизирует его с HEAD. Если наш ошибочный git add перезаписал предыдущую поэтапную незафиксированную версию, мы не сможем ее восстановить. Вот почему, строго говоря, мы не можем отменить [*].

Пример:

$ git init
$ echo "version 1" > file.txt
$ git add file.txt   # first add  of file.txt
$ git commit -m 'first commit'
$ echo "version 2" > file.txt
$ git add  file.txt   # stage (don't commit) "version 2" of file.txt
$ git diff --cached file.txt
-version 1
+version 2
$ echo "version 3" > file.txt   
$ git diff  file.txt
-version 2
+version 3
$ git add  file.txt    # oops we didn't mean this
$ git reset HEAD file.txt  # undo ?
$ git diff --cached file.txt  # no dif, of course. stage == HEAD
$ git diff file.txt   # we have lost irrevocably "version 2"
-version 1
+version 3

Конечно, это не очень важно, если мы просто следуем обычному ленивому рабочему процессу выполнения 'git add' только для добавления новых файлов (случай 1), и мы обновляем новое содержимое с помощью команды commit, git commit -a.


* (Правка: вышеупомянутое практически правильно, но все же могут быть несколько хакерские/запутанные способы восстановления изменений, которые были поставлены, но не зафиксированы, а затем перезаписаны - см. Комментарии Йоханнеса Матокича и iolsmit)

161
leonbloy
git rm --cached . -r

рекурсивно "удалит" все, что вы добавили из вашего текущего каталога

92
braitsch

Отменить уже добавленный файл довольно легко, используя git для сброса myfile.txt, который уже добавлен, используйте:

git reset HEAD myfile.txt

Объясните:

После того, как вы поставили ненужные файлы, чтобы отменить их, вы можете сделать git reset, Head - заголовок вашего файла в локальной сети, а последний параметр - это имя вашего файла.

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

git reset HEAD file

88
Alireza

Бежать

git gui

и удалите все файлы вручную или, выбрав их все и нажав кнопку nstage from commit.

86
Khaja Minhajuddin

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

Что вы делали раньше:

  • Изменили файл и использовали git add . или git add <file>.

Что вы хотите:

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

    git reset head <file>
    
  • Сбросьте файл до последнего состояния из HEAD, отмените изменения и удалите их из индекса:

    # Think `svn revert <file>` IIRC.
    git reset HEAD <file>
    git checkout <file>
    
    # If you have a `<branch>` named like `<file>`, use:
    git checkout -- <file>
    

    Это необходимо, поскольку git reset --hard HEAD не будет работать с отдельными файлами.

  • Удалите <file> из индекса и управления версиями, сохранив файл без версии с изменениями в рабочей копии:

    git rm --cached <file>
    
  • Удалите <file> из рабочей копии и полностью версионируйте:

    git rm <file>
    
80
sjas

Вопрос не четко поставлен. Причина в том, что git add имеет два значения:

  1. добавив новый файл в область подготовки, затем отмените с помощью git rm --cached file.
  2. добавив модифицированный файл в область подготовки, затем отмените с помощью git reset HEAD file.

если сомневаетесь, используйте

git reset HEAD file

Потому что это делает ожидаемую вещь в обоих случаях.

Предупреждение: если вы сделаете git rm --cached file для файла, который был изменен (файл, который существовал ранее в хранилище), то этот файл будет удален в git commit! Он все еще будет существовать в вашей файловой системе, но если кто-нибудь еще извлечет ваш коммит, файл будет удален из их рабочего дерева.

git status сообщит вам, был ли файл новый файл или изменен:

On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   my_new_file.txt
    modified:   my_modified_file.txt
73
Michael_Scharf

Если вы выполняете первоначальный коммит и не можете использовать git reset, просто объявите "Git bankruptcy", удалите папку .git и начните сначала

63
Paul Betts

Как и во многих других ответах, вы можете использовать git reset

НО:

Я нашел этот замечательный небольшой пост, который на самом деле добавляет команду Git (а также псевдоним) для git unadd: подробности смотрите в git unadd или ..

Просто,

git config --global alias.unadd "reset HEAD"

Теперь вы можете

git unadd foo.txt bar.txt
55
electblake

Для этого можно использовать git remove или git rm с флагом --cached. Пытаться:

git help rm
44
gnud

Используйте git add -i, чтобы удалить только что добавленные файлы из вашего предстоящего коммита. Пример:

Добавление файла, который вы не хотели:

$ git add foo
$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   foo
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
# [...]#

Переход к интерактивному добавлению для отмены добавления (команды, набранные здесь в git: "r" (возврат), "1" (первая запись в списке показывает возврат), "возврат", чтобы выйти из режима возврата, и "q" (уволиться):

$ git add -i
           staged     unstaged path
  1:        +1/-0      nothing foo

*** Commands ***
  1: [s]tatus     2: [u]pdate     3: [r]evert     4: [a]dd untracked
  5: [p]atch      6: [d]iff       7: [q]uit       8: [h]elp
What now> r
           staged     unstaged path
  1:        +1/-0      nothing [f]oo
Revert>> 1
           staged     unstaged path
* 1:        +1/-0      nothing [f]oo
Revert>> 
note: foo is untracked now.
reverted one path

*** Commands ***
  1: [s]tatus     2: [u]pdate     3: [r]evert     4: [a]dd untracked
  5: [p]atch      6: [d]iff       7: [q]uit       8: [h]elp
What now> q
Bye.
$

Это оно! Вот ваше доказательство, показывающее, что "foo" снова в списке неотслеживаемых:

$ git status
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
# [...]
#       foo
nothing added to commit but untracked files present (use "git add" to track)
$
42
Alex North-Keys

Вот способ избежать этой неприятной проблемы, когда вы начинаете новый проект:

  • Создайте основной каталог для вашего нового проекта.
  • Запустите git init.
  • Теперь создайте файл .gitignore (даже если он пустой).
  • Зафиксируйте свой файл .gitignore.

Git делает очень трудным выполнение git reset, если у вас нет коммитов. Если вы создаете крошечный начальный коммит только ради того, чтобы иметь его, после этого вы можете git add -A и git reset столько раз, сколько вы хотите, чтобы все было правильно.

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

  • Проверьте этот первоначальный коммит. Это удалит все ваши файлы.
  • Затем проверьте ваш последний коммит снова. Это позволит получить свежие копии ваших файлов, используя ваши текущие настройки окончания строки.
37
Ryan Lundy

Возможно, Git эволюционировал с тех пор, как вы опубликовали свой вопрос.

$> git --version
git version 1.6.2.1

Теперь вы можете попробовать:

git reset HEAD .

Это должно быть то, что вы ищете.

33
Kokotte23

Обратите внимание, что если вы не указали ревизию, вам необходимо включить разделитель. Пример из моей консоли:

git reset <path_to_file>
fatal: ambiguous argument '<path_to_file>': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions

git reset -- <path_to_file>
Unstaged changes after reset:
M   <path_to_file>

(git версия 1.7.5.4)

33
powlo

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

git rm --cached FILE

Используйте rm --cached только для случайно добавленных новых файлов.

30
Ran

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

git reset *
24
Zorayr

используйте команду * для обработки нескольких файлов одновременно

git reset HEAD *.prj
git reset HEAD *.bmp
git reset HEAD *gdb*

так далее

24
boulder_ruby

Просто введите git reset, он вернется обратно, и вы ни разу не набрали git add . с момента последнего коммита. Убедитесь, что вы совершили раньше.

22
Donovan

Предположим, я создаю новый файл newFile.txt.

enter image description here

Предположим, я случайно добавил файл, git add newFile.txt

enter image description here

Теперь я хочу отменить это добавление перед коммитом git reset newFile.txt

enter image description here

18
Vidura Mudalige

Для конкретного файла:

  • git reset my_file.txt
  • git checkout my_file.txt

Для всех добавленных файлов:

  • git reset.
  • git Checkout.

Примечание: checkout изменяет код в файлах и переходит в последнее обновленное (подтвержденное) состояние. сброс не меняет коды; это просто сбрасывает заголовок.

17
Hasib Kamal

Чтобы отменить git добавить использование

git reset filename

13
Anirudh Sood

Эта команда отменяет ваши изменения:

git reset HEAD filename.txt

Вы также можете использовать

git add -p 

добавить части файлов.

13
wallerjake

Я удивлен, что никто не упоминает интерактивный режим:

git add -i

выберите опцию 3, чтобы удалить файлы. В моем случае я часто хочу добавить более одного файла, в интерактивном режиме вы можете использовать такие номера, чтобы добавить файлы. Это займет все, кроме 4: 1,2,3,5

Чтобы выбрать последовательность, просто наберите 1-5, чтобы взять все от 1 до 5.

Git промежуточные файлы

13
Jonathan

git add myfile.txt # это добавит ваш файл в список подтвержденных

Совершенно противоположно этой команде,

git reset HEAD myfile.txt  # this will undo it. 

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

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

9
Mohideen bin Mohammed
git reset filename.txt

Удалит файл с именем filename.txt из текущего индекса, области "собирается быть зафиксирован", без изменения чего-либо еще.

9
Rahul Sinha

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

Я создал новый файл и добавил его в git. Затем я удалил его, используя графический интерфейс SourceTree. Это результат:

Unstaging файлы [12/12/15 10:43]
git -c diff.mnemonicprefix = false -c core.quotepath = false -c credential.helper = сброс исходного файла -q - путь/к/файлу/имени файла.Java

SourceTree использует reset для удаления новых файлов.

8
miva2
git reset filename.txt  

Удалит файл с именем filename.txt из текущего индекса, области "собирается быть зафиксирован", без изменения чего-либо еще.

7
Joseph Mathew

Одним из наиболее интуитивных решений является использование SourceTree .

Вы можете просто перетаскивать файлы из поэтапной и неустановленной enter image description here

7
Marcin Szymczak

Команда git reset помогает вам изменить либо промежуточную область, либо промежуточную область и рабочее дерево. Способность Git создавать коммиты в точности так, как вы хотите, означает, что вам иногда нужно отменить изменения, внесенные вами с помощью git add.

Вы можете сделать это, вызвав git reset HEAD <file to change>. У вас есть два варианта, чтобы полностью избавиться от изменений. git checkout HEAD <file(s) or path(s)> - это быстрый способ отменить изменения в области подготовки и рабочем дереве. Будьте осторожны с этой командой, потому что она удаляет все изменения в вашем рабочем дереве. Git не знает об этих изменениях, так как они никогда не совершались. Невозможно вернуть эти изменения после запуска этой команды.

Другая команда в вашем распоряжении - git reset --hard. Это в равной степени разрушительно для вашего рабочего дерева - любые незафиксированные изменения или поэтапные изменения теряются после его запуска. Запуск git reset -hard HEAD делает то же самое, что и git checkout HEAD. Это просто не требует файла или пути для работы.

Вы можете использовать --soft с git reset. Он сбрасывает репозиторий в указанный вами коммит и выполняет все эти изменения. На любые изменения, которые вы уже поставили, это не влияет, равно как и изменения в вашем рабочем дереве.

Наконец, вы можете использовать --mixed для сброса рабочего дерева без внесения каких-либо изменений. Это также unstages любые изменения, которые поставлены.

1
SAIguru011