Перейти к содержимому

Как клонировать определенный коммит git

  • автор:

Как клонировать только нужный коммит сабмодуля?

Хочу использовать определённый коммит сабмодуля как зависимость. Если просто написать git submodule update —init —recursive , то происходит (насколько я понимаю) клонирование всего репозитория и обычный чекаут на коммит из .gitmodules . Но если указать git submodule update —init —recursive —depth=1 , то клонирование проходит гораздо быстрее, но дальше как будто ещё докачивается нужный коммит (в выводе есть Receiving objects) и происходит чекаут. Правда ли, что опция —depth=1 клонирует последний + нужный коммит? Но как тогда гит без истории определяет нужный коммит? Если да, то можно ли клонировать только 1 нужный коммит без последнего? Если это так, то почему бы всегда не использовать эту опцию, если не нужна история репозитория?

Отслеживать
задан 18 июл 2023 в 10:14

дальше как будто ещё докачивается нужный коммит (в выводе есть Receiving objects) и происходит чекаут объекты — это и есть то, из чего создаётся «working directory». так что можете расслабиться — скачивается только один коммит. и только те объекты, на которые он ссылается, чтобы можно было создать «working directory».

18 июл 2023 в 10:19

@aleksandrbarakin но как без истории коммитов гит понимает, как клонировать только 1 нужный коммит? Исходя из доков, —depth=1 делает shallow clone глубины 1, т.е. получает только последний коммит в репозитории. Как после этого мы можем сделать чекаут на рандомный коммит, если у нас нет истории? Если мы так можем сделать, то почему —depth=1 не дефолтная опция тогда?

18 июл 2023 в 10:26

получает только последний коммит в репозитории — не последний, а тот, который вы указали. вы же указали коммит при подключении под-модуля (пусть и неявно). вот он и будет получен. а хэш нужного коммита можно узнать, совершенно ничего и не сохраняя, простым запросом: ru.stackoverflow.com/a/541635/178576

18 июл 2023 в 10:35

Как после этого мы можем сделать чекаут на рандомный коммит, если у нас нет истории? — мы в любой момент можем сделать fetch нужного коммита, при необходимости — с указанной глубиной. ну а потом просто распаковать полученные объекты в рабочий каталог.

A3.2 Приложение C: Команды Git — Клонирование и создание репозиториев

Существует два способа создать Git репозиторий. Первый — клонировать его из существующего репозитория (например, по сети); второй — создать репозиторий в существующем каталоге.

git init

Чтобы превратить обычный каталог в Git репозиторий и начать версионировать файлы в нём, просто запустите git init .

Впервые мы продемонстрировали эту команду в разделе Создание Git-репозитория главы 2 на примере создания нового репозитория для последующей работы с ним.

Мы немного поговорили о смене названия ветки по умолчанию с «master» на что-нибудь другое в разделе Удалённые ветки главы 3.

Мы использовали эту команду для создания чистого репозитория для работы на стороне сервера в разделе Размещение голого репозитория на сервере главы 4.

Ну и наконец мы немного покопались во внутренностях этой команды в разделе Сантехника и Фарфор главы 10.

git clone

На самом деле git clone работает как обёртка над некоторыми другими командами. Она создаёт новый каталог, переходит внутрь и выполняет git init для создания пустого репозитория, затем она добавляет новый удалённый репозиторий ( git remote add ) для указанного URL (по умолчанию он получит имя origin ), выполняет git fetch для этого репозитория и, наконец, извлекает последний коммит в ваш рабочий каталог, используя git checkout .

Команда git clone используется в десятке различных мест в этой книге, но мы перечислим наиболее интересные упоминания.

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

В разделе Установка Git на сервер главы 4 мы рассмотрели как использовать опцию —bare , чтобы создать копию Git репозитория без рабочей копии.

В разделе Создание пакетов главы 7 мы использовали git clone для распаковки упакованного с помощью git bundle репозитория.

Наконец, в разделе Клонирование проекта с подмодулями главы 7 мы научились использовать опцию —recursive чтобы упростить клонирование репозитория с подмодулями.

И хотя git clone используется во многих других местах в книге, перечисленные выше так или иначе отличаются от других вариантов использования.

Клонирование и коммиты репозиториев – Git

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

Git ー популярная платформа для работы с версиями проекта. Это ー распределенная система контроля версий или VCS (Version Control System). Version Control в данном случае означает, что в любой момент можно вернуться к нужной версии документа. А под распределённостью имеется ввиду, что системой может одновременно пользоваться множество специалистов.

Кстати, Git уже давно вышел за рамки применения только в IT-компаниях. Им пользуются и в других направлениях, где есть командная работа над техническими проектами.

Области данных в Git

Чтобы легче понять работу команд, кратко разберем области данных. В системе Git их три: рабочая директория, индекс, репозиторий.

