Можно, как А.Х. ответил , используйте git commit -a
, но я бы советовал против этого: Как прокомментировал tymtam , вы будете настраивать себя на ошибки. Если вы действительно используете git commit -a
, более раннее git add
будет достаточно во время фиксации, как мы увидим в длинном описании.
Long: индекс Git, или, почему вы должны git add
так часто
Настоящая проблема здесь - ну, это немного зависит от вашей точки зрения, но Git не собирается менять свой бесполезный маленький ум о вещах - проблема что ваша ментальная модель того, как работает Git, вероятно, не соответствует тому, как на самом деле работает Git В частности, он не учитывает то, как Git продолжает бить вас по лицу с помощью Git index .
.
Индекс также называется промежуточной областью или кешем , в зависимости от того, кто или какая часть Git выполняет вызов. Что именно является индексом , равным , часто не очень хорошо описано. Трудно выполнить его полностью, потому что он имеет многократное использование, но лучшее краткое описание, которое я нашел, состоит в следующем: Индекс содержит файлы, которые войдут в next commit. (Это оставляет некоторые тонкости индекса, например, как он используется во время git merge
, но отражает его основную сущность.)
Эти файлы, хранящиеся в индексе, не являются отличиями. Они полные, полные копии всех файлов! Когда вы запускаете git commit
, Git не использует то, что находится в вашем рабочем дереве . Вместо этого Git просто упаковывает все, что находится в индексе , а затем , и использует это для создания нового коммита.
Способ, которым это работает, заключается в том, что когда вы впервые используете git checkout
для выбора некоторого коммита для работы, Git извлекает замороженные, только для чтения, сжатые файлы в формате Git из из Зафиксируйте, разморозьте, распакуйте их и запишите эти полезные версии каждого файла в ваше рабочее дерево.
Другие системы контроля версий тоже делают это, но другие системы останавливаются на этом: у них есть только замороженные, зафиксированные файлы в форме VCS и размороженные полезные копии рабочего дерева. Таким образом, эти другие системы, когда вы говорите им сделать новый коммит, будут медленно, осторожно, по одному файлу за раз, обрабатывать все ваше рабочее дерево, подготавливая каждый файл, сжимая его и замораживая это и подготовка к следующему коммиту. В более крупных проектах это может занять много секунд или даже несколько минут: вы вызываете глагол «сделать новый коммит», затем делаете перерыв или идете на ланч, потому что коммит не будет выполняться долгое время.
Git, однако, делает что-то другое, и, возможно, умнее, но также и гораздо более неприятно. Когда вы впервые git checkout
делаете этот оригинальный коммит, Git берет замороженные копии каждого файла и просто как бы оттаивает их. Он помещает эти полузамороженные копии Git-only каждого файла в свой индекс. Там они сидят, готовые быть мгновенно замороженными в следующий коммит. Этот файл можно распаковать в рабочее дерево только после того, как какой-либо файл будет в индексе, чтобы вы могли его использовать.
Позже, когда вы запустите git add
, сейчас Git смотрит на версию рабочего дерева. Иногда он также использует некоторую дополнительную сохраненную информацию в записи индекса - сохраненные данные о рабочем дереве - чтобы решить, нужно ли скопировать файл , но в принципе Git выполняет копирование файла. вернуться в индекс сейчас . В git add
время Git выполняет медленное мучительное повторное сжатие в формат Git-only. Он помещает последнюю копию файла в индекс, перезаписывая предыдущую копию.
Конечно, если вы снова измените файл в рабочем дереве, вам придется снова скопировать его в рабочее дерево. Вот почему вы должны повторно add
файл. Шаг добавления не помечает файл рабочего дерева вообще. Вместо этого он копирует файл рабочего дерева в индексную копию.
ThТот факт, что каждый файл имеет копию в индексе, является ключом к пониманию того, как на самом деле работает .gitignore
. Наличие или отсутствие файла в индексе определяет, является ли файл отслеженным . Только файл неотслеживаемый можно игнорировать, поэтому если файл находится в индексе, перечисление его в .gitignore
не имеет никакого эффекта. И, поскольку git checkout
копирует все замороженные файлы в индекс, если есть коммит, в котором есть какой-то файл, этот файл будет становиться отслеживаемым в то время, когда вы git checkout <em>that-particular-commit</em>
, даже если он указан в .gitignore
.
Обратите внимание, что для git add
есть флаг, который говорит ему: Для каждого файла, который уже есть в индексе, проверьте, обновил ли я копию рабочего дерева. Если это так, выполните git add
этого файла. (включая удаление файла из индекса, если он был удален из рабочего дерева.) Для этого выполните git add -u
, Но так как начинается с того, что уже находится в индексе , он пропускает все новые файлы рабочего дерева. Эти неотслеживаемые файлы остаются неотслеживаемыми.
Использование git commit -a
по сути то же самое 1 , что и запуск git add -u
непосредственно перед запуском git commit
. Таким образом, для всех файлов, которые находятся в индексе прямо тогда , включая все, что вы добавили после извлечения текущей фиксации, будет проверено, будет ли копия индекса заменена копией рабочего дерева. Но любые неотслеживаемые файлы не будут добавлены. Использование git commit -a
удобно и, ну, почти работает.
1"По существу" здесь начинает показывать свои трещины, если вы смешиваете в некоторых других git commit
опциях, в частности --only
или --include
. Они влияют на то, как Git использует индекс или - для --only
- использует ли он вообще стандартный индекс во время фиксации. Из этого следует, что вы можете создавать специальные временные индексные файлы. Я не буду вдаваться в подробности здесь, но, например, git stash
использует это, чтобы делать свои причудливые трюки.