что такое репозиторий git

Если вы хотите начать работать с Git, прочитав всего одну главу, то эта глава — то, что вам нужно. Здесь рассмотрены все базовые команды, необходимые вам для решения подавляющего большинства задач, возникающих при работе с Git. После прочтения этой главы вы научитесь настраивать и инициализировать репозиторий, начинать и прекращать контроль версий файлов, а также подготавливать и фиксировать изменения. Мы также продемонстрируем вам, как настроить в Git игнорирование отдельных файлов или их групп, как быстро и просто отменить ошибочные изменения, как просмотреть историю вашего проекта и изменения между отдельными коммитами (commit), а также как отправлять (push) и получать (pull) изменения в/из удалённого (remote) репозитория.

Создание Git-репозитория

Обычно вы получаете репозиторий Git одним из двух способов:

Вы можете взять локальный каталог, который в настоящее время не находится под версионным контролем, и превратить его в репозиторий Git, либо

Вы можете клонировать существующий репозиторий Git из любого места.

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

Создание репозитория в существующем каталоге

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

а затем выполните команду:

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

Мы разберем, что делают эти команды чуть позже. Теперь у вас есть Git-репозиторий с отслеживаемыми файлами и начальным коммитом.

Клонирование существующего репозитория

Источник

Что такое репозиторий git

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

Git — система контроля версий

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

Разработчикам часто бывает нужно вернуться к предыдущей версии кода:

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

К базовым возможностям Git относятся:

Начало работы с Git

Чтобы работать с Git, нужно установить ее на компьютер. На официальном сайте Git можно найти установщик и подробные инструкции для новичков.

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

что такое репозиторий git. Смотреть фото что такое репозиторий git. Смотреть картинку что такое репозиторий git. Картинка про что такое репозиторий git. Фото что такое репозиторий git

Что такое репозиторий Git?

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

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

Где хранится репозиторий?

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

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

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

Что такое коммит и коммитить?

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

Зачем нужен коммит, если Git и так следит за всеми изменениями? Коммиты разбивают процесс разработки, состоящий из большого количества правок, на отдельные шаги. То есть коммит — это некое логически завершенное изменение внутри проекта и понятная (в том числе и другим разработчикам) точка, к которой можно вернуться, если возникнут какие-то проблемы.

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

Как правило, рабочий процесс представляет собой цикл: коммит — изменение файлов — коммит.

что такое репозиторий git. Смотреть фото что такое репозиторий git. Смотреть картинку что такое репозиторий git. Картинка про что такое репозиторий git. Фото что такое репозиторий git

Что такое ветвление?

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

Ветка в Git — это последовательность коммитов. С технической точки зрения ветка — это указатель или ссылка на последний коммит в этой ветке. По умолчанию, имя основной ветки в Git — master. Каждый раз, когда создается новый коммит, указатель ветки master автоматически передвигается на него.

Изучите с нуля алгоритмы и структуры данных, поработайте с Git и станьте востребованным специалистом. Дополнительная скидка 5% по промокоду BLOG.

При создании новой ветки коммиту дается новый указатель, например testing. Если переключиться на ветку testing и сделать новый коммит, то указатель на ветку testing переместится вперед, тогда как указатель на основную ветку master останется на месте. Переключившись обратно на ветку master, файлы в рабочем каталоге вернутся в состояние коммита, на который указывает master.

что такое репозиторий git. Смотреть фото что такое репозиторий git. Смотреть картинку что такое репозиторий git. Картинка про что такое репозиторий git. Фото что такое репозиторий git

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

Зачем нужен GitHub?

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

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

GitHub часто используют при рекрутменте — активный аккаунт и высокое качество кода могут сильно помочь в поиске работы. Поэтому особенно важно иметь аккаунт, чтобы показать свой код коллегам и как он эволюционирует со временем.

Сейчас существует и множество других онлайн-сервисов, интегрированных с Git. Альтернативы GitHub — это, например, GitLab и BitBucket. У обоих сайтов меньше аудитория, но у них есть свой функционал и свои преимущества, например BitBucket более удобен для небольших проектов с закрытым кодом.

Изучите с нуля алгоритмы и структуры данных, поработайте с Git и станьте востребованным специалистом. Дополнительная скидка 5% по промокоду BLOG.

Источник

Git для новичков (часть 1)

Что такое Git и зачем он нужен?

С помощью Git-a вы можете откатить свой проект до более старой версии, сравнивать, анализировать или сливать свои изменения в репозиторий.

Репозиторием называют хранилище вашего кода и историю его изменений. Git работает локально и все ваши репозитории хранятся в определенных папках на жестком диске.

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

Как работает

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

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

Установка

Основой интерфейс для работы с Git-ом является консоль/терминал. Это не совсем удобно, тем более для новичков, поэтому предлагаю поставить дополнительную программу с графическим интерфейсом (кнопками, графиками и т.д.). О них я расскажу чуть позже.

Но для начала, все же установим сам Git.

Windows. Проходим по этой ссылке, выбираем под вашу ОС (32 или 64 битную), скачиваем и устанавливаем.

Для Mac OS. Открываем терминал и пишем:

Linux. Открываем терминал и вводим следующую команду.

Настройка

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

Открываем терминал (Linux и MacOS) или консоль (Windows) и вводим следующие команды.

Создание репозитория

Теперь вы готовы к работе с Git локально на компьютере.

Создадим наш первый репозиторий. Для этого пройдите в папку вашего проекта.

Теперь Git отслеживает изменения файлов вашего проекта. Но, так как вы только создали репозиторий в нем нет вашего кода. Для этого необходимо создать commit.

Отлично. Вы создали свой первый репозиторий и заполнили его первым commit.

Процесс работы с Git

Не стоит после каждого изменения файла делать commit. Чаще всего их создают, когда:

Создан новый функционал

Добавлен новый блок на верстке

Исправлены ошибки по коду

Вы завершили рабочий день и хотите сохранить код

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

Визуальный интерфейс

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

Но существуют и отдельные программы по работе с Git. Могу посоветовать эти:

Я не буду рассказывать как они работают. Предлагаю разобраться с этим самостоятельно.

Создаем свой первый проект и выкладываем на GitHub

Давайте разберемся как это сделать, с помощью среды разработки Visual Studio Code (VS Code).

Перед началом предлагаю зарегистрироваться на GitHub.

Создайте папку, где будет храниться ваш проект. Если такая папка уже есть, то создавать новую не надо.

Установите себе дополнительно анализаторы кода для JavaScript и PHP

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

После этого у вас появится вот такой интерфейс

Здесь будут располагаться все файлы вашего проекта

Здесь можно работать с Git-ом

Кнопка для создания нового файла

Кнопка для создания новой папки

Давайте теперь перейдем во вкладу для работы с Git-ом.

Откроется вот такое окно:

Кнопка для публикации нашего проекта на GitHub

Вы создали и опубликовали репозиторий на GitHub.

Теперь сделаем изменения в коде и попробуем их снова опубликовать. Перейдите во вкладку с файлами, отредактируйте какой-нибудь файл, не забудьте нажать crtl+s (Windows) или cmd+s (MacOS), чтобы сохранить файл. Вернитесь обратно во вкладу управления Git.

Если посмотреть на значок вкладки Git, то можно увидеть цифру 1 в синем кружке. Она означает, сколько файлов у нас изменено и незакоммичено. Давайте его закоммитим и опубликуем:

Кнопка для просмотра изменений в файле. Необязательно нажимать, указал для справки

Добавляем наш файл для будущего commit

Отправляем наш commit в GitHub

Поздравляю, вы научились создавать commit и отправлять его в GitHub!

Это первая вводная статья по утилите Git. Здесь мы рассмотрели:

Как его устанавливать

Как его настраивать

Как инициализировать репозиторий и создать commit через консоль

Как на примере VS Code, опубликовать свой код на GitHub

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

P.S. Для облегчения обучения, оставлю вам ссылку на бесплатный тренажер по Git.

Источник

Введение в Git

Оглавление

Предисловие

Git — самая популярная распределённая система контроля версиями.[1][2]

Основное предназначение Git – это сохранение снимков последовательно улучшающихся состояний вашего проекта (Pro git, 2019).

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

Здесь рассматриваются только технические аспекты git’а, для более подробного погружения в философию git’а и его внутреннюю реализацию, советую прочитать несколько полезных книг (см. Рекомендуемая литература).

1. Настройка git

Прежде чем начинать работу с git необходимо его настроить под себя!

1.1 Конфигурационные файлы

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

1.2 Настройки по умолчанию

Есть куча настроек git’а как для сервера так и для клиента, здесь будут рассмотрены только основные настройки клиента.

где name это название параметра, а value его значение, для того что бы задать настройки.
Пример:

установит редактор по умолчанию nano.

1.3 Псевдонимы (aliases)

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

где SHORT_NAME это имя для сокращения, а COMMAND команда(ы) которую нужно сократить. Пример:

после выполнения этой команды вы можете просматривать информацию о последнем коммите на текущей ветке выполнив git last.

Я советую вам использовать следующие сокращения (вы также можете определить любые свои):

2. Основы git

2.1 Создание репозитория

2.2 Состояние файлов

Для просмотра состояния файлов в вашем репозитории используйте:

Жизненный цикл файловчто такое репозиторий git. Смотреть фото что такое репозиторий git. Смотреть картинку что такое репозиторий git. Картинка про что такое репозиторий git. Фото что такое репозиторий git
Как видно на картинке файлы могут быть не отслеживаемые (Untracked) и отслеживаемые. Отслеживаемые файлы могут находится в 3 состояниях: Не изменено (Unmodified), изменено (Modified), подготовленное (Staged).
Если вы добавляете (с помощью git add) «Не отслеживаемый» файл, то он переходит в состояние «Подготовлено».
Если вы изменяете файл в состояния «Не изменено», то он переходит в состояние «Изменено». Если вы сохраняете изменённый файл (то есть находящийся в состоянии «Изменено») он переходит в состояние «Подготовлено». Если вы делаете коммит файла (то есть находящийся в состоянии «Подготовлено») он переходит в состояние «Не изменено».
Если версии файла в HEAD и рабочей директории отличаются, то файл будет находится в состояний «Изменено», иначе (если версия в HEAD и в рабочем каталоге одинакова») файл будет находится в состояний «Не изменено».
Если версия файла в HEAD отличается от рабочего каталога, но не отличается от версии в индексе, то файл будет в состоянии «Подготовлено».

