TL; DR
Чтобы оформить файл, используйте git add
.Чтобы удалить файл, используйте git reset
.Ничего из этого не поможет, пока вы правильно не поймете Git index .
Long
Этот вопрос, кажется, не имеет смысла, что заставляет меня верить, что у вас, вероятно, естьнеправильное представление о том, что такое индекс Git.Индекс, также называемый промежуточной областью или иногда кеш , представляет собой несколько скрытую структуру данных, которая крайне важна для использования Git, но плохо объясняется в большой документации по Git идаже некоторые книги по Git.
Git фиксирует и рабочее дерево Git
Вы, вероятно, уже знакомы с коммитами и идеей Git о рабочем дереве , но давайте рассмотримих снова кратко. commit , в Git, содержит полный снимок всего исходного кода (или чего бы то ни было, что вы управляете версиями).Каждый коммит уникально идентифицируется по его хэш-идентификатору , что очень уродливо: git log
печатает идентификаторы коммитов, и когда вы запускаете git log
, вы можете увидеть, например:
commit c05048d43925ab8edcb36663752c2b4541911231
Author: Junio C Hamano ...
Помимо сохранения исходного снимка, каждый коммит также сохраняет хэш-идентификатор предыдущего или родительского коммита.Git использует их для объединения коммитов в обратном порядке, начиная с last commit и работая в обратном направлении. имя ветви , как master
или xo-wip
, просто содержит хэш-идентификатор last commit, который находится в этой ветви.Если мы используем заглавные буквы для обозначения больших уродливых хеш-идентификаторов, мы можем нарисовать следующую ситуацию:
I <-- master
/
...--G--H
\
J--K--L <-- xo-wip
Здесь имя master
обозначает коммит I
, а имя xo-wip
идентифицирует коммит L
.От L
, Git работает в обратном направлении до K
, затем J
, а затем H
.От I
, Git работает в обратном направлении до H
.(То есть, какая ветвь коммит H
или что-то до H
, например G
, в? В Git они находятся на обеих ветвях одновременно . Это одна из нескольких вещей, которая делаетGit совершенно своеобразен по сравнению с большинством других систем контроля версий.)
Поскольку каждый коммит содержит полный снимок каждого файла, вы можете удивиться, как Git может избежать использования всего вашего дискового пространства.Ответ заключается в том, что файлы, хранящиеся в коммитах, хранятся в специальном сжатом формате Git-only.Более того, после сохранения в Git каждая версия файла замораживается - только для чтения, сохраняется на все времена - поэтому каждый коммит, который использует такую же версию файла, может просто повторно использовать сжатый, только для Git, замороженный файл.
Рабочее дерево 1069 * - это просто место, где Git расширяет эти файлы до их обычной повседневной формы.Это позволяет вам работать с ними, отсюда и название «рабочее дерево» или «рабочее дерево».A git checkout
выбирает коммит - вы говорите , который коммит вы хотите, и Git извлекает этот коммит в ваше рабочее дерево.Тогда этот коммит ваш текущий коммит .Текущий коммит имеет специальное имя @
или HEAD
.Обычно Git прикрепляет слово HEAD
к имени ветви, а затем @
- это коммит, на который указывает имя ветви:
I <-- master
/
...--G--H
\
J--K--L <-- xo-wip (HEAD)
Текущий коммит - HEAD
или @
-теперь коммит L
.
Вы также можете поместить в свое рабочее дерево файлы, которые не хранятся в Git.Эти файлы не отслеживаются , и если файл не отслеживается, Git обычно будет жаловаться на него, поэтому вы можете пометить определенные неотслеживаемые файлы как игнорируемые .(Вы не можете игнорировать отслеживаемый файл, только неотслеживаемый файл.)
Индекс, или промежуточная область
Слово-картинка выше (и буквальное изображение коммитов) не включают в себя что-либо, называемое индексом или областью подготовки.Это потому, что индекс Git, по крайней мере, в целом, невидим - это не то, что вы можете просматривать непосредственно. 1 Фактически, когда вы знаете, что такое индекс, вы можете задаться вопросом, почемуGit есть один на всех.Другие системы контроля версий без них обходятся.Хотя у Git это есть, и, если это имеет смысл, образно пихает его в лицо, скрывая.:-) Вы должны работать с ним.
Самое простое объяснение индекса - это то место, где вы строите следующий коммит.Он находится "между" текущим коммитом и рабочим деревом.Он содержит копию каждого файла из текущего коммита в том же специальном сжатом формате Git, который Git использует внутри коммитов.Важно отметить, что индексная копия файла доступна для записи , в отличие от фиксированной фиксированной версии.
1 Вы можете просмотреть индекс напрямую, используя git ls-files --stage
.Однако во многих репозиториях это нецелесообразно, потому что он находит каждый файл, а это не то, что нас волнует.
Таким образом, когда вы git checkout master
или git checkout xo-lib
,Git в действительности начинается с заполнения индекса всеми файлами последнего коммита master
или xo-lib
.Другими словами, он получает замороженную копию файла в индекс.Кроме того, он также заполняет рабочее дерево, расширяя замороженную копию в удобную для использования форму.Когда это будет сделано, в вашем рабочем дереве есть все ваши файлы, готовые к использованию.
Как только вы сделаете изменения для вашего рабочего дерева, вашего индекса и рабочего дерева сейчасотличаются. Это когда вы ставите файлы, используя git add
.Все это делает копирование версии рабочего дерева в индекс.Git сжимает файл в специальный формат Git-only и заменяет все, что было в индексе, новой копией.Если файл полностью новый - если не было индексной копии - это помещает файл в индекс.
Если версия файла в рабочем дереве отличается от индексной версии этого файла, Git говорит, чтоэтот файл не подготовлен для фиксации .Если файл рабочего дерева соответствует версии индекса, но версия индекса не соответствует версии HEAD
, Git сообщает, что этот файл подготовлен для фиксации .Возможно, что файл будет отличаться в во всех трех версиях, и в этом случае он будет одновременно и не в стадии!Вы не получите этого с git add
, так как add
означает копировать версию рабочего дерева в индекс , после чего они будут соответствовать.
Как работает git commit
,включая замораживание индекса
Секрет скорости Git в том, что в индексе есть все, что нужно для следующего коммита.Команда git commit
просто должна собрать ваше сообщение журнала, затем заморозить все файлы индекса и связать их с новым коммитом.Как только это будет сделано, новый коммит и индекс совпадут, потому что новый коммит сделан из индекса.
Родительский коммит нового коммита - это текущий текущий коммит.Предполагая, что мы находимся на коммите L
, как показано выше, мы сделаем новый коммит M
:
...--L <-- xo-wip (HEAD)
\
M
, а затем Git обновит текущее имя ветви , в этом случаеxo-wip
, к которому прикреплен HEAD
, так что он указывает на наш новый коммит M
:
...--L--M <-- xo-wip (HEAD)
Поскольку M
было сделано из индекса, M
замороженные файлы соответствуют индексу.По определению нет ничего, что можно было бы удалить из-за того, что все, что Git называл «подготовленным» - все, где индексная копия какого-либо файла отличалась от копии, записанной в L
, - теперь заморожено в текущем коммите M
.Все остальные файлы, в которых совпадают L
и M
, также сохранены в M
: они просто доступны.Индекс готов к работе и большему количеству коммитов.