Все главы учебника
Содержание учебника
Глава 06 / Git

Удалённый репозиторий без сети: bare и два клона

16 мин чтенияКонтент v0.10.0

Как дать историю другому рабочему месту

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

Обычный клон содержит рабочие файлы и историю. Bare-репозиторий хранит историю и ссылки без рабочего дерева для редактирования. Именно такой формат удобен для общей точки, в которую отправляют изменения. Не открывайте bare как папку исходников и не пытайтесь писать там README рядом с его служебными файлами. Clone объясняет различие создаваемых репозиториев.

Имя remote, например origin, — локальное сокращение пути или URL. Оно не является веткой. origin/main — локальная ссылка наблюдения за веткой main в origin. После обмена она отражает последнее известное состояние, а не постоянно синхронизируется в фоне. Ваш main и origin/main могут указывать на разные коммиты; это нормальная причина для последующей проверки.

Подготовьте общую точку

lab=$(mktemp -d "${TMPDIR:-/tmp}/git-06.XXXXXX")
git init --bare -b main "$lab/shared.git"
git init -b main "$lab/author"
cd "$lab/author"
git config user.name "Учебный автор"
git config user.email "learner@example.invalid"
git config commit.gpgsign false
printf 'Local collaboration\n' > README.txt
git add README.txt
git commit -m "Add shared project description"
git remote add origin "$lab/shared.git"
git remote -v
git push -u origin main
git clone "$lab/shared.git" "$lab/reviewer"
cd "$lab/reviewer"
git status --short
git log --oneline
cat README.txt

В reviewer должна быть одна запись и тот же README. Пустой status означает чистый клон. При init bare мы явно выбрали main, чтобы его HEAD указывал на ожидаемую начальную ветку. Иначе после публикации другой ветки клон мог получить историю, но не выбрать нужные рабочие файлы автоматически.

Push отправил объекты и обновил ветку общей точки; -u назначил для локального main связь с origin/main. Эта связь называется upstream и используется командами без явно указанной ветки. Пока в reviewer не будет коммитов, автора настраивать необязательно. Перед его собственной записью задайте локальное учебное имя и email, как в author.

Посмотрите bare без редактирования его внутренностей:

git --git-dir="$lab/shared.git" log --oneline --all
git --git-dir="$lab/shared.git" rev-parse --is-bare-repository
git remote -v
git branch -vv

Первая команда читает историю общей точки, вторая выводит true. Последние команды относятся к текущему reviewer и показывают его путь origin и связь веток. --git-dir нужен именно для выбранного bare; не добавляйте его механически ко всем будущим командам.

Git и хостинг имеют разные задачи

В GitHub или другом хостинге вместо локального пути используют URL, а доступ на запись требует аутентификации. Имя автора коммита не выдаёт право push. SSH-ключи и токены относятся к каналу доступа, а не к содержимому снимка. В обязательном пути вам не нужен ни один из этих секретов.

Если хотите дополнительную практику, создайте свой пустой тестовый репозиторий GitHub и следуйте его официальной инструкции подключения. Не отправляйте лаборатории в чужие проекты. GitHub Skills можно пройти отдельно после локальной части; результат курса не зависит от доступности аккаунта.

Проверьте независимость клонов

После создания reviewer измените его рабочий README, но не делайте коммит и push. Должна ли правка появиться в author? Нет. Даже локальный путь origin не превращает два дерева в одну совместно открываемую папку. Затем сохраните изменение только в reviewer и опять посмотрите author: история автора тоже пока прежняя. Потребуется явный обмен. Это наблюдение отделяет обычное редактирование, сохранение коммита и передачу между репозиториями.

Запишите для трёх состояний, где находятся байты правки: только в рабочем файле reviewer, затем в его локальном коммите, затем после push в shared. Копия author появится после получения и интеграции. Если все папки расположены рядом на диске, модель не меняется. Заодно проверьте, что удаление имени remote из одного клона не удалило бы соседний bare: это настройка связи, а не владение общей точкой. Такой мысленный опыт помогает читать будущие сообщения об отсутствии origin без страха, что исчезла вся история.

Самостоятельная лаборатория

Выделите 30–45 минут. Создайте bare и два обычных клона в новой временной папке. В первом опубликуйте описание проекта и файл лимитов. Второй клонируйте после публикации. Сравните вершины main через git rev-parse main, содержимое файлов и список remote.

Проверьте, что в bare нет рабочего settings.txt, но git --git-dir=... show main:settings.txt читает его из снимка. Запишите три пути и роль каждого. Не называйте второй клон «веткой первого»: это независимый репозиторий со своей локальной историей, который может обмениваться объектами.

Критерии готовности

Вы создаёте общую точку без сети, публикуете main и получаете чистый второй клон. Объясняете origin, origin/main, локальный main и upstream. Можете прочитать историю bare, не открывая его как проект с исходниками. Ни одна команда не требует аккаунта или отправки личных данных.

Разбор

Вершины двух main сразу после clone совпадают. Bare хранит коммит, но не развёрнутый файл рядом с служебными папками. Если клон предупреждает про remote HEAD, проверьте начальное имя ветки bare и реально опубликованную ветку. Если push не нашёл origin, вы настроили remote в другой рабочей папке.

Локальная общая точка не резервная копия на другом устройстве: все три папки здесь зависят от одного диска. Сетевой хостинг решает другую часть задачи, но не отменяет внимательного выбора файлов.

Дальше отделим получение истории от её интеграции. Первичные источники: clone, push и глоссарий.