2.3 Работа с индексом

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

Индекс — промежуточное место между вашим прошлым коммитом и следующим. Вы можете добавлять или удалять файлы из индекса. Когда вы делаете коммит в него попадают данные из индекса, а не из рабочей области.

Что бы просмотреть индекс, используйте git status.

Что бы добавить файлы в индекс используйте

Полезные параметры команды git add:

Что бы удалить файлы из индекса вы можете использовать 2 команды git reset и git restore.
git-restore — восстановит файлы рабочего дерева.
git-reset — сбрасывает текущий HEAD до указанного состояния.
По сути вы можете добиться одного и того же с помощью обеих команд.

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

С помощью git status вы можете посмотреть какие файлы изменились но если вы также хотите узнать что именно изменилось в файлах то воспользуйтесь командой:

2.4 Работа с коммитами

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

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

Полезные опции команды git commit:

где commit это верхний коммит в вашей цепочке с которого вы бы хотели что либо изменить.

pick 2748cb4 first commit
edit 750f5ae second commit
pick 716eb99 third commit

После сохранения скрипта вы вернётесь в командную строку и git скажет что необходимо делать дальше:

Остановлено на 750f5ae … second commit
You can amend the commit now, with

Once you are satisfied with your changes, run

Для удаления коммита
Необходимо удалить строку с коммитом.
Пример: вы хотите удалить коммит 750f5ae
Нужно изменить скрипт с такого:
pick 2748cb4 third commit
pick 750f5ae second commit
pick 716eb99 first commit
на такой:
pick 2748cb4 first commit
pick 716eb99 third commit

Для объединения коммитов
Необходимо изменить pick на squash над коммитами которые вы хотите объединить.
Пример: вы хотите объединить коммиты 750f5ae и 716eb99.
Необходимо изменить скрипт с такого:
pick 2748cb4 third commit
pick 750f5ae second commit
pick 716eb99 first commit
На такой
pick 2748cb4 third commit
squash 750f5ae second commit
squash 716eb99 first commit

Заметьте что в интерактивном скрипте коммиты изображены в обратном порядке нежели в git log. С помощью squash вы объедините коммит 750f5ae с 716eb99, а 750f5ae с 2748cb4. В итоге получая один коммит содержащий изменения всех трёх.

2.5 Просмотр истории

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

Полезные параметры команды git log:

Также вы можете настроить свои формат вывода коммитов с помощью

покажет список коммитов состоящий из хэша времени и сообщения коммита.

2.6 Работа с удалённым репозиторием

Так как git это распределённая СКВ вы можете работать не только с локальными но и с внешними репозиториеми.

Удалённые репозитории представляют собой версии вашего проекта, сохранённые на внешнем сервере.

Для работы с внешними репозиториями используйте:

Если вы с клонировали репозитории через http URL то у вас уже имеется ссылка на внешний. В другом случае вы можете добавить её с помощью

Для загрузки данных с внешнего репозитория используйте git pull [rep] [branch]. Если ваши ветки отслеживают внешние, то можете не указывать их при выполнение git pull. По умолчанию вы получите данные со всех отслеживаемых веток.

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

Для удаления внешних веток используйте

Для получения подробной информации о внешнем репозитории (адреса для отправки и получения, на что указывает HEAD, внешние ветки, локальные ветки настроенные для git pull и локальные ссылки настроенные для git push)

Для переименования названия внешнего репозитория используйте

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

3. Ветвление в git

Ветвление это мощные инструмент и одна из главных фич git’а поскольку позволяет вам быстро создавать и переключатся между различным ветками вашего репозитория. Главная концепция ветвления состоит в том что вы можете откланяться от основной линии разработки и продолжать работу независимо от нее, не вмешиваясь в основную линию. Ветка всегда указывает на последний коммит в ней, а HEAD указывает на текущую ветку (см. Указатели в git).

3.1 Базовые операций

Для создания ветки используйте

Здесь branch_name это название для новой ветки, а start_commit это коммит на который будет указывать ветка (то есть последний коммит в ней). По умолчанию ветка будет находится на последнем коммите родительской ветки.

3.2 Слияние веток

Полезные параметры для git merge:

При разрешении конфликта вам необходимо выбрать какую часть изменений из двух веток вы хотите оставить. При открытии конфликтующего файла, в нём будет содержатся следующее:
>>>>>> Тут название ветки с которой сливаем

Разрешив конфликт вы должны завершить слияния выполнив коммит.

3.3 Rerere

Rerere — «reuse recorded resolution” — “повторное использование сохраненных разрешений конфликтов». Механизм rerere способен запомнить каким образом вы разрешали некую часть конфликта в прошлом и провести автоматическое исправление конфликта при возникновении его в следующий раз.

Что бы включить rerere выполните

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

Используйте git rerere diff для просмотра текущего состояния конфликта.

Если во время слияния написано: Resolved ‘nameFile’ using previous resolution. Значит rerere уже устранил конфликт используя кэш.

4. Указатели в git

