Урок курса

Remote, origin и первый clone

Git и GitHub с нуля: бесплатный курс с практикой

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

Remote как именованная ссылка на другой репозиторий

Remote — это сохранённый адрес другого репозитория Git. Не живое соединение, не копия файлов, не синхронизированная папка — просто строка с именем и адресом, которую хранит ваш локальный репозиторий.

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

Адрес remote может быть:

  • путём к папке на том же компьютере (../remote/shared.git)
  • путём на сетевом диске
  • URL до сервера (https://github.com/user/repo.git или git@github.com:user/repo.git)

С точки зрения Git это всё одно и то же. Разница только в транспортном протоколе, но команды, которые вы пишете, выглядят одинаково независимо от того, находится remote в соседней папке или на другом конце интернета.

Один локальный репозиторий может знать несколько remote-ов, у каждого своё имя. Имя нужно, чтобы в командах не писать полный адрес каждый раз — используют короткое человекочитаемое слово вместо длинного пути или URL.

Bare-репозиторий и origin: хранилище без рабочей папки и имя по умолчанию

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

Bare-репозиторий — только первый слой. В нём есть вся история Git: коммиты, ветки, объекты — но нет рабочей папки с файлами. В bare-репозиторий нельзя зайти и отредактировать README.md напрямую. Зато в него можно отправлять коммиты и получать их — именно для этого bare используется как общее хранилище.

По соглашению папки bare-репозиториев называют с суффиксом .git. В этом уроке роль учебного сервера играет папка remote/shared.git внутри распакованного архива git_practice. Это не настоящий GitHub и не сетевой сервер — просто подготовленное хранилище на вашем компьютере, с которым Git работает точно так же, как работал бы с удалённым сервером.

Когда вы клонируете репозиторий командой git clone, Git автоматически регистрирует источник как remote и даёт ему имя origin. Это соглашение, а не часть синтаксиса языка — технически remote можно назвать как угодно, но origin настолько распространено, что его используют по умолчанию везде. Имя хранит адрес источника и используется в командах вместо полного пути или URL.

git clone: полная история коммитов и автоматическая регистрация origin

При копировании только рабочих файлов без .git вы получаете текущее содержимое проекта без истории Git. Если скопировать всю папку вместе с .git, история сохранится. Команда git clone создаёт новый репозиторий с историей коммитов источника, получает его ветки как remote-tracking записи и автоматически регистрирует источник под именем origin.

После clone ваш локальный репозиторий самодостаточен: он может работать автономно, показывать git log, переключаться между состояниями — и при этом знает, откуда был создан, потому что адрес источника автоматически сохраняется под именем origin.

Синтаксис:

git clone <путь-или-URL> <имя-новой-папки>

Если второй аргумент не указать, Git создаст папку с именем репозитория. Для учебного сценария распакуйте весь выданный git_practice.zip в новую отдельную папку через файловый менеджер. Внутри появится git_practice, а в ней — подготовленный remote/shared.git с начальной веткой main и одним коммитом. Папки my_clone в свежей распаковке ещё нет. Откройте терминал в новой папке распаковки, перейдите в git_practice и клонируйте:

cd git_practice
git clone remote/shared.git my_clone
cd my_clone

Git выведет:

Cloning into 'my_clone'...
done.

Что произошло внутри:

  1. Создана папка my_clone.
  2. В ней инициализирован Git-репозиторий.
  3. Скопирована вся история коммитов из remote/shared.git.
  4. Адрес источника сохранён под именем origin.
  5. Создана и выбрана локальная ветка main, соответствующая начальной ветке источника.

Последний пункт важен: ветка называется main потому, что именно так называется начальная ветка в учебном shared.git. Имя определяет источник, а не Git сам по себе.

После cd my_clone вы находитесь в полноценном репозитории с историей. git log --oneline покажет коммит, который пришёл из shared.git.

git remote -v и git branch -r: что хранит клон о своём источнике

Находясь внутри my_clone, выполните:

git remote -v

Вывод будет выглядеть примерно так:

origin  /полный/путь/до/git_practice/remote/shared.git (fetch)
origin  /полный/путь/до/git_practice/remote/shared.git (push)

Две строки с origin — это один и тот же remote. Метки (fetch) и (push) показывают адрес в разрезе направлений обмена: откуда получать данные и куда отправлять. Обе строки указывают на shared.git. Заметьте, что Git мог нормализовать относительный путь remote/shared.git, который вы передали при clone, в абсолютный — это нормально, смысл от этого не меняется.

Команда git branch -r выводит remote-tracking записи, которые хранит этот клон:

git branch -r

Вывод:

  origin/HEAD -> origin/main
  origin/main

Флаг -r показывает remote-tracking ветки. origin/main — это не то же самое, что локальная main, хотя прямо сейчас они указывают на один и тот же коммит.

Различие принципиальное:

  • Локальная main — обычная ветка, которой вы управляете. Вы создаёте в ней новые коммиты, переключаетесь на неё, редактируете файлы.
  • origin/main — локальная запись о том, где находилась ветка main в shared.git в момент последнего контакта с ним (в данном случае — при clone).

Это не живой указатель на текущее состояние remote, а снимок того, что клон знал на момент последнего обмена. Редактировать origin/main напрямую нельзя.

Если сделать новый коммит в my_clone, локальная main сдвинется вперёд, а origin/main останется на месте — там, где была ветка в shared.git при clone. Именно это расхождение между двумя указателями позволяет Git понимать, что локальная история ушла вперёд относительно remote.

Проверить текущее состояние:

git status

Вывод:

On branch main
Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean

Фраза up to date with 'origin/main' означает именно это: локальная main и последнее известное положение origin/main совпадают. Как только они разойдутся, git status сообщит об этом явно.

Задача 1

Обычный полный clone завершён: локальная main и origin/main показывают А. В этом clone сделали локальный коммит Б, обмена с origin после clone не было. Где теперь указатели?

Выберите один вариант
Без регистрации · результат не сохраняется

Задача 2

Самостоятельная практика:
Распакуйте git_practice.zip. В папке git_practice/remote/shared.git находится учебный bare-репозиторий с одной веткой main.

Задача:

  1. Перейдите в папку git_practice.
  2. Клонируйте remote/shared.git в папку my_clone командой git clone.
  3. Перейдите в my_clone.
  4. Выполните git remote -v и запишите, какой путь указан для origin.
  5. Выполните git branch -r и запишите, какие remote-tracking ветки видны.
  6. Выполните git log --oneline и убедитесь, что история клона содержит коммит из remote-а.
  7. Выполните git status и проверьте, на какой ветке находится HEAD.

Доступный API: git clone, git remote -v, git branch -r, git log --oneline, git status, cd.
Ожидаемый результат: вывод каждой из четырёх команд проверки (шаги 4–7).

Письменное объяснение:
Коллега говорит: «Я выполнил git clone и теперь вижу в git branch -r строку origin/main. Но в git branch (без флагов) тоже есть main. Это один и тот же указатель или два разных? И зачем их два, если они оба показывают один коммит?»

Объясните коллеге:

  1. Чем локальная main отличается от origin/main по назначению.
  2. Почему после clone они указывают на один коммит и что произойдёт с каждой из них после того, как коллега сделает новый локальный коммит.

Платформа проверяет только ответ ниже; действия в своём репозитории и письменные ответы вы проверяете самостоятельно.

Контрольный случай:
После clone remote -v показывает абсолютный путь к выданному shared.git, хотя при clone ввели относительный путь. Branch -r содержит origin/main, status показывает main и чистое состояние. Что это означает?

Выберите один вариант
Без регистрации · результат не сохраняется

Продолжить с сохранением прогресса

Перейдите к уроку в учебном кабинете.

Перейти к интерактивному уроку