Что такое git clone

git clone

Назначение: создание копии проекта для совместной работы в разных репозиториях

Совместная работа в разных репозиториях

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

Поэтому совместная работа в Git принципиально отличается от совместной работы в SVN. В SVN работа строится на отношении между центральным репозиторием и рабочей копией, а модель совместной работы в Git основана на взаимодействии между репозиториями. Вместо загрузки рабочей копии в центральный репозиторий SVN в Git вы отправляете коммиты из одного репозитория в другой с помощью команды push или копируете их в обратном направлении с помощью команды pull.

Что такое git clone. Смотреть фото Что такое git clone. Смотреть картинку Что такое git clone. Картинка про Что такое git clone. Фото Что такое git clone Что такое git clone. Смотреть фото Что такое git clone. Смотреть картинку Что такое git clone. Картинка про Что такое git clone. Фото Что такое git clone

Вы легко можете задавать особую роль определенным репозиториям Git. Например, обозначив один из репозиториев Git как «центральный», вы можете воспроизвести централизованный рабочий процесс с использованием Git. Однако такой подход требует договоренностей, поскольку он не встроен в саму систему контроля версий

Использование

Чаще всего с помощью команды git clone выбирается существующий репозиторий и создается его клон или копия. Это делается в новом каталоге и в другом месте. Исходный репозиторий может находиться в локальной файловой системе или на удаленном устройстве, к которому можно получить доступ с помощью поддерживаемых протоколов. Команда git clone копирует существующий репозиторий Git. Она похожа на команду SVN checkout, но имеет некоторые отличия: так, полученная «рабочая копия» представляет собой полноценный репозиторий Git с собственной историей и файлами, полностью обособленный от исходного репозитория.

Клонирование в конкретную папку

Клонирование репозитория из в директорию

! на локальной машине.

Клонирование конкретного тега

Поверхностное клонирование

Варианты конфигурации

В примере выше клонируется только ветка new_feature из удаленного репозитория Git. Эта опция нужна исключительно для удобства, чтобы не тратить время на получение ссылки HEAD в репозитории и извлечение необходимой ссылки.

Другие варианты конфигурации

Исчерпывающий список опций git clone приведен в официальной документации по Git. В этом документе будут рассмотрены в том числе и другие распространенные опции.

URL-адреса в Git

В Git используется особый синтаксис URL-адресов, с помощью которого в команде можно задать расположение удаленных репозиториев. Поскольку команда git clone чаще всего используется в работе с удаленными репозиториями, здесь будет рассмотрен синтаксис URL-адресов в Git.

URL-протоколы в Git

Secure Shell (SSH) — это популярный сетевой протокол, обеспечивающий защищенную аутентификацию. Большинство серверов настроены для работы с ним по умолчанию. Из-за специфики протокола для входа на центральный сервер вам нужно знать учетные данные. ssh://[user@]host.xz[:port]/path/to/repo.git/

— GIT

Уникальный протокол Git. Вместе с Git поставляется специальный демон, который использует отдельный порт (9418). Этот протокол похож на SSH, однако GIT НЕ ОБЛАДАЕТ средствами аутентификации. git://host.xz[:port]/path/to/repo.git/

— HTTP

Протокол для передачи гипертекста. Этот протокол повсеместно используется во Всемирной паутине. Чаще всего применяется для передачи данных веб-страниц в формате HTML через Интернет. Git можно настроить для работы по HTTP. http[s]://host.xz[:port]/path/to/repo.git/

Резюме

1. Команда git clone предназначена для создания копии целевого репозитория.

2. Целевой репозиторий может находиться в локальной системе или на удаленном устройстве.

3. Git поддерживает несколько сетевых протоколов для установки соединения с удаленными репозиториями.

4. Существует множество вариантов конфигурации команды, которые позволяют изменять содержание копии.

Подробные сведения о возможностях git clone см. в официальной документации по Git. Примеры использования команды git clone на практике также можно найти в нашем руководстве по настройке репозитория.

Готовы изучить Git?

Ознакомьтесь с этим интерактивным обучающим руководством.

Источник

2. Основы работы с Git¶

Введение¶

Система спроектирована как набор программ, специально разработанных с учётом их использования в скриптах. Это позволяет удобно создавать специализированные системы контроля версий на базе Git или пользовательские интерфейсы. Например, Cogito является именно таким примером фронтенда к репозиториям Git, а StGit использует Git для управления коллекцией патчей.