в git есть такие указатели как HEAD branch. По сути всё очень просто HEAD указывает на текущую ветку, а ветка указывает на последний коммит в ней. Но для понимания лучше представлять что HEAD указывает на последний коммит.

4.1 Перемещение указателей

В книге Pro git приводится очень хороший пример того как вы можете управлять вашим репозиторием поэтому я тоже буду придерживается его. Представите что Git управляет содержимым трех различных деревьев. Здесь под “деревом” понимается “набор файлов”.
В своих обычных операциях Git управляет тремя деревьями:

Используя различные опций этой команды вы можете:

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

Источник

Ежедневная работа с Git

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

Конечно, я попытаюсь рассказать обо всём по-порядку, начиная с основ. Поэтому, эта статья будет крайне полезна тем, кто только начинает или хочет разобраться с git. Более опытные читатели, возможно, найдут для себя что-то новое, укажут на ошибки или поделятся советом.

Вместо плана

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

Окружение

Если вы открываете консоль, пишите git и получаете вот это:

Перестаём бояться экспериментировать

Строго говоря, даже неудачный git push можно исправить.

Поэтому, спокойно можете клонировать любой репозиторий и начать изучение.

Строим репозитории

В первую очередь нужно понять что такое git-репозиторий? Ответ очень прост: это набор файлов. Папка `.git`. Важно понимать, что это только набор файлов и ничего больше. Раз 20 наблюдал проблему у коллег с авторизацией в github/gitlab. Думая, что это часть git-системы, они пытались искать проблему в конфигруации git, вызывать какие-то git-команды.

В частности, при клонировании вот так:

урл «превращается» в

Т.е. используется SSH и проблемы нужно искать в нём. Как правило, это неправильно настроенный или не найденный ssh-ключ. Гуглить надо в сторону «SSH Auth Key git» или, если совсем по взрослому, проверить, что же происходит:

Какие протоколы поддерживаются поможет справка (раздел GIT URLS):

Сделаем себе один (будет нашим главным тестовым репозиторием):

Итог: у нас есть 3 репозитория. Там ничего нет, зато они готовы к работе.

Начало GIT

Скандалы! Интриги! Расследования!

Как это всё работает?
Как это всё можно понять и запомнить?

Для этого нужно заглянуть под капот. Рассмотрим всё в общих чертах.

Git. Почти под капотом

Git сохраняет в commit содержимое всех файлов (делает слепки содержимого каждого файла и сохраняет в objects). Если файл не менялся, то будет использован старый object. Таким образом, в commit в виде новых объектов попадут только изменённые файлы, что позволит хорошо экономить место на диске и даст возможность быстро переключиться на любой commit.

Это позволяет понять, почему работают вот такие вот забавные штуки:

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

Каждый коммит может иметь несколько коммитов-предков и несколько дочерних-коммитов:
что такое репозиторий git. Смотреть фото что такое репозиторий git. Смотреть картинку что такое репозиторий git. Картинка про что такое репозиторий git. Фото что такое репозиторий git

Мы можем переходить (восстанавливать любое состояние) в любую точку этого дерева, а точнее, графа. Для этого используется git checkout:

Каждое слияние двух и более коммитов в один — это merge (объединение двух и более наборов изменений).
Каждое разветвление — это появление нескольких вариантов изменений.

Кстати, тут хочется отметить, что нельзя сделать тэг на файл/папку, на часть проекта и т.д. Состояние восстанавливается только целиком. Поэтому, рекомендуется держать проекты в отдельном репозитории, а не складывать Project1, Project2 и т.д. просто в корень.

Теперь к веткам. Выше я написал:

В Git нет веток* (с небольшой оговоркой)

Получается, что так и есть: у нас есть много коммитов, которые образуют граф. Выбираем любой путь от parent-commit к любому child-commit и получаем состояние проекта на этот коммит. Чтобы коммит «запомнить» можно создать на него именованный указатель.
Такой именованный указатель и есть ветка (branch). Так же и с тэгом (tag). `HEAD` работает по такому же принципу — показывает, где мы есть сейчас. Новые коммиты являются продолжением текущей ветки (туда же куда и смотрит HEAD).

Указатели можно свободно перемещать на любой коммит, если это не tag. Tag для того и сделан, чтобы раз и навсегда запомнить коммит и никуда не двигаться. Но его можно удалить.
Вот, пожалуй, и всё, что нужно знать из теории на первое время при работе с git. Остальные вещи должны показаться теперь более понятными.

Терминология

index — область зафиксированных изменений, т.е. всё то, что вы подготовили к сохранению в репозиторий.
commit — изменения, отправленные в репозиторий.
HEAD — указатель на commit, в котором мы находимся.
master — имя ветки по-умолчанию, это тоже указатель на определённый коммит
origin — имя удалённого репозитория по умолчанию (можно дать другое)
checkout — взять из репозитория какое-либо его состояние.

Простые правки

Если вы сделали что-то не так, запутались, не знаете, что происходит — эти две команды вам помогут.

Вернёмся к нашим репозиториям, которые создали раньше. Далее обозначу, что один разработчик работает в dev1$, а второй в dev2$.

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

Второй разработчик может получить эти изменения, сделав pull:

Добавим ещё пару изменений:

Посмотрим, что же мы сделали (запускаем gitk):

что такое репозиторий git. Смотреть фото что такое репозиторий git. Смотреть картинку что такое репозиторий git. Картинка про что такое репозиторий git. Фото что такое репозиторий git
Выделил первый коммит. Переходя по-порядку, снизу вверх, мы можем посмотреть как изменялся репозиторий:

До сих пор мы добавляли коммиты в конец (там где master). Но мы можем добавить ещё один вариант README.md. Причём делать мы это можем из любой точки. Вот, например, последний коммит нам не нравится и мы пробуем другой вариант. Создадим в предыдущей точке указатель-ветку. Для этого через git log или gitk узнаем commit id. Затем, создадим ветку и переключимся на неё:

Выглядит это так:
что такое репозиторий git. Смотреть фото что такое репозиторий git. Смотреть картинку что такое репозиторий git. Картинка про что такое репозиторий git. Фото что такое репозиторий git

Теперь нам понятно, как создаются ветки из любой точки и как изменяется их история.

Быстрая перемотка

Наверняка, вы уже встречали слова fast-forward, rebase, merge вместе. Настало время разобраться с этими понятиями. Я использую rebase, кто-то только merge. Тем «rebase vs merge» очень много. Авторы часто пытаются убедить, что их метод лучше и удобнее. Мы пойдём другим путём: поймём, что же это такое и как оно работает. Тогда сразу станет ясно, какой вариант использовать в каком случае.

Пока, в пределах одного репозитория, сделаем ветвление: создадим файл, положим в репозиторий, из новой точки создадим два варианта файла и попробуем объединить всё в master:

Создадим файл collider.init.sh с таким содержанием:

Добавим, закоммитим и начнём разработку в новой ветке:

Обратите внимание, что в имени ветки не запрещено использовать символ ‘/’, однако, надо быть осторожным, т.к. в файловой системе создаётся папка с именем до ‘/’. Если ветка с таким названием как и папка существует — будет конфликт на уровне файловой системы. Если уже есть ветка dev, то нельзя создать dev/test.
A если есть dev/test, то можно создавать dev/whatever, но нельзя просто dev.

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

Разработка закончена и теперь надо отдать все изменения в master (там ведь старый коллайдер, который ничего не может). Объединение двух коммитов, как и говорилось выше — это merge. Но давайте подумаем, чем отличается ветка master от collider/start и как получить их объединение (сумму)? Например, можно взять общие коммиты этих веток, затем прибавить коммиты, относящиеся только к master, а затем прибавить коммиты, относящиеся только к collider/start. А что у нас? Общие коммиты — есть, только коммиты master — нет, только collider/start — есть. Т.е. объединение этих веток — это master + коммиты от collider/start. Но collider/start — это master + коммиты ветки collider/start! Тоже самое! Т.е. делать ничего не надо! Объединение веток — это и есть collider/start!
Ещё раз, только на буквах, надеюсь, что будет проще для восприятия:
master = C1 + C2 +C3
collider/start = master + C4 = C1 + C2 +C3 + C4
master + collider/start = Общие_коммиты(master, collider/start) + Только_у(master) + Только_у(collider/start) = (C1 + C2 +C3) + (NULL) + (C4) = C1 + C2 +C3 + C4

Как быстро узнать, что fast-forward возможен? Для этого достаточно посмотреть в gitk на две ветки, которые нужно объединить и ответить на один вопрос: существует ли прямой путь от ветки А к B, если двигаться только вверх (от нижней к верхней). Если да — то будет fast-forward.
В теории понятно, пробуем на практике, забираем изменения в master:

Результат (указатель просто передвинулся вперёд):
что такое репозиторий git. Смотреть фото что такое репозиторий git. Смотреть картинку что такое репозиторий git. Картинка про что такое репозиторий git. Фото что такое репозиторий git

Объединение

Теперь забираем изменения из collider/terminate. Но, тот, кто дочитал до сюда (дочитал ведь, да?!) заметит, что прямого пути нет и так красиво мы уже не отделаемся. Попробуем git попросить fast-forward:

Что и следовало ожидать. Делаем просто merge:

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

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

Как всегда, две самые нужные команды нам спешат помочь:

что такое репозиторий git. Смотреть фото что такое репозиторий git. Смотреть картинку что такое репозиторий git. Картинка про что такое репозиторий git. Фото что такое репозиторий git
Мы находимся в master, туда же указывает HEAD, туда же и добавляются наши коммиты.
Файл выглядит так:

Из-за того что изменения были в одних и тех же местах конфликтов получилось много. Поэтому, я брал везде первый вариант, а второй копировал сразу после первого, но с gui это сделать довольно просто. Вот результат — вверху варианты файла, внизу — объединение (простите за качество):
что такое репозиторий git. Смотреть фото что такое репозиторий git. Смотреть картинку что такое репозиторий git. Картинка про что такое репозиторий git. Фото что такое репозиторий git
Сохраняем результат, закрываем окно, коммитим, смотрим результат:
что такое репозиторий git. Смотреть фото что такое репозиторий git. Смотреть картинку что такое репозиторий git. Картинка про что такое репозиторий git. Фото что такое репозиторий git

