Git: наглядная справка
Если вы не видите иллюстраций, попробуйте переключиться на версию со стандартными картинками (без SVG).
SVG изображения были отключены. (Включить SVG изображения)
На этой странице представлена краткая наглядная справка для наиболее часто используемых команд git. Если у вас уже есть небольшой опыт работы с git, эта страница поможет вам закрепить ваши знания. Если вам интересно, как был создан этот сайт, загляните на мой репозиторий на GitHub.
Содержание
Основные команды
Следующие четыре команды предназначены для копирования файлов между рабочей директорией, сценой, также известной как «индекс», и историей, представленной в форме коммитов.
Также можно перепрыгнуть через сцену и сразу же получить файлы из истории прямо в рабочую директорию или сделать коммит, минуя сцену.
Соглашения
Иллюстрации в этой справке выдержаны в единой цветовой схеме.
Коммиты раскрашены зелёным цветом и подписаны 5-ти буквенными идентификаторами. Каждый коммит указывает на своего родителя зелёной стрелочкой. Ветки раскрашены оранжевым цветом; ветки указывают на коммиты. Специальная ссылка HEAD указывает на текущую ветку. На иллюстрации вы можете увидеть последние пять коммитов. Самый последний коммит имеет хеш ed489. main (текущая ветка) указывает на этот коммит, stable (другая ветка) указывает на предка main-ового коммита.
Подробно о командах
Есть много способов посмотреть изменения между коммитами. Ниже вы увидите несколько простых примеров. К каждой из этих команд можно добавить имена файлов в качестве дополнительного аргумента. Так мы выведем информацию об изменениях только для перечисленных файлов.
Commit
Когда вы делаете коммит, git создаёт новый объект коммита, используя файлы со сцены, а текущей коммит становится родителем для нового. После этого указатель текущей ветки перемещается на новый коммит. Вы это видите на картинке, где main — это текущая ветка. До совершения коммита main указывал на коммит ed489. После добавления нового коммита f0cec, родителем которого стал ed489, указатель ветки main был перемещён на новый коммит.
То же самое происходит, если одна ветка является предком другой ветки. Ниже показан пример нового коммита 1800b в ветке stable, которая является предком ветки main. После этого ветка stable уже больше не является предком ветки main. И в случае необходимости объединения работы, проделанной в этих разделённых ветках, вам следует воспользоваться командой merge (что более предпочтительно) или rebase.
Четвертый случай коммита из состояния «detached HEAD» будет рассмотрен далее.
Checkout
Команда checkout используется для копирования файлов из истории или сцены в рабочую директорию. Также она может использоваться для переключения между ветками.
foo.c копирует файл foo.c из коммита HEAD
(предка текущего коммита) в рабочую директорию и на сцену. Если имя коммита не указано, то файл будет скопирован со сцены в рабочую директорию. Обратите внимание на то, что при выполнении команды checkout позиция указателя текущей ветки (HEAD) остаётся прежней, указатель никуда не перемещается.
В том случае, если мы не указываем имя файла, но указываем имя локальной ветки, то указатель HEAD будет перемещён на эту ветку, то есть мы переключимся на эту ветку. При этом сцена и рабочая директория будут приведены в соответствие с этим коммитом. Любой файл, который присутствует в новом коммите (a47c3 ниже), будет скопирован из истории; любой файл, который был в старом коммите (ed489), но отсутствует в новом, будет удалён; любой файл, который не записан ни в одном коммите, будет проигнорирован.
В том случае, если мы не указываем имя файла, и не указываем имя локальной ветки, а указываем тег, дистанционную (remote) ветку, SHA-1 хеш коммита или что-то вроде main
Коммит из состояния «Detached HEAD»
Когда мы находимся в состоянии оторванной головы (Detached HEAD), коммит совершается по тем же правилам, что и обычно, за исключением одной маленькой особенности: ни один указатель ветки не будет изменён или добавлен к новому коммиту. Вы можете представить эту ситуацию как работу с анонимной веткой.
Если после такого коммита вы переключитесь в ветку main, то коммит 2eecb, совершённый из состояния «Detached HEAD», потеряется и попросту будет уничтожен очередной сборкой мусора только потому, что нет ни одного объекта, который бы на него ссылался: ни ветки, ни тега.
Reset
Команда reset перемещает указатель текущей ветки в другую позицию и дополнительно может обновить сцену и рабочую директорию. Эту команду можно также использовать для того, чтобы скопировать файл из истории на сцену, не задевая рабочую директорию.
Merge
Команда merge (слияние) создает новый коммит на основе текущего коммита, применяя изменения других коммитов. Перед слиянием сцена должна быть приведена в соответствие с текущим коммитом. Самый простой случай слияния — это когда другой коммит является предком текущего коммита: в этом случае ничего не происходит. Другой простой случай слияния — когда текущий коммит является предком другого коммита: в этом случае происходит быстрая перемотка (fast-forward). Ссылка текущей ветки будет просто перемещена на новый коммит, а сцена и рабочая директория будут приведены в соответствие с новым коммитом.
Во всех других случаях выполняется «настоящее» слияние. Вы можете изменить стратегию слияния, но по умолчанию будет выполнено «рекурсивное» слияние, для которого будет взят текущий коммит (ed489 ниже на схеме), другой коммит (33104) и их общий предок (b325c); и для этих трех коммитов будет выполнено трёхстороннее слияние. Результат этого слияния будет записан в рабочую директорию и на сцену, и будет добавлен результирующий коммит со вторым родителем (33104).
Cherry Pick
Команда cherry-pick («вишенка в тортике») создаёт новый коммит на основе только одного сладкого «коммита-вишенки», применив все его изменения и сообщение.
Rebase
Перебазирование (rebase) — это альтернатива слиянию для задач объединения нескольких веток. Если слияние создаёт новый коммит с двумя родителями, оставляя нелинейную историю, то перебазирование применяет все коммиты один за одним из одной ветки в другую, оставляя за собой линейную историю коммитов. По сути это автоматическое выполнение нескольких команд cherry-pick подряд.
На схеме выше вы видите как команда берёт все коммиты, которые есть в ветке topic, но отсутствуют в ветке main (коммиты 169a6 and 2c33a), и воспроизводит их в ветке main. Затем указатель ветки перемещается на новое место. Следует заметить, что старые коммиты будут уничтожены сборщиком мусора, если на них уже ничего не будет ссылаться.
Технические заметки
Содержание файлов не хранится в индексе (.git/index) или в объектах коммитов. Правильнее было бы сказать, что каждый файл хранится в базе данных объектов (.git/objects) в двоичном представлении; найти этот файл можно по его SHA-1 хешу. В файле индекса записаны имена файлов, их хеши и дополнительная информация. В информации о коммитах вы встретите тип данных дерево, для идентификации которого также используется SHA-1 хеш. Деревья описывают директории в рабочей директории, а также содержат информацию о других деревьях и файлах, принадлежащих обозначенному дереву. Каждый коммит хранит идентификатор своего верхнего дерева, которое содержит все файлы и другие деревья, изменённые в этом коммите.
Copyright © 2010, Mark Lodato. Russian translation © 2012, Alex Sychev.

