Очевидно, C:\files\programming\workspaces\project1
не является репозиторием Git.
Это правда, что Y:\git\myrepo.git
- это репозиторий Git (при условии, что ранее работал git init
). Но C:\files\programming\workspaces\project1
нет. Вам нужно будет создать второй репозиторий Git. 1 Например, вы можете git clone
пустой репозиторий в Y:\git\myrepo.git
(хотя клонирование полностью пустого репозитория имеет некоторые странные побочные эффекты и обычно это не правильный способ запуска).
В общем случае Git работает так:
Вы клонируете целый существующий репозиторий: каждый коммит, который сохраняет каждая версия каждого файла теперь копируется в каталог .git
здесь.
Git - действительно все об этих коммитах. Каждый коммит имеет полный и полный снимок каждого файла, сохраненный в специальном формате только для чтения, Git, а также некоторую дополнительную информацию, например, кто сделал коммит, когда и почему. Эти коммиты действуют как архивы: каждый раз, когда кто-то запускает git commit
, Git в архиве все . 2 Теперь у вас есть копия все , в этом специальном формат Achival, который может использовать только Git.
Каждый коммит имеет свой уникальный идентификатор ha sh. Никакие две коммиты никогда не могут делиться ID. По этой причине и из-за того факта, что каждый Git в мире должен предоставить каждому уникальному идентификатору ha sh, эти идентификаторы должны быть очень большими, уродливыми и случайными. Все Гиты повсюду делятся га sh идентификаторами для всех своих коммитов, так что они могут поделиться своими коммитами по ID, позже. Вы можете соединить любые два Gits друг с другом, и они могут получить коммиты друг друга, просто используя эти идентификаторы ha sh.
Поскольку эти идентификаторы ha sh такие большие и уродливые, люди не могут получить они правы. К счастью, мы не должны; мы увидим это чуть позже.
Затем - это фактически встроено, как последний шаг из git clone
, который вы только что сделали - у вас есть Git выберите некоторый коммит. Этот выбранный коммит становится текущим коммитом .
Обычно вы выбираете коммит, выбирая имя ветви , и в этом случае это имя становится текущим именем ветви , т. Е. Эти два действия спарены: выбор ветви master
в качестве текущей ветви выбирает последний коммит в этой ветви в качестве текущего коммита.
(есть дополнительная сложность при выполнении этого начального git clone
, опять же, но мы пока пропустим его.)
Git сейчас извлекает все файлы из выбранного коммита, в рабочую область. В этой рабочей области у вас есть обычные файлы, которые вы можете использовать со всеми обычными программами на вашем компьютере. Это ваши файлы, с которыми вы будете работать sh: они вовсе не являются копиями Git. Git просто извлек все из коммита, чтобы сделать эти копии доступными.
Как только у вас есть все рабочие копии файлов, хранящиеся в этой рабочей области , который мы называем рабочим деревом или рабочим деревом , вы можете работать с ними. Вот почему это ваше рабочее дерево: потому что вы на самом деле можете выполнить некоторую работу.
Поработав над кучей файлов, вы можете сохранить новый сохраненный за все время архивный снимок. Вы можете подумать, что можете просто запустить git commit
, а Git сохранит все ваши файлы. Другие системы контроля версий работают таким образом, но Git - нет. Git содержит в секретном файле 3 сохраненные все файлы, полученные из текущего коммита. Эти файлы представлены в специальном Git -только замороженном формате, но в отличие от копий файлов, которые находятся в коммитах, на самом деле они не заморожены . Вы можете заменить их, или полностью удалить некоторые файлы, или вставить новые.
Git называет эту специальную дополнительную область index , или промежуточная область , а иногда - редко в наши дни - кеш . Эти три имени для этой единственной вещи отражают ее центральные и множественные роли в Git, или, возможно, есть три имени, потому что оригинальное имя, «индекс», просто ужасно. :-) Но в любом случае вам нужно знать об индексе.
По существу - и не упоминая некоторые другие его роли - что представляет собой индекс и что он представляет собой next , обязывающее вас сделаю. То есть он содержит в специальном формате Git -specifi c некоторую информацию о вашем текущем рабочем дереве, но, что более важно, копию каждого файла, которая будет go в следующем коммите. 4
Обновив файлы рабочего дерева, вам необходимо скопировать эти файлы обратно в индекс Git, что вы делаете с git add
:
git add file1 folder/file2
например. 5 Это копирует эти два файла из вашего рабочего дерева в указатель, превращая копии в специальный Git формат, готовый go в следующий коммит. Другими словами, эти файлы теперь подготовлены для коммита , отсюда и другое название индекса - «область подготовки». На самом деле они еще не совершены , но они готовы к go. (Они были готовы к go и раньше, но раньше они соответствовали копии текущего коммита!)
На этом этапе выполнение git commit
создает новый коммит из любых файлов в индексе прямо сейчас . Этот новый коммит получает ваше имя и адрес электронной почты как автора и коммиттера, а «сейчас» - текущую дату и время, сообщаемое вашей ОС - как метки времени. Вы должны предоставить лог-сообщение с указанием причины того, что вы сделали коммит: краткое изложение почему вы делаете все, что делаете. 6
Команда git commit
упаковывает всю эту информацию - кто, когда, почему и т. Д. - вместе с необработанным идентификатором ha sh текущего текущего коммита и создает новый коммит из это плюс снимок, который он делает, используя файлы, которые уже имеют правильный формат в индексе Git. Теперь, когда новый коммит сделан, он становится текущим коммитом. Теперь все вернулось к тому, что было, когда вы запустили git checkout
: и индекс, и текущий коммит содержат одинаковый набор файлов в формате замороженного архива, готовый к go в новый коммит.
Обратите внимание, что никаких изменений коммита не было. Фактически, ни один из существующих Git commit не может когда-либо измениться. Все коммиты заморожены на все время, только для чтения. Они продолжают существовать до тех пор, пока вы и Git сможете найти их - обычно навсегда, но вы можете договориться о "потере" одного, если вы сделали тот, который вам не нравится.
Способ Git находит коммитов важен и немного сложен. Однако, как только вы это освоите, на самом деле все будет очень просто.
1 Это может быть единственный репозиторий, который вам нужен: непонятно, зачем вам нужен пустой и во-первых, в Y:\git\myrepo.git
.
2 Точнее, Git заархивировал все, что было сказано, в архив, как мы увидим через мгновение.
3 Это не совсем секрет вообще, но вы не можете увидеть это очень хорошо: оно спрятано в специально отформатированном файле в .git
с именем index
(и, возможно, и с других мест, но все они начинаются с индексного файла; индексный файл содержит записи, и некоторые из них могут содержать другие файлы).
4 Технически, то, что находится в индексе в этих записях кэша , это путь к файлу, режим и внутренний Git блоб ха sh ID . Также имеется номер промежуточного слота , который действительно используется только для слияния. Идентификатор ha sh означает, что вместо хранения фактической копии каждого файла индекс просто содержит запись объекта блоба, отформатированного Git. Но если вы не начнете использовать git ls-files --stage
и git update-index
напрямую, вам не нужно знать об этом: вы можете просто думать об индексе как о хранении копии каждого файла.
5 Вы можете использовать либо forward sla sh как этот, либо обратную косую черту; обе работают. Я не использую Windows, и всегда использую forward sla sh, и несколько раз, когда я был вынужден кратко использовать Windows, я всегда называю свои файлы там с косой чертой. (Это в основном работает, за исключением нескольких команд, которые настаивают на том, что они переключают параметры. При работе с Git и его экосистемой backsla sh имеет тенденцию путать некоторые другие программы: \b
, например, может представлять Backspace и \t
вкладка, поэтому попытка присвоить файлу имя .\buttons\toggle
может дать сбой, и в результате вы получите файл с именем .^Huttons^Toggle
или чем-то еще.)
6 Git может легко показать , что вы сделали позже, но Git даже не подозревает, что это было, например, чтобы исправить ошибку # 12345 или проблему # 97, или что бы то ни было, тем более как ошибка или проблема может быть описана. Это сообщение журнала - это ваша возможность объяснить, например, что такое ошибка, где ее найти в системе сообщений об ошибках, что вы обнаружили во время исследования ошибки, и что-нибудь еще, что может быть полезно вам или кому-то еще, глядя на этот коммит позже.
Имена ветвей позволяют Git найти коммиты для вас
Имя ветки, подобное master
, в Git, на самом деле просто содержит one га sh ID.
Это все, что нужно сделать. Ранее мы упоминали, что всякий раз, когда вы Git делаете новый коммит, новый коммит сохраняет необработанный га sh ID текущего коммита.
Предположим у вас есть Git репозиторий с одним коммитом. Этот коммит имеет какой-то большой уродливый идентификатор sh, но мы просто назовем его A
для краткости:
A
В репозитории только один коммит. Этот коммит имеет много файлов, но это всего лишь один коммит. Его легко найти: это коммит . Давайте теперь добавим второй коммит, получив этот коммит с именем master
- мы поместим имя в одно мгновение.
Мы изменим некоторые файлы рабочего дерева, git add
их, и запустите git commit
и укажите причину для фиксации в сообщении журнала. Git создает новый коммит из всех файлов в индексе, плюс обычные метаданные, в том числе ha sh ID коммита A
. Давайте назовем новый коммит B
и нарисуем его сейчас:
A <-B
B
содержит идентификатор ha sh старого коммита. Мы говорим, что B
указывает на A
.
Git записывает новый коммит ха sh ID в имя master
, поэтому давайте нарисуем имя master
, указывающее на B
сейчас:
A--B <-- master
Я уже стал ленивым (нарочно): это B
, которое указывает на A
, а не наоборот. Но стрелка, выходящая из B
, не может измениться, потому что никакая часть любого коммита не может измениться. Это стрелка, выходящая из master
, которая меняется. Мы называем commit A
родителем B
, а B
дочерним A
.
Текущей ветвью теперь является master
, а текущим коммитом - B
. Давайте сделаем новый коммит обычным способом:
A--B--C <-- master
Новый коммит C
указывает на B
, что указывает на A
. Так что B
может быть потомком A
, но также является родителем C
.
(Куда указывает A
? Ответ: нигде. Коммит A
немного немного особенный. Будучи самым первым коммитом, он не может указывать на какой-либо более ранний коммит. Так что это просто не так. Создание первого коммита в репозитории является чем-то особенным; создает имя ветви тоже! Имя master
не может существовать, пока не существует какой-либо коммит, поэтому создание коммита A
создает все.)
(я продолжаю говорить ребенок , а не ребенок . Это потому, что мы можем go вернуться и добавить еще детей позже. Когда-то сделанные комитеты заморожены на все времена, поэтому дети точно знают, кто их родители Есть, но родители могут приобрести новых детей, когда-нибудь, в будущем. Когда создается новый коммит, у него никогда не бывает потомков , но . Поэтому родители никогда не знают, кто их дети. Вот почему Git работает задом наперед!)
Обратите внимание, что все, что нам нужно, это Git для хранения необработанного (и случайного вида) га sh идентификатора последнего коммита во имя master
. Мы можем вспомнить имя master
, а Git помнит идентификатор ha sh для нас. Добавление нового коммита состоит из:
- , удостоверяющих, что текущее имя ветви равно
master
(git checkout master
при необходимости) - , чтобы текущий commit - это
C
- , так что
a123456...
index содержит Git полных правильных копий файлов и нашего рабочего дерева есть файлы, которые мы хотим - , чтобы мы могли изменить файлы рабочего дерева на месте, используя все обычные компьютерные инструменты
- , чтобы мы могли
git add
обновленные файлы, чтобы сделать Git скопируйте их обратно в индекс - , чтобы мы могли
git commit
сделать новый коммит D
, который изменит наш рисунок на:
A--B--C--D <-- master
Все эти новые коммиты go в нашем хранилище . Сам репозиторий состоит в основном из двух больших баз данных:
- коммитов и других внутренних Git объектов, адресованных идентификаторами ha sh;
- и меньшего размера name-to-ha sh -ID таблица, которая говорит что-то вроде имя ветки
master
означает фиксацию *1338* или что-либо еще.
Весь репозиторий находится в каталоге / папке .git
под верхним уровнем нашего рабочего дерева. Имена ветвей находят последний коммит, а эти коммиты находят более ранние коммиты. Git просто идет назад, от последнего коммита обратно к первому, один коммит за раз. Git знает, что у него закончились коммиты, чтобы пройти назад, когда он достигает root коммитов, таких как коммит A
, у которого нет родителя.
Существует много больше, чем это, начиная с того факта, что вы можете добавить больше имен ветвей: например,
A--B--C--D <-- master, dev
, перемещать имена ветвей и т. д., и мы даже не затронули идею подключения этого Git хранилища в C:\files\programming\workspaces\project1
к другому Git хранилищу в Y:\git\myrepo.git
или на другом компьютере или еще где-либо. Вот где все усложняется. Вот для чего git remote
: remote - это имя, которое вы используете в вашем Git, чтобы запомнить URL для какого-либо другого Git хранилища.
Если вам пока не нужно использовать пульты, не делайте этого; это достаточно для начала.