Какие элементы из локального каталога .git копируются на / с пульта при нажатии / извлечении? - PullRequest
0 голосов
/ 06 февраля 2019
  1. Когда вы push отправляете в удаленный репозиторий, какие элементы из локального каталога .git копируются в удаленный каталог .git?

  2. Тот же вопрос в обратном направлении, когда вы выполняете fetch.

Ответы [ 3 ]

0 голосов
/ 06 февраля 2019

Во многом это детали реализации - как Git хранит информацию, а не какая информация Git хранит информацию.Таким образом, это не имеет значения: все, что вы знаете о каком-то другом Git-репозитории, это , что он покажет вам, что у него , а не , где он помещен .

Тем не менее, вТипичная настройка, то, что находится на каком-то удаленном устройстве, это еще один Git-репозиторий, такой же, как ваш.Фактически, с их точки зрения, вы пульт. Они являются реальными вещами, вы клон.С вашей точки зрения, они клон и вы реальная вещь.С точки зрения внешнего наблюдателя, ваш клон и его клон - это всего лишь два независимых репозитория Git.

Когда вы запускаете git push, ваш Git вызывает свой Git, а ваш Git и Git ведут разговор.У этого разговора есть конечная цель, и если мы начнем там и будем работать задом наперед, это будет иметь больше смысла.Конечная цель состоит в том, чтобы вы хотели, чтобы их Git установил одно из их имен (имя ветви или тега в их хранилище) для запоминания одного конкретного коммита.Таким образом, вы собираетесь отправить им вежливый запрос или принудительную команду в форме: установите refs/heads/master для фиксации хеш-идентификатора a123456....

