Я всегда путаюсь с этим, так что вот контрольный пример с напоминанием; скажем, у нас есть этот 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
полностью перезапишет изменения.