Почему есть 2 способа, чтобы отменить добавление файла в Git?



иногда git предлагает git rm --cached чтобы открепить файл, иногда git reset HEAD file. Когда я должен использовать что?



EDIT:



D:codegt2>git init
Initialized empty Git repository in D:/code/gt2/.git/
D:codegt2>touch a

D:codegt2>git status
# On branch master
#
# Initial commit
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# a
nothing added to commit but untracked files present (use "git add" to track)

D:codegt2>git add a

D:codegt2>git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
# (use "git rm --cached <file>..." to unstage)
#
# new file: a
#
D:codegt2>git commit -m a
[master (root-commit) c271e05] a
0 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 a

D:codegt2>touch b

D:codegt2>git status
# On branch master
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# b
nothing added to commit but untracked files present (use "git add" to track)

D:codegt2>git add b

D:codegt2>git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: b
#
805   10  

10 ответов:

git rm --cached <filePath>не unstage файл, это на самом деле этапы удаления файла(ов) из репозитория (если оно уже было совершено ранее), но оставляет файл в вашем рабочем каталоге (с неотслеживаемый файл).

git reset -- <filePath> будет убрать из буфера любые поэтапные изменения для данного файла(ов).

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

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

git reset HEAD file ( который по умолчанию использует --mixed флаг) отличается тем, что в случае, когда файл уже находится в репо, он заменяет индексируйте версию файла с помощью одного из РЕПО (HEAD), эффективно разбивая модификации к нему.

в случае неверсионного файла, он собирается unstage весь файл, как файл не был там в голове. В этом аспекте git reset HEAD file и git rm --cached одинаковы, но они не одинаковы ( как объяснено в случае файлов, уже находящихся в репо)

к вопросу о Why are there 2 ways to unstage a file in git? - там никогда не бывает только один способ сделать что-нибудь в git. это красота его:)

все просто:

  • git rm --cached <file>делает git остановить отслеживание файла полностью (оставляя его в файловой системе, в отличие от простого git rm*)
  • git reset HEAD <file>отменяет любые изменения, внесенные в файл с момента последнего фиксации (но не возвращает их в файловой системе, вопреки тому, что имя команды может предложить**). Файл остается под контролем редакции.

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

* имейте в виду предостережение @DrewT упоминает в своем ответе, относительно git rm --cached из файла, который был ранее совершенных в репозиторий. В контексте этого вопроса, только что добавленного и еще не зафиксированного файла, беспокоиться не о чем о.

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

этот поток немного стар, но я все еще хочу добавить небольшую демонстрацию, так как это все еще не интуитивная проблема:

me$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   new file:   to-be-added
#   modified:   to-be-modified
#   deleted:    to-be-removed
#

me$ git reset -q HEAD to-be-added

    # ok

me$ git reset -q HEAD to-be-modified

    # ok

me$ git reset -q HEAD to-be-removed

    # ok

# or alternatively:

me$ git reset -q HEAD to-be-added to-be-removed to-be-modified

    # ok

me$ git status
# On branch master
# Changes not staged for commit:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   to-be-modified
#   deleted:    to-be-removed
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   to-be-added
no changes added to commit (use "git add" and/or "git commit -a")

git reset HEAD (без -q) дает предупреждение об измененном файле и его код выхода равен 1, который будет рассматриваться как ошибка в скрипте.

Edit:git checkout HEAD to-be-modified to-be-removed также работает для индексации, но удаляет полностью из рабочего пространства

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

git stash
git stash pop

это выполняет сброс в HEAD и повторно применяет ваши изменения, позволяя вам повторно выполнить отдельные файлы для фиксации. это также полезно, если вы забыли создать отдельную ветку для запросов (git stash ; git checkout -b <feature> ; git stash pop).

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

  • git reset HEAD <file> разворачивает файл в текущей фиксации.
  • git rm --cached <file> будет unstage файл для будущих коммитов также. Он не выгружается до тех пор, пока он не будет добавлен снова с git add <file>.

и есть еще одно важное отличие:

  • после git rm --cached <file> и нажимаем ваш ответвление на пульт, любой, кто потянет вашу ветку с пульта дистанционного управления, получит файл на самом деле удален из своей папки, даже если в вашем локальном рабочем наборе файл просто не отслеживается (т. е. физически не удаляется из папки).

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

допустим, вы stage весь каталог через git add <folder>, но вы хотите исключить файл из поэтапного списка (т. е. список, который генерируется при запуске git status) и сохранить изменения в исключенном файле (вы работали над чем-то, и он не готов к фиксации, но вы не хотите потерять свою работу...). Вы можете просто использовать:

git reset <file>

при выполнении git status, вы увидите, что любой файл(ы) вы reset are unstaged а остальные файлы added еще в staged список.

1.

D:\code\gt2>git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#       new file:   a

(используйте "git rm -- cached ..."чтобы отменить добавление)

  • Git-это система указателей

  • у вас еще нет фиксации, чтобы изменить указатель на

  • единственный способ "вынуть файлы из ведра, на которое указывают" - это удалите файлы, которые вы сказали git, чтобы следить за изменениями

2.

D:\code\gt2>git commit -m a
[master (root-commit) c271e05] a
0 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 a

коммитов - м а

  • ты совершил, 'спас'

3.

D:\code\gt2>git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   b
#

(используйте " git reset HEAD ..."чтобы отменить добавление)

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

Я удивлен, что никто не упомянул git reflog (http://git-scm.com/docs/git-reflog):

# git reflog
<find the place before your staged anything>
# git reset HEAD@{1}

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

Это похоже на git reset HEAD <file> но в некоторых случаях может быть более зернистый.

извините-не совсем отвечая на ваш вопрос, но просто указывая еще один способ unstage файлов, которые я использую довольно часто (я для одного, как ответы Райана Стюарта и waldyrious очень много.);) Надеюсь, это поможет.

мне кажется, что git rm --cached <file> удаляет файл из индекса, не удаляя его из каталога, где обычный git rm <file> сделал бы обе, просто как ОС rm <file> удалит файл из каталога без удаления его версии.

Comments

    Ничего не найдено.