Рабочая директория содержит в себе файлы, с которыми работаете. Также это могут быть файлы, только что извлеченные из истории проекта. При переключении между ветками файлы в Working Directory можно удалять или изменять. По этому поводу переживать не нужно, так как история сохранена в Git-директории. А рабочая директория ー временное место для работы с файлами.

Git-индекс ー промежуточная локация для изменения файлов на пути от рабочей директории к репозиторию. Здесь хранятся изменения между уже зафиксированными в репозитории данными и теми, что еще лежат в рабочей директории. После выполнения команды git commit информация из индекса переходит в репозиторий с соответствующими ссылками.

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

Базовые команды: checkout git

В работе с репозиторием под командой checkout git (git checkout) подразумевается переключение между версиями для трех видов объектов. К ним относятся файлы, коммиты и ветки. Кроме функции переключения между branches, это действие используется и для просмотра старых commits.
Как происходит переключение веток? Процесс аналогичен шифтингу между старыми коммитами и документами, где каталог обновляется по выбранной ветке (или ревизии). При этом новые изменения остаются в истории, потому что операция checkout git ー это не только функция чтения.

Глава 4. Все о клонировании

В старых системах управления версиями стандартная операция для получения файлов — это checkout. Вы получаете набор файлов в конкретном сохраненном состоянии.

В Git и других распределенных системах управления версиями стандартный способ — клонирование. Для получение файлов вы создаете «клон» всего хранилища. Другими словами, вы фактически создаете зеркало центрального сервера. При этом всё, что можно делать с основным хранилищем, можно делать и с локальным.

Синхронизация компьютеров

Я вполне приемлю создание архивов или использование rsync для резервного копирования и простейшей синхронизации. Но я работаю то на ноутбуке, то на стационарном компьютере, которые могут никак между собой не взаимодействовать между этим.

Создайте хранилище Git и закоммитьте файлы на одном компьютере. А потом выполните на другом

$ git clone первый.компьютер:/путь/к/файлам

для создания второго экземпляра файлов и хранилища Git. С этого момента команды

$ git commit -a $ git pull другой.компьютер:/путь/к/файлам HEAD

будут «втягивать» состояние файлов с другого компьютера на тот, где вы работаете. Если вы недавно внесли конфликтующие изменения в один и тот же файл, Git даст вам знать, и нужно будет сделать коммит заново после разрешения ситуации.

Классическое управление исходным кодом

Создайте хранилище Git для ваших файлов:

$ git init $ git add . $ git commit -m "Начальный коммит"

На центральном сервере создайте так называемое «голое» (bare) хранилище Git в неком каталоге:

$ mkdir proj.git $ cd proj.git $ git init --bare $ # вариант «в одну строчку»: GIT_DIR=proj.git git init

Запустите Git-демон, если необходимо:

$ git daemon --detach # возможно уже запущен

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

Отправьте ваши изменения в центральное хранилище вот так:

$ git push git://центральный.сервер/путь/к/proj.git HEAD

Для получения ваших исходников разработчик вводит

$ git clone git://центральный.сервер/путь/к/proj.git

После внесения изменений разработчик сохраняет изменения локально:

$ git commit -a

Для обновления до последней версии:

$ git pull

Любые конфликты слияния нужно разрешить и закоммитить:

$ git commit -a

Для выгрузки локальных изменений в центральное хранилище:

$ git push

Если на главном сервере были новые изменения, сделанные другими разработчиками, команда push не сработает. В этом случае разработчику нужно будет вытянуть к себе (pull) последнюю версию, разрешить возможные конфликты слияний и попробовать еще раз.

Голые (bare) хранилища

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

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

Многие команды Git не работают в голых хранилищах, если переменная среды GIT_DIR не содержит путь до хранилища и не указан параметр —bare.

Push или pull?

Зачем вводится команда push, вместо использования уже знакомой pull? Прежде всего, pull не работает в голых хранилищах, вместо нее нужно использовать команду fetch, которая будет рассмотрена позже. Но даже если держать на центральном сервере нормальное хранилище, использование команды pull в нем будет затруднительным. Нужно будет сначала войти на сервер интерактивно и сообщить команде pull адрес машины, с которой мы хотим забрать изменения. Этому могут мешать сетевые брандмауэры (firewall), но в первую очередь: что если у нас нет интерактивного доступа к серверу?

Тем не менее, не рекомендутся push-ить в хранилище помимо этого случая — из-за путаницы, которая может возникнуть, если у целевого хранилища есть рабочий каталог.

Короче говоря, пока изучаете Git, push-те только в голые хранилища. В остальных случаях pull-те.

Создание форка проекта

Не нравится путь развития проекта? Думаете, можете сделать лучше? Тогда на вашем сервере выполните

$ git clone git://основной.сервер/путь/к/файлам

Теперь расскажите всем о форке (ответвлении, прим. пер.) проекта на вашем сервере.

Позже вы сможете в любой момент втянуть к себе изменения из первоначального проекта:

