Я всегда путаюсь с этим, поэтому вот контрольный пример с напоминанием; допустим, у нас есть этот bash
скрипт для тестирования git
:
set -x
rm -rf test
mkdir test
cd test
git init
git config user.name test
git config user.email test@test.com
echo 1 > a.txt
echo 1 > b.txt
git add *
git commit -m "initial commit"
echo 2 >> b.txt
git add b.txt
git commit -m "second commit"
echo 3 >> b.txt
На этом этапе изменения не размещаются в кеше, так же git status
как и:
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: b.txt
no changes added to commit (use "git add" and/or "git commit -a")
Если с этого момента мы это сделаем git checkout
, результат будет таким:
$ git checkout HEAD -- b.txt
$ git status
On branch master
nothing to commit, working directory clean
Если вместо этого мы делаем git reset
, результат:
$ git reset HEAD -- b.txt
Unstaged changes after reset:
M b.txt
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: b.txt
no changes added to commit (use "git add" and/or "git commit -a")
Итак, в этом случае - если изменения не являются поэтапными, git reset
не имеет значения, пока git checkout
перезаписываются изменения.
Теперь предположим, что последнее изменение из приведенного выше сценария является поэтапным / кэшированным, то есть мы также сделали это git add b.txt
в конце.
В этом случае, git status
на данный момент это:
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: b.txt
Если с этого момента, мы делаем git checkout
, результат будет таким:
$ git checkout HEAD -- b.txt
$ git status
On branch master
nothing to commit, working directory clean
Если вместо этого мы делаем git reset
, результат:
$ git reset HEAD -- b.txt
Unstaged changes after reset:
M b.txt
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: b.txt
no changes added to commit (use "git add" and/or "git commit -a")
Таким образом, в этом случае - если изменения будут поэтапными, в git reset
основном внесут поэтапные изменения в не поэтапные изменения - в то время git checkout
как изменения будут полностью перезаписаны.