Git поддерживает быстрое разделение и слияние версий, включает инструменты для визуализации и навигации по нелинейной истории разработки. Как и Darcs, BitKeeper, Mercurial, SVK, Bazaar и Monotone, Git предоставляет каждому разработчику локальную копию всей истории разработки; изменения копируются из одного репозитория в другой.

Удалённый доступ к репозиториям Git обеспечивается git-daemon, gitosis, SSH- или HTTP-сервером. TCP-сервис git-daemon входит в дистрибутив Git и является наряду с SSH наиболее распространённым и надёжным методом доступа. Метод доступа по HTTP, несмотря на ряд ограничений, очень популярен в контролируемых сетях, потому что позволяет использовать существующие конфигурации сетевых фильтров.

Основы работы с удаленным репозиторием¶

git clone — создание копии (удаленного) репозитория¶

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

Клонируем репозиторий, используя протокол http:

Клонируем репозиторий с той же машины в директорию myrepo :

Клонируем репозиторий, используя безопасный протокол ssh:

У git имеется и собственный протокол:

Импортируем svn репозиторий, используя протокол http:

-s – понимать стандартные папки SVN (trunk, branches, tags)

git fetch и git pull — забираем изменения из центрального репозитория¶

Для синхронизации текущей ветки с репозиторием используются команды git fetch и git pull.

git fetch — забрать изменения удаленной ветки из репозитория по умолчания, основной ветки; той, которая была использована при клонировании репозитория. Изменения обновят удаленную ветку (remote tracking branch), после чего надо будет провести слияние с локальной ветку командой git merge.

git fetch /home/username/project — забрать изменения из определенного репозитория.

Возможно также использовать синонимы для адресов, создаваемые командой git remote :

git fetch username-project — забрать изменения по адресу, определяемому синонимом.

Команда git pull сразу забирает изменения и проводит слияние с активной веткой.

Забрать из репозитория, для которого были созданы удаленные ветки по умолчанию:

Забрать изменения и метки из определенного репозитория:

git push — вносим изменения в удаленный репозиторий¶

После проведения работы в экспериментальной ветке, слияния с основной, необходимо обновить удаленный репозиторий (удаленную ветку). Для этого используется команда git push.

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

Отправить изменения из ветки master в ветку experimental удаленного репозитория:

В удаленном репозитории origin удалить ветку experimental:

В удаленную ветку master репозитория origin (синоним репозитория по умолчанию) ветки локальной ветки master:

Отправить метки в удаленную ветку master репозитория origin:

Изменить указатель для удаленной ветки master репозитория origin (master будет такой же как и develop)

Добавить ветку test в удаленный репозиторий origin, указывающую на коммит ветки develop:

Работа с локальным репозиторием¶

Базовые команды¶

git init — создание репозитория

git add и git rm — индексация изменений

индексация измененного файла, либо оповещение о создании нового:

внести в индекс все изменения, включая новые файлы:

Из индекса и дерева проекта одновременно файл можно удалить командой git rm :

хороший пример удаления из документации к git, удаляются сразу все файлы txt из папки:

внести в индекс все удаленные файлы:

Сбросить весь индекс или удалить из него изменения определенного файла можно
командой git reset :

сбросить весь индекс:

удалить из индекса конкретный файл:

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

git status — состояние проекта, измененные и не добавленные файлы, индексированные файлы

Кроме того, git status указывает на файлы с неразрешенными конфликтами слияния и
файлы, игнорируемые git.

git commit — совершение коммита

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

Есть несколько ключей, упрощающих работу с git commit :
совершит коммит, автоматически индексируя изменения в файлах проекта. Новые файлы при этом индексироваться не будут! Удаление же файлов будет учтено.
комментируем коммит прямо из командной строки вместо текстового редактора.
внесет в индекс и создаст коммит на основе изменений единственного файла.

git reset — возврат к определенному коммиту, откат изменений, «жесткий» или «мягкий»

Помимо работы с индексом (см. выше), git reset позволяет сбросить состояние проекта до какого-либо коммита в истории. В git данное действие может быть двух видов: «мягкого»(soft reset) и «жесткого» (hard reset).

Обратите внимание на обозначение HEAD^, оно означает «обратиться к предку последнего коммита». Подробней описан синтаксис такой относительной адресации будет ниже, в разделе «Хэши, тэги, относительная адресация». Соответственно, HEAD — ссылка на последний коммит. Ссылка ORIG_HEAD после «мягкого» резета указывает на оригинальный коммит.

Естественно, можно вернуться и на большую глубину коммитов,

Если команда достигнет точки ветвления, удаления коммита не произойдет.

Для команд слияния или выкачивания последних изменений с удаленного репозитория
примеры резета будут приведены в соответствующих разделах.

git revert — отмена изменений, произведенных в прошлом отдельным коммитом

Возможна ситуация, в которой требуется отменить изменения, внесенные отдельным коммитом. git revert создает новый коммит, накладывающий обратные изменения.

Отменяем коммит, помеченный тегом:

Отменяем коммит, используя его хэш:

Для использования команды необходимо, чтобы состояние проекта не отличалось от состояния, зафиксированного последним коммитом.

git log — разнообразная информация о коммитах в целом

Простейший пример использования, в котором приводится короткая справка по всем
коммитам, коснувшимся активной в настоящий момент ветки (о ветках и ветвлении
подробно узнать можно ниже, в разделе «Ветвления и слияния»):

За информацию по созданиям, переименованиям и правам доступа файлов отвечает ключ
—summary :

Чтобы просмотреть историю отдельного файла, достаточно указать в виде параметра
его имя (кстати, в моей старой версии git этот способ не срабатывает,
обязательно добавлять » — » перед «README»):

или, если версия git не совсем свежая:

Далее будет приводится только более современный вариант синтаксиса. Возможно
указывать время, начиная в определенного момента («weeks», «days», «hours», «s»
и так далее):

изменения, касающиеся отдельной папки:

Можно отталкиваться от тегов.

Все коммиты, начиная с тега v1:

Все коммиты, включающие изменения файла README, начиная с тега v1:

Все коммиты, включающие изменения файла README, начиная с тега v1 и заканчивая тегом v2:

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

Лаконичная информация о коммитах, приводятся только автор и комментарий:

Более полная информация о коммитах, с именем автора, комментарием, датой создания и внесения коммита:

В принципе, формат вывода можно определить самостоятельно:

git diff — отличия между деревьями проекта, коммитами и т.д.

Показать изменения, не внесенные в индекс:

Изменения, внесенные в индекс:

Изменения в проекте по сравнению с последним коммитом:

Можно сравнивать «головы» веток:

или активную ветку с какой-либо:

git show — показать изменения, внесенные отдельным коммитом

Посмотреть изменения, внесенные любым коммитом в истории, можно командой git show :

git blame и git annotate — команды, помогающие отслеживать изменения файлов

Можно указать и конкретные строки для отображения:

git grep — поиск слов по проекту, состоянию проекта в прошлом

Поиск слова tst в проекте:

Подсчитать число упоминаний tst в проекте:

Поиск в старой версии проекта:

Команда позволяет использовать логическое И и ИЛИ.

Найти строки, где упоминаются и первое слово, и второе:

Найти строки, где встречается хотя бы одно из слов:

Ветвление¶

git branch — создание, перечисление и удаление веток

Работа с ветками — очень легкая процедура в git, все необходимые механизмы сконцентрированы в одной команде:

Просто перечислить существующие ветки, отметив активную:

Создать новую ветку new-branch:

Удалить ветку, если та была залита (merged) с разрешением возможных конфликтов в текущую:

Удалить ветку в любом случае:

Показать те ветки, среди предков которых есть определенный коммит:

git checkout — переключение между ветками, извлечение файлов

Команда git checkout позволяет переключаться между последними коммитами (если упрощенно) веток:

Создаст ветку, в которую и произойдет переключение

Вернуть файл (или просто вытащить из прошлого коммита) позволяет команда вида:

Вернуть somefile к состоянию последнего коммита:

Вернуть somefile к состоянию на два коммита назад по ветке:

git merge — слияние веток (разрешение возможных конфликтов)

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

Попробовать объединить текующую ветку и ветку new-feature:

В случае возникновения конфликтов коммита не происходит, а по проблемным файлам расставляются специальные метки а-ля svn; сами же файлы отмечаются в индексе как «не соединенные» (unmerged). До тех пор пока проблемы не будут решены, коммит совершить будет нельзя.

Произошла неудачная попытка слияния:

Смотрим на проблемные места:

Индексируем наши изменения, тем самым снимая метки:

Совершаем коммит слияния:

Вот и все, ничего сложного. Если в процессе разрешения вы передумали разрешать конфликт, достаточно набрать (это вернёт обе ветки в исходные состояния):

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

git rebase — построение ровной линии коммитов

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

Предположим, имеется две ветки, master и topic, в каждой из которых было совершенно несколько коммитов начиная с момента ветвления. Команда git rebase берет коммиты из ветки topic и накладывает их на последний коммит ветки master.

Вариант, в котором явно указывается, что и куда накладывается:

на master накладывается активная в настоящий момент ветка:

git cherry-pick — применение к дереву проекта изменений, внесенных отдельным коммитом

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

Изменения, внесенные указанным коммитом будут применены к дереву, автоматически проиндексированы и станут коммитом в активной ветке:

Прочие команды и необходимые возможности¶

Хэш — уникальная идентификация объектов

В git для идентификации любых объектов используется уникальный (то есть с огромной вероятностью уникальный) хэш из 40 символов, который определяется хэшируюшей функцией на основе содержимого объекта. Объекты — это все: коммиты, файлы, тэги, деревья. Поскольку хэш уникален для содержимого, например, файла, то и сравнивать такие файлы очень легко — достаточно просто сравнить две строки в сорок символов.

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

найти разницу текущего состояния проекта и коммита за номером… сами видите, каким:

То же самое, но оставляем только шесть первых символов. Git поймет, о каком коммите идет речь, если не существует другого коммита с таким началом хэша:

Иногда хватает и четырех символов:

Читаем лог с коммита по коммит:

Разумеется, человеку пользоваться хэшами не так удобно, как машине, именно поэтому были введены другие объекты — тэги.

git tag — тэги как способ пометить уникальный коммит

Тэг (tag) — это объект, связанный с коммитом; хранящий ссылку на сам коммит, имя автора, собственное имя и некоторый комментарий. Кроме того, разработчик может оставлять на таких тегах собственную цифровую подпись.

Кроме этого в git представленные так называемые «легковесные тэги» (lightweight tags), состоящие только из имени и ссылки на коммит. Такие тэги, как правило, используются для упрощения навигации по дереву истории; создать их очень легко.

Создать «легковесный» тэг, связанный с последним коммитом; если тэг уже есть, то еще один создан не будет:

Пометить определенный коммит:

Создать тэг для последнего коммита, заменить существующий, если таковой уже был:

Обычные тэги имеет смысл использовать для приложения к коммиту какой-либо информации, вроде номера версии и комментария к нему. Иными словами, если в комментарии к коммиту пишешь «исправил такой-то баг», то в комментарии к тэгу по имени «v1.0» будет что-то вроде «стабильная версия, готовая к использованию».

Создать обычный тэг для последнего коммита; будет вызван текстовый редактор для составления комментария:

Создать обычный тэг, сразу указав в качестве аргумента комментарий:

Команды перечисления, удаления, перезаписи для обычных тэгов не отличаются от команд для «легковесных» тэгов.

Относительная адресация

Вместо ревизий и тэгов в качестве имени коммита можно опираться на еще один механизм — относительную адресацию. Например, можно обратиться прямо к предку последнего коммита ветки master:

Если после «птички» поставить цифру, то можно адресоваться по нескольким предкам коммитов слияния:

найти изменения по сравнению со вторым предком последнего коммита в master; HEAD здесь — указатель на последний коммит активной ветки:

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

что привнес «дедушка» нынешнего коммита:

Обозначения можно объединять, чтобы добраться до нужного коммита:

Пример содержимого такого файла:

Серверные команды репозитория¶

; git count-objects : Проверка, сколько объектов будет потеряно и объём освобождаемого места при перепаковке репозитория.
; git gc : Переупаковка локального репозитория.

Рецепты¶

Создание пустого репозитория на сервере

Импорт svn репозитория на Git-сервер

Источник

Git Wizardry

1 Введение

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

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

2 Работа с локальным репозитарием

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

2.1 Базовые команды

Базовые команды — те, без которых невозможно обойтись в разработке.

2.1.1 git init — создание репозитария

Команда git init создает в директории пустой репозитарий в виде директория
.git, где и будет в дальнейшем храниться вся информация об истории коммитов,
тегах — ходе разработки проекта:

Другой способ создать репозитарий — команда git clone, но о ней чуть позже.

2.1.2 git add и git rm — индексация изменений

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

git add EDITEDFILE — индексация измененного файла, либо оповещение о
создании нового.

git add. — внести в индекс все изменения, включая новые файлы.

Из индекса и дерева одновременно проекта файл можно удалить командой git rm:

git rm FILE1 FILE2 — отдельные файлы

git rm Documentation/\*.txt — хороший пример удаления из документации к git,
удаляются сразу все файлы txt из папки.

Сбросить весь индекс или удалить из него изменения определенного файла можно
командой git reset:

git reset — сбросить нафиг весь индекс.

git reset — EDITEDFILE — удалить из индекса конкретный файл.

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

2.1.3 git status — состояние проекта, измененные и не добавленные файлы, индексированные файлы

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

Кроме того, git status указывает файлы с неразрешенными конфликтами слияния и
файлы, игнорируемые git.

2.1.4 git commit — совершение коммита

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

Если индекс не пустой, то на его основе будет совершен коммит, после чего
пользователя попросят прокомментировать вносимые изменения вызовом команды
edit(например, в Ubuntu обычно вызывается простенький текстовый редактор nano, у
меня же — emacs). Сохраняемся, и вуала! Коммит готов.

Есть несколько ключей, упрощающих работу с git commit:

git commit FILENAME — внесет в индекс и создаст коммит на основе изменений
единственного файла.

2.1.5 git reset — возврат к определенному коммиту, откат изменений, «жесткий» или «мягкий»

Помимо работы с индексом (см. выше), git reset позволяет сбросить состояние
проекта до какого-либо коммита в истории. В git данное действие может быть двух
видов: «мягкого»(soft reset) и «жесткого» (hard reset).

«Мягкий» (с ключом «—soft») резет оставит нетронутыми ваши индекс и все дерево
файлов и директорий проекта, вернется к работе с указанным коммитом. Иными
словами, если вы обнаруживаете ошибку в только что совершенном коммите или
комментарии к нему, то легко можно исправить ситуацию:

Обратите внимание на обозначение HEAD^, оно означает «обратиться к предку
последнего коммита». Подробней описан синтаксис такой относительной адресации
будет ниже, в разделе «Хэши, тэги, относительная адресация». Соответственно,
HEAD — ссылка на последний коммит. Ссылка ORIG_HEAD после «мягкого» резета
указывает на оригинальный коммит.

Естественно, можно вернуться и на большую глубину коммитов,

1 — больше никто и никогда не увидит этот позорный коммит.

3 — вернее, три последних коммита. Никто. Никогда.

Если команда достигнет точки ветвления, удаления коммита не произойдет.

Для команд слияния или выкачивания последних изменений с удаленного репозитария
примеры резета будут приведены в соответствующих разделах.

2.1.6 git revert — отмена изменений, произведенных в прошлом отдельным коммитом

Возможна ситуация, в которой требуется отменить изменения, внесенные отдельным
коммитом. Git revert создает новый коммит, накладывающий обратные изменения:

git revert config-modify-tag — отменяем коммит, помеченный тегом.

git revert 12abacd — отменяем коммит, используя его хэш.

Для использования команды необходимо, чтобы состояние проекта не отличалось от
состояния, зафиксированного последним коммитом.

2.1.7 git log — разнообразная информация о коммитах в целом, по отдельным файлам и различной глубины погружения в историю

Иногда требуется получить информацию об истории коммитов, коммитах, изменивших
отдельный файл; коммитах за определенный отрезок времени и так далее. Для этих
целей используется команда git log.

Простейший пример использования, в котором приводится короткая справка по всем
коммитам, коснувшимся активной в настоящий момент ветки (о ветках и ветвлении
подробно узнать можно ниже, в разделе «Ветвления и слияния»):

За информацию по созданиям, переименованиям и правам доступа файлов отвечает ключ
—summary:

Для исследования истории отдельного файла достаточно указать в виде параметра
его имя (кстати, в моей старой версии git этот способ не срабатывает,
обязательно добавлять » — » перед «README»):

или, если версия git не совсем свежая:

Далее будет приводится только более современный вариант синтаксиса. Возможно
указывать время, начиная в определенного момента («weeks», «days», «hours», «s»
и так далее):

Можно отталкиваться от тегов:

git log v1… — все коммиты, начиная с тега v1.

git log v1… README — все коммиты, включающие изменения файла README, начиная с
тега v1.

git log v1..v2 README — все коммиты, включающие изменения файла README, начиная с
тега v1 и заканчивая тегом v2.

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