Мы создали новый коммит, который является объединением двух других. Fast-forward не произошёл, потому, что не было прямого пути для этого, история стала выглядеть чуть-чуть запутаннее. Иногда, merge действительно нужен, но излишне запутанная история тоже ни к чему.
Вот пример реального проекта:

что такое репозиторий git. Смотреть фото что такое репозиторий git. Смотреть картинку что такое репозиторий git. Картинка про что такое репозиторий git. Фото что такое репозиторий gitчто такое репозиторий git. Смотреть фото что такое репозиторий git. Смотреть картинку что такое репозиторий git. Картинка про что такое репозиторий git. Фото что такое репозиторий gitчто такое репозиторий git. Смотреть фото что такое репозиторий git. Смотреть картинку что такое репозиторий git. Картинка про что такое репозиторий git. Фото что такое репозиторий git

Конечно, такое никуда не годится! «Но разработка идёт параллельно и никакого fast-forward не будет» скажете вы? Выход есть!

Перестройка

Что же делать, чтобы история оставалась красивой и прямой? Можно взять нашу ветку и перестроить её на другую ветку! Т.е. указать ветке новое начало и воспроизвести все коммиты один за одним. Этот процесс и называется rebase. Наши коммиты станут продолжением той ветки, на которую мы их перестроим. Тогда история будет простой и линейной. И можно будет сделать fast-forward.
Другими словами: мы повторяем историю изменений с одной ветки на другой, как будто бы мы действительно брали другую ветку и заново проделывали эти же самые изменения.

Для начала отменим последние изменения. Проще всего вернуть указатель master назад, на предыдущее состояние. Создавая merge-commit, мы передвинули именно master, поэтому именно его нужно вернуть назад, желательно (а в отдельных случаях важно) на тот же самый commit, где он был.
Как результат, наш merge-commit останется без какого-либо указателя и не будет принадлежать ни к одной ветке.

Используя gitk или консоль перемещаем наш указатель. Поскольку, ветка collider/start уже указывает на наш коммит, нам не нужно искать его id, а мы можем использовать имя ветки (это будет одно и тоже):

Когда с коммита или с нескольких коммитов пропадает указатель (ветка), то коммит остаётся сам по себе. Git про него забывает, не показывает его в логах, в ветках и т.д. Но физически, коммит никуда не пропал. Он живёт себе в репозитории как невостребованная ячейка памяти без указателя и ждёт своего часа, когда git garbage collector её почистит.
Иногда бывает нужно вернуть коммит, который по ошибке был удалён. На помощь придёт git reflog. Он покажет всю историю, по каким коммитам вы ходили (как передвигался указатель HEAD). Используя вывод, можно найти id пропавшего коммита, сделать его checkout или создать на коммит указатель (ветку или тэг).
Выглядит это примерно так (история короткая, поместилась вся):

Посмотрим, что получилось:
что такое репозиторий git. Смотреть фото что такое репозиторий git. Смотреть картинку что такое репозиторий git. Картинка про что такое репозиторий git. Фото что такое репозиторий git

Для того, чтобы перестроить одну ветку на другую, нужно найти их общее начало, потом взять коммиты перестраиваемой ветки и, в таком же порядке, применить их на основную (base) ветку. Очень наглядная картинка (feature перестраивается на master):
что такое репозиторий git. Смотреть фото что такое репозиторий git. Смотреть картинку что такое репозиторий git. Картинка про что такое репозиторий git. Фото что такое репозиторий git
Важное замечание: после «перестройки» это уже будут новые коммиты. А старые никуда не пропали и не сдвинулись.

В теории разобрались, пробуем на практике. Переключаемся в collider/terminate и перестраиваем на тот коммит, куда указывает master (или collider/start, кому как удобнее). Команда дословно «взять текущую ветку и перестроить её на указанный коммит или ветку»:

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

Если коротко: то в процессе перестройки мы можем изменять комментарии к коммитам, редактировать сами коммиты, объединять их или вовсе пропускать. Т.е. можно переписать историю ветки до неузнаваемости. На данном этапе нам это не нужно, просто закрываем редактор и продолжаем. Как и в прошлый раз, конфликтов нам не избежать:

На данном этапе мы удаляли, редактировали, объединяли правки, а на выходе получили красивую линейную историю изменений:
что такое репозиторий git. Смотреть фото что такое репозиторий git. Смотреть картинку что такое репозиторий git. Картинка про что такое репозиторий git. Фото что такое репозиторий git

Перерыв

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

Передача и приём изменений

git remote

Как отмечалось выше, origin — это имя репозитория по умолчанию. Имена нужны, т.к. репозиториев может быть несколько и их нужно как-то различать. Например, у меня была копия репозитория на флешке и я добавил репозиторий flash. Таким образом я мог работать с двумя репозиториями одновременно: origin и flash.

Имя репозитория используется как префикс к имени ветки, чтоб можно было отличать свою ветку от чужой, например master и origin/master

В справке по git remote достаточно хорошо всё описано. Как и ожидается, там есть команды: add, rm, rename, show.
show покажет основные настройки репозитория:

Чтобы добавить существующий репозиторий используем add :

git fetch

