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