Почему существует 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
#

10 ответов


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

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

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


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

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

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

если файл не был в контроле версий раньше (т. е. вы разворачиваете файл, который у вас был только 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> unstages файл в текущей фиксации.
  • git rm --cached <file> также размонтирует файл для будущих коммитов. Это unstaged, пока он не будет добавлен снова с git add <file>.

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

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

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


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

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 ..."to unstage)

  • 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

git commit - м а

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

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 ..."to unstage)

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

Я удивлен, что никто не упомянул 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> будет делать оба, как и OS rm <file> удалить файл из каталога, не удаляя ее версий.