Команда говорит сама за себя: получить изменения.
Стоит отметить, что локально никаких изменений не будет. Git не тронет рабочую копию, не тронет ветки и т.д.
Будут скачены новые коммиты, обновлены только удалённые (remote) ветки и тэги. Это полезно потому, что перед обновлением своего репозитория можно посмотреть все изменения, которые «пришли» к вам.

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

Теперь от имени dev2 посмотрим, что есть и получим все изменения:

Выглядит это так:
что такое репозиторий git. Смотреть фото что такое репозиторий git. Смотреть картинку что такое репозиторий git. Картинка про что такое репозиторий git. Фото что такое репозиторий git
Обратите внимание, что мы находимся в master.
Что можно сделать:
git checkout origin/master — переключиться на удалённый master, чтобы «пощупать» его. При этом нельзя эту ветку редактировать, но можно создать свою локальную и работать с ней.
git merge origin/master — объединить новые изменения со своими. Т.к. у нас локальных изменений не было, то merge превратится в fast-forward:

git pull

В 95% случаев, вам не нужно менять это поведение.

git push

На все вопросы может ответить расширенный вариант использования команды:
git push origin :
Примеры:

Включаемся в проект

К этому моменту уже более-менее понятно, как работает push, pull. Более смутно представляется в чём разница между merge и rebase. Совсем непонятно зачем это нужно и как применять.
Когда кого-нибудь спрашивают:
— Зачем нужна система контроля версий?
Чаще всего в ответе можно услышать:
— Эта система помогает хранить все изменения в проекте, чтобы ничего не потерялось и всегда можно было «откатиться назад».

А теперь задайте себе вопрос: «как часто приходится откатываться назад?» Часто ли вам нужно хранить больше, чем последнее состояние проекта? Честный ответ будет: «очень редко». Я этот вопрос поднимаю, чтобы выделить гораздо более важную роль системы контроля версий в проекте:

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

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

Используете %VCS_NAME%? Удобно? Не ограничивает процесс разработки и легко адаптируется под требования? Быстро? Значит эта %VCS_NAME% подходит для вашего проекта лучше всего. Пожалуй, вам не нужно ничего менять.

Типичные сценарии при работе над проектом

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

Исправление багов

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

И второй разработчик «забирает» новую ветку к себе:

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

Когда работа закончена, передаём изменения в репозиторий. Dev1:

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

Посмотрим на результат:
что такое репозиторий git. Смотреть фото что такое репозиторий git. Смотреть картинку что такое репозиторий git. Картинка про что такое репозиторий git. Фото что такое репозиторий git
Теперь, всё как положено: наши изменения в dev и готовы быть переданы в origin.
Передаём:

Нам откроется редактор и даст возможность исправить нашу историю, например, поменять порядок коммитов или объединить несколько. Об этом писалось выше. Я оставлю как есть:

После того как все конфликты решены, история будет линейной и логичной. Для наглядности я поменял комментарии (интерактивный rebase даёт эту возможность):
что такое репозиторий git. Смотреть фото что такое репозиторий git. Смотреть картинку что такое репозиторий git. Картинка про что такое репозиторий git. Фото что такое репозиторий git
Теперь наша ветка продолжает origin/dev и мы можешь отдать наши изменения: актуальные, адаптированные под новые коммиты:

Далее история повторяется. Для удобства или в случае работы над несколькими багами, как говорилось выше, удобно перед началом работы создать отдельные ветки из dev или origin/dev.

Feature branch

Бывает так, что нужно сделать какой-то большой кусок работы, который не должен попадать в основную версию пока не будет закончен. Над такими ветками могут работать несколько разработчиков. Очень серьёзный и объёмный баг может рассматриваться с точки зрения процесса работы в git как фича — отдельная ветка, над которой работают несколько человек. Сам же процесс точно такой же как и при обычном исправлении багов. Только работа идёт не с dev, а с feature/name веткой.
Вообще, такие ветки могут быть коротко-живущими (1-2 неделя) и долго-живущими (месяц и более). Разумеется, чем дольше живёт ветка, тем чаще её нужно обновлять, «подтягивая» в неё изменения из основной ветки. Чем больше ветка, тем, вероятно, больше будет накладных расходов по её сопровождению.

Начнём с коротко-живущих (short-live feature branches)

Обычно ветка создаётся с самого последнего кода, в нашем случае с ветки dev:

Теперь работу на feature1 можно вести в ветке feature/feature1. Спустя некоторое время в нашей ветке будет много коммитов, и работа над feature1 будет закончена. При этом в dev тоже будет много изменений. И наша задача отдать наши изменения в dev.
Выглядеть это будет приблизительно так:
что такое репозиторий git. Смотреть фото что такое репозиторий git. Смотреть картинку что такое репозиторий git. Картинка про что такое репозиторий git. Фото что такое репозиторий git
Ситуация напоминает предыдущую: две ветки, одну нужно объединить с другой и передать в репозиторий. Единственное отличие, это две публичные (удалённые) ветки, а не локальные. Это требует небольшой коммуникации. Когда работа закончена, один разработчик должен предупредить другого, что он собирается «слить» изменения в dev и, например, удалить ветку. Таким образом передавать в эту ветку что-либо будет бессмысленно.
А дальше алгоритм почти такой как и был:

