Хранилище файлов репозитория удаленного сервера Git

#git #bitbucket

#git #bitbucket

Вопрос:

Скоро я буду работать над рядом приложений для iPhone / iPad и собираюсь использовать Git в качестве своей системы контроля версий. В прошлых проектах (но не на базе iOS) Я использовал SVN. Мое главное решение для перехода на Git — децентрализованная структура.

Я буду использовать удаленный сервер в качестве центрального репозитория Git (скорее всего, bitbucket от Atlassian). Я еще не настроил это, но тем временем я тестировал Git локально.

Я прочитал ряд ресурсов для начинающих и теперь довольно хорошо разбираюсь в основах, но есть одна вещь, которую мне нужно подтвердить, что я правильно понимаю.

В приведенном ниже примере я использую локальную версию Git на моем Mac.

Я создал локальный репозиторий git под названием git_test. В этом репозитории у меня есть два фиктивных файла с именами file1 и file2. Я понимаю, что это мой рабочий каталог, который содержит мои реальные файлы (а не большие двоичные объекты).

Я также понимаю, что центральное хранилище на удаленном сервере должно быть пустым и не содержать фактических файлов рабочего каталога.

Давайте предположим, что у меня есть два пользователя (пользователь A и Пользователь B) с идентичными локальными репозиториями.

Пользователь A

  • Изменяет file1
  • Фиксирует file1
  • Выполняет отправку в удаленный репозиторий

Пользователь B

  • Изменяет file2
  • Фиксирует file2
  • Выполняет отправку в удаленный репозиторий

Правильно ли я говорю, что новые большие двоичные объекты загружаются в каталог .git/objects в удаленном репозитории?

Затем, когда пользователь A и Пользователь B выполняют команду извлечения в своих локальных системах, фактический файл, а не большой двоичный объект, обновляется содержимым нового большого объекта. Это правильно?

Извините за многословный вопрос. Я просто надеюсь, что все имеет смысл.

Ответ №1:

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

В вашем примере пользователь A локально генерирует коммит, пользователь B локально генерирует коммит, оба они были основаны на master на простой репозитории, который указывал бы на объект фиксации (скажем) commitBase. Это означает, что у обоих из них есть родительский элемент commitBase.

Когда пользователь выполняет нажатие, он помещает свою фиксацию в пустой репозиторий, который перемещает указатель главной ветви вверх на фиксацию. Вся информация о file1 находится внутри объекта фиксации commitA (наряду с информацией об остальной файловой структуре).

Перед запуском B он должен сначала внести изменения для commitA в свое репозиторий, потому что указатель удаленной главной ветви больше не указывает на commitBase. Он не может нажать, пока не синхронизируется с пультом дистанционного управления по объектам фиксации и указателям ветвей. Таким образом, когда он получает объект commitA в свой репозиторий, он собирается получить fileA как часть этого, который появится в его файловой системе, если он выполнит извлечение или перебазирование, но получит объект commit только в свой репозиторий (не файл в свой рабочий каталог), если он выполнит выборку. Fetch просто обновляет git внутренне с помощью новых объектов фиксации, не изменяя ваш собственный указатель главной ветви. Именно в момент слияния / перебазирования git придется принять некоторые решения о файлах в рабочем каталоге, например, легко ли объединять обычные файлы, или новые файлы можно просто поместить на диск, или если конфликт слишком велик, и вам придется вручную разрешать конфликты в файлах.

В вашем простом примере у вас нет конфликта, поэтому вы должны либо перебазировать и сделать так, чтобы ваш commitA стал commitA2 и имел родительский элемент commitB, либо объединить и сохранить родительский элемент вашего объекта commitA в качестве commitBase, но сгенерировать новый объект commitM, который является результатом слияния B и A.

То, как git внутренне представляет это в своем каталоге .git / objects в любом из 3 репозиториев, на данный момент не имеет значения. Возможно, он сжимает и перемещает содержимое, чтобы максимально увеличить базу данных всех этих объектов по своему усмотрению, но это не то, о чем я когда-либо беспокоился, пытаясь понять, как работают объекты фиксации в файлах.

Ответ №2:

Когда вы нажимаете на удаленный репозиторий, он отклонит его, если ваш локальный репозиторий отстает от удаленного репозитория

Не уверен, что это отвечает на ваш вопрос

Это гарантирует, что вы не попытаетесь изменить файл, который уже был изменен — это заставляет вас извлекать последние изменения заранее

Также, когда вы переходите к своему локальному репозиторию, да, фактический файл изменяется — в репозитории git, я полагаю, создается новый файл diff iirc, но я могу ошибаться, все, что я знаю, это то, что на самом деле он не перезаписывает файлы удаленно

Комментарии:

1. Большое спасибо, это проясняет мое замешательство.

2. Если @DanZimm ответил на ваш вопрос, не могли бы вы, пожалуйста, отметить ответ как правильный?