В принципе, формат вывода можно определить самостоятельно:

Определение формата можно поискать в разделе по git log из Git Community Book
или справке. Красивый ASCII-граф коммитов выводится с использованием ключа
—graph.

2.1.8 git diff — отличия между деревьями проекта; коммитами; состоянием индекса и каким-либо коммитом.

Своего рода подмножеством команды git log можно считать команду git diff,
определяющую изменения между объектами в проекте: деревьями (файлов и
директорий):

git diff — покажет изменения, не внесенные в индекс.

git diff HEAD — изменения в проекте по сравнению с последним коммитом

git diff HEAD^ — предпоследним коммитом

Можно сравнивать «головы» веток:

git diff master..experimental

Ну или активную ветку с какой-либо:

git diff experimental

2.1.9 git show — показать изменения, внесенные отдельным коммитом

Посмотреть изменения, внесенные любым коммитом в истории можно командой git
show:

git show COMMIT_TAG

2.1.10 git blame и git annotate — вспомогательные команды, помогающие отслеживать изменения файлов

При работе в команде часто требуется выяснить, кто именно написал конкретный
код. Удобно использовать команду git blame, выводящую построчную информацию о
последнем коммите, коснувшемся строки, имя автора и хэш коммита:

Можно указать и конкретные строки для отображения:

Аналогично работает команда git annotate, выводящая и строки, и информацию о
коммитах, их коснувшихся:

git annotate README

2.1.11 git grep — поиск слов по проекту, состоянию проекта в прошлом

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

git grep tst — поиск слова tst в проекте.

git grep tst v1 — поиск в старой версии проекта.

Команда позволяет использовать логическое И и ИЛИ:

2.2 Ветвление

Операции ветвления и слияния — сердце и душа git, именно эти возможности делают такой
удобной работу с системой.

2.2.1 git branch — создание, перечисление и удаление веток

Работа с ветками — очень легкая процедура в git, все необходимые механизмы
сконцентрированы в одной команде:

git branch — просто перечислит существующие ветки, отметив активную.

git branch new-branch — создаст новую ветку new-branch.

2.2.2 git checkout — переключение между ветками, извлечение отдельных файлов из истории коммитов

Команда git checkout позволяет переключаться между последними коммитами (если
упрощенно) веток:

Вернуть файл (или просто вытащить из прошлого коммита) позволяет команда вида:

git checkout somefile — вернуть somefile к состоянию последнего коммита
git checkout HEAD

2 somefile — вернуть somefile к состоянию на два коммита назад по ветке.

2.2.3 git merge — слияние веток (разрешение возможных конфликтов).

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

git merge new-feature — попробует объединить текующую ветку и ветку new-feature.

В случае возникновения конфликтов коммита не происходит, а по проблемным файлам
расставляются специальные метки а ля svn; сами же файлы отмечаются в индексе как
«не соединенные» (unmerged). До тех пор пока проблемы не будут решены, коммит совершить
будет нельзя.

Например, конфликт возник в файле TROUBLE, что можно увидеть в git status:

git merge experiment — произошла неудачная попытка слияния.

git status — смотрим на проблемные места.

edit TROUBLE — разрешаем проблемы.

git add. — индексируем наши изменения, тем самым снимая метки.

git commit — совершаем коммит слияния.

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

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

2.2.4 git rebase — построение ровной линии коммитов

Предположим, разработчик завел дополнительную ветку для разработки отдельной
возможности и совершил в ней несколько коммитов. Одновременно по какой-либо
причине в основной ветке также были совершены коммиты: например, в нее были
залиты изменения с удаленного сервера; либо сам разработчик совершал в ней
коммиты.

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

Предположим, имеется две ветки, master и топик, в каждой из которых было совершенно несколько коммитов начиная с момента ветвления.
Команда git rebase берет коммиты из ветки topic и накладывает их на последний коммит ветки
master:

2.2.5 git cherry-pick — применение к дереву проекта изменений, внесенных отдельным коммитом

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

git cherry-pick BUG_FIX_TAG — изменения, внесенные указанным коммитом будут
применены к дереву, автоматически проиндексированы и станут коммитом в активной
ветке.

2.3 Прочие команды и необходимые возможности

Для удобства работы с git было введено дополнительное понятие: тэг. Кроме того
дальше будет пояснена необходимость в хэшах, и его применение; показан способ
обращаться к коммитам при помощи относительной адресации.

