Чтобы понять разницу между git commit
и git commit -a
, вам нужно знать о index в git, также известном как staging area .
Индекс по существу хранит состояние каждого файла, который войдет в следующий коммит. (Под «состоянием» здесь я подразумеваю точное содержимое файла, которое git идентифицирует по его хешу.) Когда вы набираете git commit
без каких-либо других параметров, git сделает новый коммит, в котором будут указаны состояния всех файлов. точно так же, как в индексе. Это может сильно отличаться от вашего рабочего дерева, и это полезная функция git, как я объясню ниже.
Что действительно делает git add
, так это «ставит» файл в файл или добавляет его текущее состояние к индексу. Неважно, был ли он изначально отслежен или нет, вы говорите: «В следующем коммите я хочу, чтобы этот файл присутствовал именно с этим содержимым». Важно понимать, что здесь записывается контент, который вы хотите добавить, а не имя файла - это означает, что если вы затем продолжите вносить изменения в файл после того, как добавили его в git add
, вы увидите вывод из git status
это иногда смущает людей, приходящих из других систем контроля версий:
$ git status
[...]
# Changes to be committed:
# (use "git rm --cached <file>..." to unstage)
#
# modified: foo.txt
#
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: foo.txt
... но это имеет абсолютный смысл, если вы знаете об индексе. Вы можете увидеть изменения, которые вы уже поставили (то есть разницу между состоянием файлов в индексе и HEAD, который обычно является последним коммитом в ветви, над которой вы работаете) с:
$ git diff --cached
... и вы можете увидеть все изменения, которые еще не были подготовлены (то есть разницу между вашей рабочей копией и индексом) с помощью:
$ git diff
Так почему это так полезно? По сути, идея заключается в том, что история вашего проекта наиболее полезна, когда каждый коммит содержит логически сгруппированный набор изменений, которые вносят четко определенные улучшения в проект. Чем меньше вы можете сделать эти коммиты, тем лучше, поскольку позже замечательный инструмент git bisect
может быстро помочь вам отследить, какие изменения привели к ошибке. Если вы не обладаете чрезмерной дисциплиной, то в процессе исправления ошибки вы часто будете заканчивать редактированием других файлов, которые вам не нужно менять, чтобы решить проблему, или в конечном итоге вы сможете решить две логически разные проблемы до того, как решив принять ваши изменения. В этих случаях индекс может помочь вам выделить эти изменения - просто git add
в каждом файле, который содержит изменения, которые вы хотите внести в первый коммит, запустите git commit
, затем сделайте то же самое, чтобы создать второй коммит. [1] * 1 029 *
Если вы привыкли делать это и вам нравится рабочий процесс, вам иногда придется просто захотеть внести некоторые изменений в файл, а не другие, и в этом случае вы захотите узнать о git add -p
(а затем о его интерактивных опциях s
и e
!)
Однако, чтобы вернуться к первоначальному вопросу - что делает git commit -a
иначе? По сути, он говорит: «Перед созданием этого коммита также поместите каждый файл, который был изменен (или удален) в его текущее состояние». Так что, если вы не думаете, что тщательное размещение файлов в индексе перед фиксацией полезно, вы можете просто использовать «git commit -a» все время. Тем не менее, я думаю, что одним из приятных моментов использования git является то, что он поощряет вас создавать красивые коммиты, и активное использование индекса очень помогает в этом. :)
Примечания:
Для простоты приведенного выше объяснения некоторые утверждения несколько приблизительны (например, я не упомянул, что индекс также хранит (не) исполняемое состояние файла, что он может иметь несколько версий во время слияния, и т. д.)
[1] Вы должны делать это осторожно, если хотите убедиться, что каждый коммит в вашей истории был должным образом протестирован - если это важно в вашем проекте, вы должны тестировать дерево при каждом новом коммите, прежде чем нажимать ...