Картинка, feature1 стала частью dev, то что на и нужно было:
что такое репозиторий git. Смотреть фото что такое репозиторий git. Смотреть картинку что такое репозиторий git. Картинка про что такое репозиторий git. Фото что такое репозиторий git
Делаем push и чистим за собой ненужное:

Долго-живущие ветки (long-live feature branches)

Сложность долго-живущих веток в их поддержке и актуализации. Если делать всё как описано выше то, вероятно быть беде: время идёт, основная ветка меняется, проект меняется, а ваша фича основана на очень старом варианте. Когда настанет время выпустить фичу, она будет настолько выбиваться из проекта, что объединение может быть очень тяжёлым или, даже, невозможным. Именно поэтому, ветку нужно обновлять. Раз dev уходит вперёд, то мы будем просто время от времени перестраивать нашу ветку на dev.

Всё бы хорошо, но только нельзя просто так взять и перестроить публичную ветку: ветка после ребэйза — это уже новый набор коммитов, совершенно другая история. Она не продолжает то, что уже было. Git не примет такие изменения: два разных пути, нет fast-forward’а. Чтобы переписать историю разработчикам нужно договориться.
Кто-то будет переписывать историю и принудительно выкладывать новый вариант, а в этот момент остальные не должны передавать свои изменения в текущую ветку, т.к. она будет перезаписана и всё пропадёт. Когда первый разработчик закончит, все остальные перенесут свои коммиты, которые они успеют сделать во время переписи уже на новую ветку. Кто говорил, что нельзя ребэйзить публичные ветки?

Приступим к практике:

Второй разработчик подключается к работе всё стандартно:

Добавим ещё несколько коммитов в основную ветку dev и история будет такая:
что такое репозиторий git. Смотреть фото что такое репозиторий git. Смотреть картинку что такое репозиторий git. Картинка про что такое репозиторий git. Фото что такое репозиторий git

Настало время актуализировать feature/long, но при этом разработка должна продолжиться отдельно. Пусть перестраивать будет dev1. Тогда он предупреждает dev2 об этом и начинает:

В это время dev2 продолжает работать, но знает, что ему нельзя делать push, т.к. нужной ветки ещё нет (а текущая будет удалена).
Первый заканчивает rebase и история будет такой:
что такое репозиторий git. Смотреть фото что такое репозиторий git. Смотреть картинку что такое репозиторий git. Картинка про что такое репозиторий git. Фото что такое репозиторий git
Ветка перестроена, а origin/feature/long остался там, где и был. Цели мы достигли, теперь нужно поделиться со всеми:

Git лишний раз напоминает, что что-то не так. Но теперь, мы точно знаем, что мы делаем, и знаем, что так надо:

Теперь можно работать дальше предупредив остальных об окончании работ.

Посмотрим, как эти изменения отразились на окружающих и на dev2 в частности:

что такое репозиторий git. Смотреть фото что такое репозиторий git. Смотреть картинку что такое репозиторий git. Картинка про что такое репозиторий git. Фото что такое репозиторий git

N, чтобы указать на предыдущий N-ый коммит.
HEAD

1 — это предыдущий, а HEAD

2 — это предпредыдущий. HEAD

5 — 5 коммитов назад. Удобно, чтобы не запоминать id.

Посмотрим, как теперь нам перестроить только один коммит:

1

Если бы нам надо было перетянуть 4 коммита, то было бы feature/long

что такое репозиторий git. Смотреть фото что такое репозиторий git. Смотреть картинку что такое репозиторий git. Картинка про что такое репозиторий git. Фото что такое репозиторий git
Осталось продолжить работу.

Hotfixes

Hotfixы нужны, т.к. бывают очень критичные баги, которые нужно исправить как можно быстрее. При этом нельзя передать вместе с hotfix-ом последний код, т.к. он не оттестирован и на полное тестирование нет времени. Нужно только это исправление, максимально быстро и оттестированное. Чтобы это сделать, достаточно взять последний релиз, который был отправлен на продакшен. Это тот, где у вас остался tag или master. Тэги играют очень важную роль, помогая понять что именно было собрано и куда это попало.
Тэги делаются командой

Всякие полезности

Git позволяет настраивать aliasы для различных команд. Это бывает очень удобно и сокращает время набора команд. Приводить здесь примеры не буду, в Интернете их полно, просто поищите.

Перед тем, как отдавать свои изменения их можно перестроить на самих себя, чтобы привести историю в порядок.
Например, в логах может быть такое:

Перестроим сами себя, но начиная с 6 коммитов назад:

Теперь в интерактивном режиме можно объединить (squash) первые два коммита в один и последние четыре. Тогда история будет выглядеть так:

Такое намного приятнее передавать в общим репозиторий.

Выводы

Причемания и апдейты

gcc рекомендовал посмотреть на Git Extensions.
borNfree подсказал ещё один GUI клиент Source Tree.
zloylos поделился ссылкой на визуализатор для git
olancheg предложил посмотреть на ещё один туториал для новичков.

PS. Что тут обычно пишут, когда первый пост на хабре? Прошу не судить строго, писал как мог.

Источник

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

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