2.3.1 Хэш — уникальная идентификация объектов

В git для идентификации любых объектов используется уникальный (то есть с
огромной вероятностью уникальный) хэш из 40 символов, который определяется
хэшируюшей функцией на основе содержимого объекта. Объекты — это все: коммиты,
файлы, тэги, деревья. Поскольку хэш уникален для содержимого, например, файла,
то и сравнивать такие файлы очень легко — достаточно просто сравнить две строки
в сорок символов.

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

git diff f292ef5d2b2f6312bc45ae49c2dc14588eef8da2 — найти разницу текущего
состояния проекта и коммита за номером… Ну сами видите, каким.

git diff f292ef5 — то же самое, но оставляем только шесть первых символов. Git
поймет, о каком коммите идет речь, если не существует другого коммита с таким
началом хэша.

git diff f292 — иногда хватает и четырех символов.

git log febc32. f292 — читаем лог с коммита по коммит.

Разумеется, человеку пользоваться хэшами не так удобно, как машине, именно поэтому были
введены другие объекты — тэги.

2.3.2 git tag — тэги как способ пометить уникальный коммит

Тэг (tag) — это объект, связанный с коммитом; хранящий ссылку на сам коммит, имя
автора, собственное имя и некоторый комментарий. Кроме того, разработчик может
оставлять на таких тегах собственную цифровую подпись.

Кроме этого в git представленные так называемые «легковесные тэги» («lightweight
tags»), состоящие только из имени и ссылки на коммит. Такие тэги, как правило,
используются для упрощения навигации по дереву истории; создать их очень легко:

git tag stable-1 — создать «легковесный» тэг, связанный с последним
коммитом. Если тэг уже есть, то еще один создан не будет.

git tag stable-2 f292ef5 — пометить определенный коммит.

После создания тэга его имя можно использовать вместо хэша в любых командах
вроде git diff, git log и так далее:

git diff stable-1.1. stable-1

Обычные тэги имеет смысл использовать для приложения к коммиту какой-либо
информации, вроде номера версии и комментария к нему. Иными словами, если в
комментарии к коммиту пишешь «исправил такой-то баг», то в комментарии к тэгу по
имени «v1.0» будет что-то вроде «стабильная версия, готовая к использованию»:

Команды перечисления, удаления, перезаписи для обычных тэгов не отличаются от
команд для «легковесных» тэгов.

2.3.3 Относительная адресация

Вместо ревизий и тэгов в качестве имени коммита можно опираться на еще один
механизм — относительную адресацию. Например, можно обратиться прямо к предку
последнего коммита ветки master:

Если после «птички» поставить цифру, то можно адресоваться по нескольким предкам
коммитов слияния:

git diff HEAD^2 — найти изменения по сравнению со вторым предком последнего
коммита в master. HEAD здесь — указатель на последний коммит активной ветки.

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

git diff master^^ — что привнес «дедушка» нынешнего коммита.

Обозначения можно объединять, чтобы добраться до нужного коммита:

Иногда по директориям проекта встречаются файлы, которые не хочется постоянно
видеть в сводке git status. Например, вспомогательные файлы текстовых
редакторов, временные файлы и прочий мусор.

Заставить git status игнорировать можно, создав в корне или глубже по дереву
(если ограничения должны быть только в определенных директория) файл
.gitignore. В этих файлах можно описывать шаблоны игнорируемых файлов
определенного формата.

Пример содержимого такого файла:

#не нужны объектники и архивы

Существуют и другие способы указания игнорируемых файлов, о которых можно узнать
из справки git help gitignore.

3 «Вместе мы — сила», или основы работы с удаленным репозитарием

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

3.1 Удаленные ветки (remote tracking branches)

Новое понятие здесь — удаленные ветки. Удаленные ветки соответствуют какой-либо
ветке (чаще master) на удаленном сервере. Одна такая создается автоматически при
создании копии удаленного репозитария; все команды, связанные с удаленной
работой, будут по умолчанию использовать именно эту удаленную ветку (обычно
называется «origin»).

Рассмотрим эти команды.

3.2 git clone — создание копии (удаленного) репозитария

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

git clone /home/username/project myrepo — клонируем репозитарий с той же машины
в директорию myrepo.

git clone ssh://user@somehost:port/

user/repository — клонируем репозитарий,
используя безопасный протокол ssh (для чего требуется завести у себя на машине
эккаунт ssh).

