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

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

git add myfile.txt

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

6630
задан paxos1977 08 дек. '08 в 0:57
источник поделиться
33 ответов
  • 1
  • 2

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

git reset <file>

который удалит его из текущего индекса (список "about to be commit" ) без изменения чего-либо еще.

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

git reset

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

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

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

7409
ответ дан genehack 08 дек. '08 в 1:30
источник поделиться

Вы хотите:

git rm --cached <added_file_to_undo>

Рассуждение:

Когда я был новым, я сначала попробовал

git reset .

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

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

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

  • cd в мой новый новый каталог проектов, чтобы опробовать Git, новую горячность
  • git init
  • git add .
  • git status

    ... много свитков дерьма с помощью...

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

  • google "undo git add"

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

  • git reset .

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

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

И что правильное решение было прямо там, в состоянии вывода 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 не уничтожая ничего (и что, если я его опечатал).

1843
ответ дан Rhubarb 25 марта '09 в 19:20
источник поделиться

Если вы наберете:

git status

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

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

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

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

(use "git rm --cached <file>..." to unstage)
446
ответ дан Paul Beckingham 08 дек. '08 в 2:22
источник поделиться

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

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

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
201
ответ дан takeshin 10 сент. '10 в 23:28
источник поделиться

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

git gc --prune=now

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

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

git reset HEAD <file>?

или

git rm --cached <file>?

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

git add нельзя отменить - в целом.

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

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

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

В свете этого вопрос немного неоднозначен:

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

Сценарий OP, по-видимому, является первым (необработанным файлом), мы хотим, чтобы "undo" удалял файл (а не только текущее содержимое) из отслеживаемых элементов. Если это, то это нормально для запуска 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.

119
ответ дан leonbloy 18 мая '11 в 21:05
источник поделиться
git rm --cached . -r

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

79
ответ дан braitsch 10 дек. '09 в 0:19
источник поделиться

Run

git gui

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

68
ответ дан Khaja Minhajuddin 12 окт. '11 в 4:12
источник поделиться

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

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

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

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

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

    git reset head <file>
    
  • Reset файл с последним состоянием из 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> из индекса и версии, сохраняя файл с версией un- с изменениями в рабочей копии:

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

    git rm <file>
    
65
ответ дан sjas 29 марта '13 в 14:14
источник поделиться

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

49
ответ дан Paul Betts 19 нояб. '09 в 19:39
источник поделиться

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

  • добавление нового файла в промежуточную область, затем отмените с помощью git rm --cached file.
  • добавление файла измененного в промежуточную область, затем отмените с помощью 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
48
ответ дан Michael_Scharf 16 янв. '14 в 22:54
источник поделиться

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

НО:

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

Просто,

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

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

git unadd foo.txt bar.txt
43
ответ дан electblake 01 окт. '10 в 17:54
источник поделиться

git remove или git rm можно использовать для этого с флагом --cached. Попробуйте:

git help rm
36
ответ дан gnud 08 дек. '08 в 1:00
источник поделиться

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

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

$ 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" (quit):

$ 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)
$
32
ответ дан Alex North-Keys 18 апр. '12 в 15:53
источник поделиться

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

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

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

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

  • Отметьте, что начальная фиксация. Это приведет к удалению всех ваших файлов.
  • Затем снова проверьте свою последнюю фиксацию. Это приведет к восстановлению свежих копий ваших файлов, используя текущие настройки окончания line-.
29
ответ дан Kyralessa 25 сент. '11 в 2:34
источник поделиться

Может быть, Git развился с тех пор, как вы разместили свой вопрос.

$> git --version
git version 1.6.2.1

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

git reset HEAD .

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

27
ответ дан Kokotte23 19 нояб. '09 в 19:38
источник поделиться

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

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)

26
ответ дан powlo 23 янв. '12 в 19:57
источник поделиться

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

git reset HEAD myfile.txt

Объясняю:

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

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

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

25
ответ дан Alireza 28 июня '17 в 13:43
источник поделиться

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

git rm --cached FILE

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

23
ответ дан Ran 22 июня '09 в 14:58
источник поделиться

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

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

и т.д.

18
ответ дан boulder_ruby 28 авг. '13 в 0:15
источник поделиться

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

git reset *
16
ответ дан Zorayr 26 июля '12 в 10:50
источник поделиться

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

16
ответ дан Donovan 19 мая '10 в 6:49
источник поделиться

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

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

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

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

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

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

13
ответ дан Vidura Mudalige 04 окт. '16 в 14:02
источник поделиться

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

git reset HEAD filename.txt

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

git add -p 

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

10
ответ дан wallerjake 31 янв. '13 в 18:43
источник поделиться

Для отмены git add используйте

git reset filename

8
ответ дан Anirudh Sood 02 окт. '16 в 18:54
источник поделиться

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

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

Unstaging files [08/12/15 10:43]
git -c diff. mnemonicprefix=false -c core. quotepath=false -c учетные данные. helper=sourcetree reset -q - путь /to/file/filename.java

SourceTree использует reset, чтобы отключить новые файлы.

6
ответ дан miva2 08 дек. '15 в 12:58
источник поделиться

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

git add -i

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

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

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

6
ответ дан Jonathan 22 окт. '15 в 16:03
источник поделиться
git reset filename.txt

Удалит файл с именем filename.txt из текущего индекса, область "about to be commit", не изменяя ничего.

4
ответ дан Rahul Sinha 11 июля '16 в 21:40
источник поделиться
git reset filename.txt  

Удалит файл с именем filename.txt из текущего индекса, область "about to be commit", не изменяя ничего.

2
ответ дан Joseph Mathew 26 окт. '17 в 21:15
источник поделиться

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

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

2
ответ дан Marcin Szymczak 26 мая '17 в 11:32
источник поделиться

git add myfile.txt # это добавит ваш файл в список, посвященный фиксации

В отличие от этой команды,

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

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

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

2
ответ дан Mohideen ibn Mohammed 27 июня '17 в 16:58
источник поделиться
  • 1
  • 2

Другие вопросы по меткам