(Это имя можетбыть чем-либо, включая имя, которое у них уже есть, или имя, которого у них еще нет. Правила принятия / отклонения зависят от написания имени и того, есть ли у него его, но зависят от получающего Git. Обычнополучателям не нравятся имена, которые плохо известны = например, refs/heads/*, refs/tags/*, refs/notes/*. GitHub отклонит любую попытку, например, установить refs/pull/* имя.)

Они могут отказаться - даже если вы отправите команду, а не вежливый запрос - но если они этого не сделают, они должны иметь коммит a123456... в своем хранилище.Так что, как часть этого разговора, ваш Git предложит этот коммит им.Они либо скажут У меня уже есть это , либо Да, я хотел бы это .Если коммит a123456... зависит от любого более раннего коммита (ов), то, имея их в качестве своих родителей, ваш Git теперь должен также предложить своему Git эти коммиты.Если эти коммиты зависят от более ранних коммитов, ваш Git должен продолжать предлагать им больше коммитов до тех пор, пока вы не достигнете точки, в которой коммиты, которые вы предлагаете, уже есть, или вы предлагаете каждый свой коммит (в зависимости от того, что наступит первым).1052 *

Чтобы дать другому Git коммит, вы также должны давать ему каждый файл , который в , который фиксирует, если - опять же - у них уже нет этой версии этого файла.Таким образом, кое-что из этого также входит в разговор, хотя многое из этого подразумевается: если они не имеют коммита X , но имеют коммит W , тогда у них определенно есть все файлыкоторые находятся в W , многие из которых, вероятно, точно такие же в X , поэтому нет необходимости отправлять их, даже если мы отправляем коммит X .

Итак, это самая ранняя часть разговора, после того, как ваши два Gits подключены: вы предлагаете им некоторые коммиты и файлы по хеш-идентификатору.Они выбирают, какой из них они хотят, а какой уже имеют, и затем ваш Git упаковывает эти объекты.

ThosОбъекты - внутренняя форма хранения Git коммитов, деревьев, файлов и аннотированных тегов - могут находиться в вашем каталоге .git/objects/ или могут быть упакованы в файл пакета в вашем каталоге..git/objects/pack/ подкаталог.Но вы не предлагаете им файлов , обычно.(Точные данные зависят от транспортного протокола.) Вместо этого, как правило, ваш Git создает новый пакет специального «прореженного» типа, называемый thin pack.Ваш мерзавец отправляет свои мерзавцы тонкой пачкой.Их Git откармливает его в обычную упаковку.Если они в конце концов примут все ваши коммиты и файлы, они, вероятно, просто поместят этот пакет в свой подкаталог .git/objects/pack/, хотя вы никогда не узнаете наверняка, потому что в будущем разговоре с ними ваш Git и их Git будутговорите только о объектах , по их хэш-идентификаторам.

(Они могут также полностью разорвать откормленную упаковку и создать новые пакеты, которые более эффективны, чем просто добавление в откормленную версиютонкий пакет. Опять же, вы никогда не узнаете, если не сможете войти на другой компьютер и покопаться в его каталоге .git.)

Наконец, когда они примут все, что собираютсяпримите и выполнив ваш запрос или команду, чтобы они установили свои refs/heads/<em>whatever</em>, они обновят свою копию этой ссылки, однако сохранят ее: как файл в .git/refs/heads/, возможно, или как запись базы данных в некоторой справочной базе данных, иливозможно, что-то совсем другое.

Короткий ответ, таким образом, что, как правило, нет .git файлы получают скопировано напрямую .Вместо этого информация повторно упаковывается в подходящий «проводной формат», доставляется таким образом, а затем повторно упаковывается в подходящий «формат хранения».

То же самое относится к git fetch, за исключением того, что вв начале разговора у вашего Git есть список Git, их имена и хэш-идентификаторы;их Git предлагает ваши объекты по хеш-идентификатору, а ваш говорит, что хочет / должен иметь эти идентификаторы;и, в конце концов, они никогда не отправляют вам никаких запросов или команд.Вместо этого, получив свои объекты, ваш Git обновляет ваши имена для удаленного слежения , и именно так ваш Git запоминает то, что их Git сказал, что их refs/heads/master было: это становится вашим refs/remotes/origin/master, вашей памятью об их refs/heads/master.

0 голосов
/ 06 февраля 2019

Во время операций fetch или push обычно используются две вещи: объекты и ссылки.Обратите внимание, что принимающее хранилище может хранить данный фрагмент информации в файле, отличном от того, где отправляющий сервер хранил этот фрагмент информации.

Объекты включают в себя коммиты, объекты «дерево» (которые представляют каталоги содержимого) и «блоб»объекты (которые представляют отдельные файлы содержимого), среди прочего.Вместе они составляют историю вашего проекта.Они хранятся в .git / objects в «свободной» форме (файл на объект, в каталогах / файлах, имена которых получены из идентификатора объекта - который является хешем SHA данных объекта) или в «упакованной» форме (вфайл в .git / objects / packs). Передачи между репозиториями используют упакованную форму, и принимающее репо может реорганизовать свои пакеты, если сочтет нужным.

Ссылки - это ветки, теги и другие вещи;они обеспечивают «точки входа» в историю.Они хранятся в «свободной» форме в .git / refs или в упакованном виде в файле pack-refs.Не только локально свободный ссылка может быть упакована на принимающей стороне, но в зависимости от refspec, используемого для совместного использования ссылки, удаленный может обновить совершенно другой ref (например, при получении вы обычно обновляете отслеживающий ref, чтобы соответствовать ветви удаленного)

0 голосов
/ 06 февраля 2019

Когда мы создаем (используя git init) или клонируем git-репо из апстрима, каталог git create .git, который содержит так много информации о нашем локальном репо с нашим удаленным репо, помогает нам контролировать версию нашего кода.Если мы удалим каталог .git, то получим fatal: Not a git repository (or any of the parent directories): .git

Я не думаю, что у нас есть каталог .git в удаленном репо, я думаю, что каталог .git находится только в нашем локальном репо, которыйиспользуется для отслеживания веток, коммитов, пользовательских настроек, добавления удаленных репозиториев ... У нас есть только файл .gitignore в удаленном репо, если мы добавим его для игнорирования файлов ...

Если вы заглянете внутрь .git каталог вы можете увидеть следующие файлы и папки ...

├── HEAD
├── branches
├── config
├── description
├── hooks
│ ├── pre-commit.sample
│ ├── pre-push.sample
│ └── ...
├── info
│ └── exclude
├── objects
│ ├── info
│ └── pack
└── refs
 ├── heads
 └── tags
...