Основы Git
Git очень удобная система контроля версий, которая сейчас используется практические повсеместно. Она нужна для того, чтобы команды могли кооперироваться в создании программного продукта и совмещать код написанный разными людьми в одном репозитории.
Когда я учил Git мне говорили, что в работе мне понадобятся всего 3 команды:
Правда, по сути мне немного слукавили, нужен был ещё как минимум:
Однако, на этом все мои теоретические знания по Git заканчивались и достаточно долгое время я пользовался только этими командами, покуда в один момент не начал работать над веб-приложениями, над которыми со мной работали ещё несколько человек.
Там мне объяснили какие команды также нужны в разработке, зачем они используются и как часто они используются. Сегодня я решил поделиться этими командами с вами.
Основная терминология
Работа с Git
Прежде всего нам понадобятся команды для работы с файлами. Знать add конечно хорошо, но нужно иногда и удалять что-то из кэшируемых файлов или изменять поведение Git для определенных файлов. Сегодня я разберу некоторые команды, которые позволят вам манипулировать с файлами, ветками, коммитами в Git.
init
Данная команда инициализирует систему контроля версий. Для того чтобы создать новый репозиторий достаточно просто ввести:
clone
Данная команда нужна для того, чтобы клонировать репозиторий из облака. Можно клонировать репозитории из Github, Gitlab, BitBucket и других сервисов. Для того чтобы склонировать репозиторий нужно ввести:
Данная команда понадобится вам, когда вам нужно добавить файл для кэширования. Давайте разберёмся как это работает:
Вы изменяете файлы, можете изменять достаточно много файлов, задачи изменения которых вообще никак не связаны
Вы решаете «закоммитить» ваши файлы (сделать сохранение версии, для того чтобы Git запомнил все ваши изменения в файлах и как-то назвал их, для этого есть отдельная команда git commit )
Вы также можете добавить файлы, которые ранее не отслеживались, для того чтобы Git занёс их в свою систему хранения версий и вы могли откатываться на какую-то из версий файла
Проделав данный алгоритм, состоящий из двух команд вы занесёте все файлы из вашего проекта в систему контроля версий Git.
Но, что если вам не хочется вносить все файлы? Тогда вы может использовать следующий синтаксис:
Также мы можем сделать так, чтобы Git искал некоторые названия в дочерних директориях и игнорировал их:
Данная команда поможет, когда нам нужно избавиться от файла, она подобно команде rm удаляет файл из файловой системы и кэша Git, позволяя нам быстро избавиться от файла.
Данный пример удалит файл file.txt из кэша и файловой системы.
Но, что если мы добавили файл, который нам более не нужен в кэше, но нужен в файловой системе? Тогда мы можем воспользоваться следующей командой:
Данная команда удалит файл из «кэша», но что это значит? Допустим, что мы «закоммитили» (сохранили версию, об этом поговорим вот уже совсем скоро) наш файл, а теперь хотим, чтобы Git считал что мы его удалили, а сами просто оставили его на диске. Для этого и нужна команда выше. Она просто говорит Git: «Слушай, а давай ты просто удалишь этот файл из кэша и не будешь его показывать в репозитории, а я оставлю копию у себя на ПК, ок?»
Таким образом мы можем работать с данным файлом и Git не будет знать что именно в нём мы изменяем, а затем просто можем опять добавить его. Файл будет висеть в состоянии «untracked» (не отслеживается) до тех пор, покуда мы его опять не добавим.
commit
Думаю, что стоит поговорить об этом уже сейчас, ибо позже без данной команды уже никуда. Данная команда буквально сохраняет версию, в которой указывается что именно в файлах мы изменили.
Обычно разработчики сохраняют версию программы с помощью данной команды:
В данном случае мы просто скажем, чтобы Git сохранил все изменения, которые мы сделали в файлах, которые отслеживаются. Файлы, которые не отслеживаются просто не попадают в версию, а также их изменения никак нельзя отследить.
Для того чтобы отменить последний коммит (отменить не изменения, а именно просто разкоммитить изменения) и совместить его с текущими изменениями используйте команду:
show
Данная команда нужна для того, чтобы быстро показать что было сделано за предыдущие коммит:
Выведутся изменения следующим образом:
status
До этого момента мы могли только посмотреть что творилось в предыдущем коммите, однако с помощью git log мы можем посмотреть историю наших коммитов:
Если же вы хотите красиво вывести все ваши коммиты в столбик, то используйте данную команду:
В данной команде мы описываем что хотим просматривать коммиты и их названия в одну строку, хотим чтобы коммиты сокращали свой ID, а также чтобы всё это красиво было разбито по списку
diff
С помощью данной команды мы можем посмотреть на изменения между коммитами. Эта комманда является одной из самых мощных в Git, вам стоит обратить на неё внимание:
Так называемые «ID-коммита» можно взять и вышеприведенной git log
Если вы хотите посмотреть историю изменений в файлах в определенном коммите, то используйте следующую команду:
Если вы хотите посмотреть на изменения только тех файлов, которые добавлены для отслеживания, то нужно ввести следующую команду:
branch
В Git есть ветки для разделения версий. Если коммит нужен для того, чтобы сделать snapshot (слепок изменений) файлов, то ветки нужны для того, чтобы эти snapshot’ы разделять. У вас может быть ветка
любое другое название
Для того чтобы перечислить все ветки с помощью Git нужно ввести следующую команду:
Для того чтобы создать новую ветку нужно ввести:
checkout
Checkout используют для того, чтобы переходить между ветками. Для того чтобы перейти на другую ветку достаточно просто написать:
Для того чтобы создать ветку и сразу же перейти на неё достаточно ввести:
merge
Соединение веток не являются сложной темой. Для того чтобы слить текущую ветку с другой нужно ввести:
push
В завершение
Здесь мы чуть более глубже познакомились с основами Git, поняли как работать с ветками, как их мерджить, как коммитить файлы, смотреть изменения, а также как показывать последние коммиты.
Если вы хотите больше узнать о веб-разработке, а также о линуксе, то милости прошу в мой блог на телеграм.
Надеюсь данная статья помогла вам чуть лучше узнать Git. Хорошего дня и продуктивной недели!
Шпаргалка по Git, в которой представлены основные команды
Шпаргалка по основным командам
git add
Команда git add добавляет содержимое рабочей директории в индекс (staging area) для последующего коммита. По умолчанию git commit использует лишь этот индекс, так что вы можете использовать git add для сборки слепка вашего следующего коммита.
git status
Команда git status показывает состояния файлов в рабочей директории и индексе: какие файлы изменены, но не добавлены в индекс; какие ожидают коммита в индексе. Вдобавок к этому выводятся подсказки о том, как изменить состояние файлов.
git diff
git difftool
git commit
git reset
git rm
Команда git rm используется в Git для удаления файлов из индекса и рабочей директории. Она похожа на git add с тем лишь исключением, что она удаляет, а не добавляет файлы для следующего коммита.
git mv
Команда git mv — это всего лишь удобный способ переместить файл, а затем выполнить git add для нового файла и git rm для старого.
git clean
Команда git clean используется для удаления мусора из рабочей директории. Это могут быть результаты сборки проекта или файлы конфликтов слияний.
Шпаргалка по ветвлению и слиянию
git branch
Команда git branch — это своего рода “менеджер веток”. Она умеет перечислять ваши ветки, создавать новые, удалять и переименовывать их.
git checkout
Команда git checkout используется для переключения веток и выгрузки их содержимого в рабочую директорию.
git merge
Команда git merge используется для слияния одной или нескольких веток в текущую. Затем она устанавливает указатель текущей ветки на результирующий коммит.
git mergetool
Команда git mergetool просто вызывает внешнюю программу слияний, в случае если у вас возникли проблемы слияния.
git log
Команда git log используется для просмотра истории коммитов, начиная с самого свежего и уходя к истокам проекта. По умолчанию, она показывает лишь историю текущей ветки, но может быть настроена на вывод истории других, даже нескольких сразу, веток. Также её можно использовать для просмотра различий между ветками на уровне коммитов.
git stash
Команда git stash используется для временного сохранения всех незакоммиченных изменений для очистки рабочей директории без необходимости коммитить незавершённую работу в новую ветку.
git tag
Команда git tag используется для задания постоянной метки на какой-либо момент в истории проекта. Обычно она используется для релизов.
Шпаргалка по совместной работе и обновлению проектов
Не так уж много команд в Git требуют сетевого подключения для своей работы, практически все команды оперируют с локальной копией проекта. Когда вы готовы поделиться своими наработками, всего несколько команд помогут вам работать с удалёнными репозиториями.
git fetch
Команда git fetch связывается с удалённым репозиторием и забирает из него все изменения, которых у вас пока нет и сохраняет их локально.
git pull
git push
Команда git push используется для установления связи с удалённым репозиторием, вычисления локальных изменений отсутствующих в нём, и собственно их передачи в вышеупомянутый репозиторий. Этой команде нужно право на запись в репозиторий, поэтому она использует аутентификацию.
git remote
Команда git remote служит для управления списком удалённых репозиториев. Она позволяет сохранять длинные URL репозиториев в виде понятных коротких строк, например «origin», так что вам не придётся забивать голову всякой ерундой и набирать её каждый раз для связи с сервером. Вы можете использовать несколько удалённых репозиториев для работы и git remote поможет добавлять, изменять и удалять их.
git archive
Команда git archive используется для упаковки в архив указанных коммитов или всего репозитория.
git submodule
Шпаргалка по осмотру и сравнению
git show
Команда git show отображает объект в простом и человекопонятном виде. Обычно она используется для просмотра информации о метке или коммите.
git shortlog
git describe
Команда git describe принимает на вход что угодно, что можно трактовать как коммит (ветку, тег) и выводит более-менее человекочитаемую строку, которая не изменится в будущем для данного коммита. Это может быть использовано как более удобная, но по-прежнему уникальная, замена SHA-1.
Шпаргалка по отладке
В Git есть несколько команд, используемых для нахождения проблем в коде. Это команды для поиска места в истории, где проблема впервые проявилась и собственно виновника этой проблемы.
git bisect
Команда git bisect — это чрезвычайно полезная утилита для поиска коммита в котором впервые проявился баг или проблема с помощью автоматического бинарного поиска.
git blame
Команда git blame выводит перед каждой строкой файла SHA-1 коммита, последний раз менявшего эту строку и автора этого коммита. Это помогает в поисках человека, которому нужно задавать вопросы о проблемном куске кода.
git grep
Команда git grep используется для поиска любой строки или регулярного выражения в любом из файлов вашего проекта, даже в более ранних его версиях.
Если вы только начинаете работать с Git, или переходите на Git с другой СКВ, то такая шпаргалка может вам очень пригодиться.
Git checkout
Переключение веток аналогично переключению старых коммитов и файлов, в которых рабочий каталог обновляется в соответствии с выбранной веткой/ревизией; вместе с тем новые изменения сохраняются в истории проекта, то есть это не просто операция чтения.
Переключение веток
Наличие выделенной ветки для каждой новой функции сильно отличается от традиционного рабочего процесса в SVN. Это значительно облегчает проведение новых экспериментов без страха разрушить существующую функциональность и позволяет одновременно работать со множеством несвязанных функций. Кроме того, ветки облегчают ведение нескольких совместных рабочих процессов.
Использование: существующие ветки
В вышеприведенном примере показано, как просмотреть список доступных веток с помощью команды git branch и переключиться на конкретную ветку (в данном случае — на ветку feature_inprogress_branch ).
Новые ветки
Переключение веток
Переключение на удаленную ветку
При совместной работе команды нередко используют удаленные репозитории. Такие репозитории могут размещаться на сервере с предоставлением общего доступа либо это может быть локальная копия другого коллеги. Каждый удаленный репозиторий содержит собственный набор веток. Для переключения на удаленную ветку нужно сначала извлечь содержимое этой ветки.
В современных версиях Git переключение на удаленную ветку не отличается от переключения на локальную ветку.
В старых версиях Git необходимо создавать новую ветку на основе удаленного репозитория ( remote ).
Кроме того, можно переключиться на новую локальную ветку и сбросить ее до последнего коммита удаленной ветки.
Открепленные указатели HEAD
Резюме
Готовы попробовать ветвление?
Ознакомьтесь с этим интерактивным обучающим руководством.
Git. Урок 3.
Ветвление. Создание, переключение и удаление веток. Команды: branch, checkout, status, log, diff.
1. Что такое ветка.
2. Зачем нужны ветки.
3. Создание новых веток.
4. Просмотр списка веток.
5. Переключение между ветками.
6. Просмотр состояния ветки. Команды: git status, git log, git diff.
6.1. Просмотр состояния файлов ветки. Команда git status.
6.2. Просмотр истории коммитов ветки. Команда git log.
6.3. Просмотр различий между коммитами. Команда git diff.
7. Удаление веток.
Дадим два определения ветки: на логическом и физическом уровнях.
1. Логический уровень.
С точки зрения логики, ветка – это последовательность коммитов. Чтобы проще было понять, что такое ветка, рассматривайте ее как некоторую временную шкалу. Коммиты в ней – снимки интересных моментов, идущие друг за другом в хронологической последовательности. Рисунок ниже поможет вам в интуитивном представлении.
2. Физический уровень
На физическом уровне, то есть с точки зрения внутренней реализации Git, ветка – это ссылка на последний коммит в этой ветке. Картинка ниже поможет вам понять, что к чему.
Преимущество веток в их независимости. Вы можете вносить изменения в файлы в одной ветке, например, пробовать новую функцию, и они никак не скажутся на файлах в другой ветке. Изначально в репозитории одна ветка, но позже мы рассмотрим, как создавать другие.
На самом деле, вначале, когда мы делаем свой первый коммит, Git автоматически создает основную ветку. Вы можете помнить, что ее имя по умолчанию «main» мы задавали в настройках Git в предыдущем уроке. Каждый раз, когда мы создаем новый коммит, Git автоматически перемещает указатель main на последний коммит. Тем не менее, в следующем уроке мы узнаем, как перемещать указатель ветки между коммитами самостоятельно.
Пока мы разбирались, что такое ветка, у вас мог возникнуть вопрос: зачем нужны такие сложности, ведь можно просто делать коммиты и откатывать изменения, когда нужно.
Дело в том, что Git – универсальная система контроля версий: она подходит и большим командам крупных корпораций, и индивидуальным разработчикам для их личных проектов.
Если вы работаете один – скорее всего вы будете редко использовать ветки, но если вы работаете в большой компании, без веток вам не обойтись.
Итак, чаще всего ветки используются в следующих случаях.
Способ 1. Команды git branch + git checkout
Команда git branch
На самом деле, git branch – очень мощная команда, которая умеет много всего. Сейчас мы рассматриваем ее как инструмент для создания веток. Ниже мы рассмотрим еще некоторые способы ее применения.
Команда git checkout
40 шестнадцатеричных цифр в файле выше и есть хэш последнего коммита, на который указывает новосозданная ветка.
С помощью команд git branch и git checkout вы можете создать неограниченное количество веток и переключаться между ними по мере необходимости. Обычно если ветка вам больше не нужна, ее сливают с основной и удаляют. Тема слияния веток заслуживает отдельного урока, поэтому про это мы поговорим в следующий раз, а удаление веток рассмотрим чуть ниже.
Команда git branch
# Теперь выведем только локальные ветки
$ git branch
* develop
feature
main
Теперь, когда мы поняли, как можно узнать имена веток в репозитории, давайте научимся переключаться между ними.
Команда git checkout
Этот маленький фокус позволит вам сэкономить время, особенно, если вы часто переключаетесь между ветками.
Шаг 1. Проверка существования ветки
Нужен этот этап, чтобы случайно не переключиться на ветку, которой не существует. Чтобы понять, как происходит этот процесс, нужно сделать небольшое отступление и рассказать, как вообще Git хранит информацию о существующих ветках.
Шаг 2. Переключение HEAD на нужную ветку
Шаг 3. Изменение рабочей копии
У внимательного читателя мог возникнуть вопрос: почему файлы в рабочей копии подгружаются именно из последнего коммита ветки? Что если до переключения с данной ветки, в ней были какие-то изменения, еще не добавленные в коммит? Что с ними будет? Ответ довольно прост. Согласно трем шагам, указанным выше, Git просто проигнорирует все такие файлы. То есть они останутся в вашей рабочей копии в том же состоянии, в котором и были до этого. Как правило, такое поведение очень неудобно, поскольку позволяет легко запутаться в структуре собственного проекта. Представьте: у вас два параллельных релиза, а вы, переключаясь между ветками, случайно занесли файлы одного релиза в ветку другого.
6.1. Просмотр состояния файлов ветки. Команда git status.
6.2. Просмотр истории коммитов ветки. Команда git log.
Команда git log
-p
Показывает изменения, сделанные в данном коммите.
—graph
Рисует ASCII-граф взаимосвязи коммитов.
—all
Выводит историю всех имеющихся коммитов на всех ветках.
adding complex algebra project
commit 603def20e5da2d512da2852011eb5be3fa156940 (origin/main, origin/HEAD)
Author: smartiqa
Date: Fri Dec 4 02:00:41 2020 +0300
В описании команды git log выше сказано, что в зависимости от ситуации, она может вывести полную историю репозитория, или же только историю некоторых коммитов. Давайте разбираться, как работает Git при выводе истории.
Общее правило, которым руководствуется Git при выводе истории, такое: иди по предкам коммитов, пока они не закончатся. Иногда это бывает удобно, иногда – нет.
Давайте разберемся, что делать, если мы хотим просмотреть историю коммитов только внутри какой-то конкретной ветки. То есть историю от момента создания ветки, до последнего коммита в ней. В этом случае нужно сделать следующее:


