git clone git://user@somehost:port/

user/repository/project.git/ — у git имеется
и собственный протокол.

3.3 git fetch и git pull — забираем изменения из центрального репозитария (из удаленной ветки)

Для синхронизации текущей ветки с репозитарием используются команды git fetch и
git pull.

git fetch — забрать изменения удаленной ветки из репозитария по умолчания,
основной ветки; той, которая была использована при клонировании
репозитария. Изменения обновят удаленную ветку (remote tracking branch), после
чего надо будет провести слияние с локальной ветку командой git merge.

git fetch /home/username/project — забрать изменения из определенного
репозитария.

Возможно также использовать синонимы для адресов, создаваемые командой git remote:

git remote add username-project /home/username/project

git fetch username-project — забрать изменения по адресу, определяемому
синонимом.

Естественно, что после оценки изменений, например, командой git diff, из надо
создать коммит слияния с основной:

git merge username-project/master

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

git pull — забрать из репозитария, для которого были созданы удаленные ветки по
умолчанию.

git pull username-project — забрать изменения из определенного репозитария.

Как правило, используется сразу команда git pull.

3.4 git push — вносим изменения в удаленный репозитарий (удаленную ветку)

После проведения работы в экспериментальной ветке, слияния с основной,
необходимо обновить удаленный репозитарий (удаленную ветку). Для этого
используется команда git push:

git push — отправить свои изменения в удаленную ветку, созданную при
клонировании по умолчанию.

git push ssh://yourserver.com/

you/proj.git master:experimental — отправить изменения
из ветки master в ветку experimental удаленного репозитария.

git push origin :experimental — в удаленном репозитарии origin удалить ветку experimental.

git push origin master:master — в удаленную ветку master репозитария origin (синоним
репозитария по умолчанию) ветки локальной ветки master.

4 git-о-день

В этом разделе будут показаны и разобраны подробно несколько обычных и чуть
меньше необычных для работы с git ситуаций.

4.1 Обычный workflow при работе с локальным репозитарием

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

Почему именно так? Зачем отказываться от линейной модели? Хотя бы даже потому,
что у программиста появляется дополнительная гибкость: он может переключаться
между задачами (ветками); под рукой всегда остается «чистовик» — ветка
master; коммиты становятся мельче и точнее.

4.2 Workflow при работе с удаленным репозитарием

Предположим, что вы и несколько ваших напарников создали общественный
репозитарий, чтобы заняться неким общим проектом. Как выглядит самая
распространенная для git модель общей работы?

you/proj.git
… возможно, прошло некоторое время.

Итак, первым делом создаем (1) создаем копию удаленного репозитария (по
умолчанию команды вроде git pull и git push будут работать с ним). «Вытягиваем»
последние обновления (2); смотрим, что же изменилось(3); создаем новую ветвь и
переключаемся в нее (4); индексируем все изменения и одновременно создаем из них
коммит (5); переключаемся в главную ветвь (6), обновляем ее (7); проводим
слияние с веткой bad-feature(8) и, обнаружив и разрешив конфликт, делаем коммит
слияния (9).

После совершения коммита отслеживаем изменения(10), запускаем, например,
юнит-тесты и с ужасом обнаруживаем, что после слияния проект валится на большей
части тестов.

В принципе, тесты можно было прогнать и до коммита, в момент
слияния (между пунктами 8 и 9); тогда бы хватило «мягкого» резета.

Таким образом, приходится совершить «жесткий» (11) сброс произошедшего слияния,
ветки вернулись в исходное до состояние. После чего переключаемся в неудачную
ветку (12), вносим необходимые изменения и переименовываем ветку (13). Совершаем
коммит (14); переходим в главную ветку(15), опять ее обновляем (16). На этот раз
бесконфликтно делаем слияние (17), закидываем изменения в удаленный репозитарий
(18) и удаляем ненужную теперь ветку (19). Закрываем ноутбук, одеваемся и идем
домой под утро.

5 Заключение

В топике не рассмотрено несколько важных вопросов, вроде администрирования
общественного репозитария, интеграции с текстовыми редакторами или IDE,
использования SSH под Линукс и Windows; приветствуются замечания, и особенно
дополнения в раздел «git-о-день».

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

Это все я сейчас собираю в отдельный топик, которую и выкину сюда через неделю-полторы.

Источник

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

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