$ git pull

Максимальные бэкапы

Хотите иметь множество защищенных, географически разнесенных запасных архивов? Если в вашем проекте много разработчиков, ничего делать не нужно! Каждый клон — это и есть резервная копия; не только текущего состояния, но и всей истории изменений проекта. Благодаря криптографическому хешированию, повреждение какого-либо из клонов будет обнаружено при первой же попытке взаимодействия с другими клонами.

Если ваш проект не такой популярный, найдите как можно больше серверов для размещения клонов.

Особо беспокоящимся рекомендуется всегда записывать самый последний 20-байтный SHA1 хеш HEAD в каком-нибудь безопасном месте. Оно должно быть безопасным, а не тайным. Например, хороший вариант — публикация в газете, потому что атакующему сложно изменить каждый экземпляр газеты.

Многозадачность со скоростью света

Скажем, вы хотите работать над несколькими функциями параллельно. Тогда закоммитьте ваши изменения и запустите

$ git clone . /некий/новый/каталог

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

Теперь вы можете работать с двумя независимыми функциями одновременно. Например, можно редактировать один клон, пока другой компилируется. В любой момент можно сделать коммит и вытянуть изменения из другого клона:

$ git pull /другой/клон HEAD

Партизанское управление версиями

Вы работаете над проектом, который использует другую систему управления версиями, и вам очень не хватает Git? Тогда создайте хранилище Git в своем рабочем каталоге:

$ git init $ git add . $ git commit -m "Начальный коммит"

затем склонируйте его:

$ git clone . /некий/новый/каталог

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

$ git add . $ git commit -m "Синхронизация с остальными"

Теперь перейдите в новый каталог и запустите

$ git commit -a -m "Описание моих изменений" $ git pull

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

Subversion (вероятно, наилучшая централизованная система управления версиями) используется неисчислимым множеством проектов. Команда git svn автоматизирует описанный процесс для хранилищ Subversion, а также может быть использована для экспорта проекта Git в хранилище Subversion.

Mercurial

Mercurial — похожая система управления версиями, которая может работать в паре с Git практически без накладок. С расширением hg-git пользователь Mercurial может без каких либо потерь push-ить и pull-ить из хранилища Git.

Получить hg-git можно с помощью Git:

$ git clone git://github.com/schacon/hg-git.git
$ hg clone http://bitbucket.org/durin42/hg-git/

К сожалению, мне неизвестен аналогичное расширение для Git. Поэтому я рекомендую использовать Git, а не Mercurial, для центрального хранилища, даже если вы предпочитаете Mercurial. Для проектов, использующих Mercurial, обычно какой-нибудь доброволец поддерживает параллельное хранилище Git для привлечения пользователей последнего, тогда как проекты, использующие Git, благодаря hg-git автоматически доступны пользователям Mercurial.

Хотя расширение может сконвертировать хранилище Mercurial в Git путем push’а в пустое хранилище, эту задачу легче решить, используя сценарий hg-fast-export.sh, доступный как

$ git clone git://repo.or.cz/fast-export.git

Для преобразования выполните в пустом каталоге

$ git init $ hg-fast-export.sh -r /hg/repo

после добавления сценария в ваш $PATH.

Bazaar

Упомянем вкратце Bazaar, так как это самая популярная свободная распределенная система управления версиями после Git и Mercurial.

Bazaar относительно молод, поэтому у него есть преимущество идущего следом. Его проектировщики могут учиться на ошибках предшественников и избавиться от исторически сложившихся неровностей. Кроме того, его разработчики заботятся о переносимости и взаимодействии с другими системами управления версиями.

Расширение bzr-git позволяет (в какой-то степени) пользователям Bazaar работать с хранилищами Git. Программа tailor конвертирует хранилища Bazaar в Git и может делать это с накоплением, тогда как bzr-fast-export хорошо приспособлена для разовых преобразований.

Почему я использую Git

Изначально я выбрал Git потому, что слышал, что он в состоянии справиться с совершенно неуправляемыми исходными текстами ядра Linux. Я никогда не ощущал потребности сменить его на что-то другое. Git работает замечательно и мне еще только предстоит напороться на его недостатки. Так как я в основном использую Linux, проблемы на других системах меня не касаются.

Я также предпочитаю программы на C и сценарии на bash исполняемым файлам вроде сценариев на Python-е: у них меньше зависимостей, и я привык к быстрому выполнению.

Я думал о том, как можно улучшить Git, вплоть до того, чтобы написать собственный инструмент, похожий на Git; но только как академическое упражнение. Завершив проект, я бы все равно продолжил пользоваться Git, потому что выигрыш слишком мал, чтобы оправдать использование самодельной системы.

Естественно, ваши потребности и пожелания вероятно отличаются от моих и вы, возможно, лучше уживетесь с другой системой. И всё же вы не слишком ошибетесь, используя Git.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *