Работа с удалёнными репозиториями в Git: команды pull, push и fetch

Введение

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

Одной из ключевых возможностей Git является работа с удалёнными репозиториями. Обычно код проекта хранится на сервере (например, GitHub, GitLab или Bitbucket), а разработчики синхронизируют свои локальные копии с этим сервером.

Для взаимодействия с удалённым репозиторием используются три основные команды:

  1. git fetch — получение изменений из удалённого репозитория
  2. git pull — получение изменений и их объединение с локальной веткой
  3. git push — отправка локальных изменений в удалённый репозиторий

Понимание принципов работы этих команд важно для правильного управления историей проекта и предотвращения конфликтов при совместной работе.

Команда git fetch

Команда git fetch используется для загрузки новых изменений из удалённого репозитория. При этом она не изменяет текущую локальную ветку и не объединяет скачанные изменения с рабочим каталогом.

Фактически команда выполняет синхронизацию информации о состоянии удалённого репозитория, обновляя ссылки на удалённые ветки.

Это делает команду безопасной, поскольку она позволяет сначала посмотреть изменения, а затем решить, как именно их объединять с локальной веткой.

Пример использования

git fetch origin

После выполнения этой команды Git скачает все новые коммиты из удалённого репозитория origin.

Однако текущая ветка не изменится. Например, если посмотреть историю:

git log —oneline —graph —all

можно увидеть, что обновилась ветка origin/main, но локальная ветка main осталась прежней.

Для объединения изменений необходимо выполнить:

git merge origin/main

Основные флаги git fetch

—all

Загружает изменения из всех удалённых репозиториев.

git fetch —all

—prune

Удаляет локальные ссылки на удалённые ветки, которые были удалены на сервере. Это полезно для поддержания чистоты списка веток.

git fetch —prune

—dry-run

Показывает, какие изменения будут загружены, не выполняя фактическую операцию.

git fetch —dry-run

Команда git pull

Команда git pull используется для получения изменений из удалённого репозитория и их автоматического объединения с текущей веткой.

Команда является комбинацией двух операций:

git fetch

git merge

Таким образом, git pull сначала загружает новые коммиты, а затем объединяет их с локальной веткой.

Пример использования

git pull origin main

Эта команда:

  1. скачивает изменения из удалённой ветки main
  2. объединяет их с текущей локальной веткой

Почему при git pull появляется merge-коммит

Иногда после выполнения git pull в истории появляется merge-коммит. Это происходит в случае, если и локальная, и удалённая ветки содержат уникальные коммиты. D и E – уникальные коммиты в локальной ветке Feature:

После выполнения git pull Git создаст новый коммит объединения. Коммит M называется merge commit и фиксирует результат объединения двух веток.

Основные флаги git pull

—rebase

Позволяет выполнить перебазирование вместо merge. В этом случае локальные коммиты будут перенесены поверх обновлённой удалённой ветки.

git pull —rebase

—ff-only

Разрешает обновление ветки только в случае fast-forward. Если требуется merge-коммит, операция будет отменена.

git pull —ff-only

—no-commit

Выполняет merge, но не создаёт коммит автоматически. Это позволяет сначала проверить изменения.git pull —no-commit

Команда git push

Команда git push используется для отправки локальных коммитов в удалённый репозиторий.

Она синхронизирует историю локальной ветки с соответствующей веткой на сервере.

Пример использования

git push origin main

После выполнения этой команды все новые коммиты будут отправлены на сервер.

Основные флаги git push

-u или —set-upstream

Устанавливает связь между локальной и удалённой веткой.

git push -u origin main

После этого можно использовать просто:

git push

—force

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

git push —force

—force-with-lease

Более безопасная версия —force. Git проверит, изменялась ли удалённая ветка после последнего получения данных.

git push —force-with-lease

Пример использования git push –force

Предположим, что история на сервере выглядит следующим образом:

Локально разработчик выполнил:

git reset —hard B

После этого история стала:

Обычный push выполнить нельзя, так как история ветки отличается.

Поэтому используется:

git push —force

После этого удалённая ветка будет переписана.

Различие между git merge и git pull —rebase

git merge

Команда merge объединяет две ветки и создаёт отдельный merge-коммит.

Преимуществом такого подхода является сохранение полной истории развития веток.

Однако история может становиться менее читаемой из-за большого количества merge-коммитов.

git pull —rebase

При использовании rebase локальные коммиты переносятся поверх обновлённой удалённой ветки.

До выполнения команды:

После выполнения:

git pull –rebaseобновляет локальную ветку, забирая изменения из удаленного репозитория, а затем переносит локальные коммиты поверх полученных. В отличие от стандартного pull, она не создает коммит слияния (merge commit), делая историю линейной и чистой.

Различие между git reset и git revert

git reset

Команда git reset используется для перемещения указателя HEAD на другой коммит.

При этом коммиты могут исчезнуть из истории.

Пример:

После выполнения:

git reset —hard B

История станет:

Коммит C будет удалён.

git revert

Команда git revert не удаляет коммит, а создаёт новый коммит, который отменяет изменения предыдущего.

Пример:

Коммит D отменяет изменения коммита C. Git создал новый коммит, который эти изменения полностью отменяет. Этот новый коммит был добавлен в конец текущей ветки, став её новым указателем. Исходный коммит остался в истории, но его эффект полностью удален последующим отменяющим коммитом.

Режимы команды git reset

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

Git оперирует тремя основными состояниями:

  1. HEAD — указатель на текущий коммит
  2. Index (staging area) — область подготовленных изменений
  3. Working directory — рабочая директория проекта

git reset —soft

Изменяет только положение HEAD.

Команда:

git reset —soft HEAD~1

Последний коммит будет удалён из истории, но изменения останутся в staging area.

git reset —mixed

Это режим по умолчанию.

Команда:

git reset HEAD~1

В этом случае:

  1. HEAD перемещается
  2. изменения удаляются из staging area
  3. файлы остаются изменёнными

git reset —hard

Самый радикальный режим.

git reset —hard HEAD~1

В этом случае:

  1. HEAD перемещается
  2. staging area очищается
  3. рабочий каталог возвращается к состоянию выбранного коммита

Все незакоммиченные изменения будут потеряны.

Заключение

Команды git fetch, git pull и git push являются основными инструментами для синхронизации локального и удалённого репозиториев. Они позволяют разработчикам обмениваться изменениями и поддерживать актуальную версию проекта.