Шпаргалка по работе с командами git
Используемые термины: Git, Gitlab, Bitbucket.
Утилита git позволяет работать с системами контроля версий, которые реализованы на базе одноименной технологии. К таким репозиториям можно отнести GitHub, Gitlab, Bitbucket, Gogs и другие.
В данной инструкции мы рассмотрим синтаксис команд git, а также приведем примеры работы с ними.
Список команд и их описание
Общий синтаксис работы с утилитой git:
git [--version] [--help] [-C <path>] [-c <name>=<value>]
[--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
[-p|--paginate|-P|--no-pager] [--no-replace-objects] [--bare]
[--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
[--super-prefix=<path>] [--config-env=<name>=<envvar>]
<command> [<args>]
* обратите внимание, что обязательными являются git <command>.
Утилита git имеет большое число команд, которые разработчики делят на:
1. HIGH-LEVEL COMMANDS, которые в свою очередь, подразделяют на:
- основные.
- вспомогательные:
- команды управления.
- команды опроса.
- команды взаимодействия (экспорт, импорт, конвертация).
2. LOW-LEVEL COMMANDS, которые делятся на:
- команды управления.
- команды опроса.
- синхронизации репозиториев.
- внутренние вспомогательные команды.
С полным перечнем команд можно ознакомиться, введя:
git help -a
Мы же рассмотрим только HIGH-LEVEL COMMANDS.
Команда | Описание |
---|---|
Основные команды | |
add | Добавляем файлы в индекс git. Далее утилита будет работать с индексными файлами для добавления комментария (git commit) и отправки их в репозиторий (git push). |
am | Применяет коммиты (патч-файлы) из почтового ящика. |
archive | Создает архив из бранча. |
bisect | Бинарный поиск коммита, который привел к ошибке. |
branch | Работа с ветками (бранчами) — просмотр, создание, удаление. |
bundle | Позволяет упаковать в бинарный файл то, что было бы отправлено в репозиторий с помощью git push. После его можно переместить на другом репозитории. |
checkout | Переключает нас на разные ветки репозитория и восстанавливает файлы в рабочем бранче (приводит содержимое в соответствие с удаленным репозиторием). Также позволяет создать новый бранч. Позже данную команду разделили на switch и restore. |
cherry-pick | Из нескольких коммитов собирает один и применяет его в текущей ветке. |
citool | Графическая альтернатива git commit. |
clean | Удаляет файлы, которые не отслеживаются в репозитории (файлы которые попали в папку, но не были добавлены в индекс с помощью git add). |
clone | Клонируем репозиторий. |
commit | Добавляет описание к файлам, которые ранее были добавлены в индекс с помощью git add. |
describe | Дает объекту удобочитаемое имя. |
diff | Сравнение содержимого (фиксами, деревьями и так далее). |
fetch | Скачать объекты и ссылки из другого репозитория. Обратите внимание, что данная команда только скачивает информацию об изменениях, но не сами файлы. Для этого мы уже используем git pull. |
format-patch | Готовит патчи из коммитов для возможности их отправки по почте и применения в другом репозитории. |
gc | Чистка репозитория от устаревших и временных данных. |
grep | Печатает строку по шаблону. |
gui | Портативный графический интерфейс к Git. |
init | Создание нового репозитория или повторная инициализация существующего. |
log | Показывает журналы коммитов. |
maintenance | Запускает задачи для оптимизации данных репозитория. |
merge | Объединяет ветки. |
mv | Перемещает или переименовывает файл. |
notes | Создать примечание для объекта. |
pull | Скачиваем файлы из другого репозитория. |
push | Отправляет на сервер файлы, которые были добавлены в индекс с помощью git add. |
range-diff | Сравнивает диапазоны коммитов. |
rebase | Слияние веток с заменой всех коммитов на один единственный. В итоге мы получаем ветку, которая, как будто, только что была создана заново. |
reset | Сбрасывает состояние изменений для текущей ветки. Позволяет без объединений заменить файлы при выполнении git pull. |
restore | Восстановить файлы рабочего дерева. А именно, приводит содержимое в соответствие с удаленным репозиторием. |
revert | Отмена некоторых коммитов. |
rm | Удаляет файлы из ветки и индекса. |
shortlog | Выполняет группировку всех коммитов по автору. |
show | Показывает объект в удобочитаемом виде. |
stash | Позволяет отложить на время сделанные изменения, чтобы применить их позже. |
status | Показывает статус — название бранча, в котором мы находимся, нужно ли его обновлять, сколько файлов в индексе и так далее. |
submodule | Работа с подмодулями (инициализация, обновление или проверка). |
switch | Позволяет переключаться между ветками. |
tag | Работа с тегами. |
worktree | Управление несколькими рабочими ветками. |
Вспомогательные (управление) | |
config | Позволяет работать с настройками репозитория — читать их или задавать новые значения опциям. |
fast-export | Экспорт данных. |
fast-import | Импорт данных. |
filter-branch | Позволяет изменить содержимое коммитов по заданному алгоритму. |
mergetool | Инструменты для решения проблем с git merge. |
pack-refs | Для решения проблемы хранения и производительности путем сохранения ссылок в одном файле. |
prune | Позволяет удалить все недоступные объекты из базы данных. |
reflog | Управление журналом изменений. |
remote | Управляйте набором репозиториев, чьи ветки поставлены на отслеживание (git branch --track). |
repack | Объединение всех объектов, которые в данный момент не находятся в «пакете». |
replace | Меняет содержимое, например, можно заменить один коммит другим или содержимое объекта. |
Вспомогательные (опроса) | |
annotate | Добавить аннотацию для каждой строке файла информацией из коммита, который добавил данную строку. |
blame | Показывает ревизию и автора последней модификации для каждой строки файла. |
bugreport | Сбор информации для отправки отчета. |
count-objects | Посчитать количество распакованных объектов и их использование на диске. |
difftool | Покажет изменения с помощью обычных инструментов сравнения. |
fsck | Проверка работы объектов в базе данных. |
help | Отобразить справочную информацию по работе с git. |
instaweb | Просмотреть рабочий проект в gitweb. |
merge-tree | Выводит на экран результат слияния трех веток. |
rerere | Позволяет Git запомнить разрешенную часть конфликта, так что в случае возникновения такого же конфликта, Git сможет его разрешить автоматически. |
show-branch | Показать ветки и их коммиты. |
verify-commit | Проверяет подпись GPG коммитов. |
verify-tag | Проверяет подпись GPG тегов. |
whatchanged | Показать журналы с различиями, которые вводит каждый коммит. |
Команды взаимодействия | |
archimport | Импорт репозитория GNU Arch в Git. |
cvsexportcommit | Экспортирует коммиты из Git в хранилище CVS. |
cvsimport | Импортирует репозиторий CVS в Git. |
cvsserver | Эмулятор сервера CVS для Git. |
imap-send | Отправить коллекцию патчей в папку IMAP. |
p4 | Импорт из репозиториев Perforce. |
quiltimport | Применяет набор исправлений quilt к текущей ветке. |
request-pull | Создает сводку ожидающих изменений. |
send-email | Отправить коллекцию исправлений по электронной почте. |
svn | Двунаправленная работа между репозиторием Subversion и Git. |
В данной таблице приведены команды с кратким описанием, по которому не всегда можно понять всех возможностей и назначения команды. Для того, чтобы получить подробное описание с опциями и примерами можно воспользоваться командой git help, например, чтобы прочитать о git pull вводим:
git help pull
Примеры некоторых команд GIT
Рассмотрим теперь некоторые простые примеры из жизни. По мере необходимости, данный список будет пополняться.
1. Отправить все изменения в репозиторий. Это самая часто используемая связка команд git:
git add .
git commit -m "My comment"
git push
Первая команда добавит в индекс все файлы, которые были изменены, вторая добавит на низ комментарий My comment и последняя отправит изменения на сервер.
2. Клонировать проект из репозитория. Тоже достаточно популярная команда. Она позволяет не создавать и инициализировать локальный репозиторий проекта, а сразу получить его с сервера.
Клонировать с мастер-ветки:
git clone <ссылка до репозитория>
Или мы можем склонировать проект из репозитория с определенной его ветки:
git clone -b <имя ветки> <ссылка до репозитория>
После клонирования в текущем каталоге появится папка с названием проекта.
3. Переключение между ветками:
git checkout master
* в данном примере мы переключились на ветку master.
Посмотреть и убедиться, что мы переключились можно командой:
git branch
Также мы можем проверить состояние репозитория и, при необходимости, закачать изменения:
git status
git pull
4. Создать новый бранч и переключиться на него:
git branch
git pull
git checkout -b new-branch
git branch
Сначала мы смотрим, в каком бранче находимся (из него будет создан новый), после закачиваем все обновления с репозитория и создаем бранч с названием new-branch. Команда checkout переключает нас сразу на него. В конце мы смотрим, в какой ветке сейчас находимся.
Если мы хотим сразу отправить изменения на сервер, вводим:
git push -u origin new-branch
5. Переписать локальный репозиторий.
Иногда бывает так, что изменения внесены как на удаленном репозитории, так и локальном. В этом случае при попытке закачать файлы произойдет слияние содержимого. Если мы уверена на все 100, что локальные данные нам не нужны, выполняем:
git reset --hard
git clean -f -d
git pull
Сначала мы сбросим все наши изменения для текущей ветки. После удалим все файлы, которых нет в репозитории. И наконец, загрузим все изменения из удаленного репозитория.
6. Скачать все ветки для проекта.
На stackoverflow есть такое решение:
git branch -r | grep -v '\->' | sed "s,\x1B\[[0-9;]*[a-zA-Z],,g" | while read remote; do git branch --track "${remote#origin/}" "$remote"; done
git fetch --all
git pull --all
Сначала мы получаем все ветки на удаленном репозитории и отмечаем их как отслеживаемые, то есть теперь наш локальный репозиторий будет учитывать изменения в них. После двумя оставшимися командами мы загружаем все изменения и файлы.
7. Отправка комментария без изменений.
Предположим, что нам не нравится комментарий для последнего коммита. Мы хотим его поменять без внесения изменений в репозиторий. Это делается двумя командами:
git commit --allow-empty -m "Added fix changes"
git push
Первой командой мы добавили комментарий для нового коммита, второй — отправили изменения в репозиторий.
8. Сравнение данных.
С помощью команды diff мы можем выполнить сравнение содержимого репозитория. Рассмотрим несколько примеров.
Для сравнения веток сначала переключимся на оба бранча и обновим содержимое:
git checkout branch1
git checkout branch2
git fetch --all
* предполагается, что мы будем сравнивать ветки branch1 и branch2.
Для сравнения содержимого теперь вводим:
git diff branch1
* так как последний раз мы переходили в ветку branch2, то данная команда сравнит текущую ветку с указанно, то есть, в нашем случае, branch2 с branch1.
На экран будет выведено много информации. Мы можем ограничить область сравнения конкретным каталогом или файлом:
git diff branch1 -- <имя каталога или файла>
Примеры работы с Git
В данном примере рассмотрим более сложные сценарии работы с git, а также некоторые настройки репозиториев.
1. Слить ветки проекта
Предположим, что мы хотим объединить содержимое веток new-branch и master. При этом, последняя будет принимающей.
Переходим к принимающей ветке:
git switch master
Если нам нужна ветка по умолчанию, то она не всегда будет иметь имя master. Чтобы узнать default-бранч для проекта, вводим следующее.
а) на Linux:
git remote show origin | grep 'HEAD branch'
б) на Windows:
git remote show origin | find 'HEAD branch'
* где origin — имя репозитория проекта по умолчанию.
Проверяем, что мы там, где нужно
git branch
Актуализируем содержимое:
git pull
Выполним объединение:
git merge new-branch
* мы вливаем содержимое указанного бранча (new-branch) в текущий (master).
Заливаем изменения в удаленный репозиторий:
git push
После при необходимости, рабочую ветку можно удалить:
git branch -d new-branch
git push origin --delete new-branch
* локально и удаленно.
2. Смена адреса подключения к репозиторию с https на SSH
При клонировании репозитория мы задаем протокол подключения HTTP или SSH, который заносится в конфигурацию локального репозитория и будет использоваться в будущем для команд git pull и git push. По разным обстоятельствам, мы можем захотеть поменять протокол подключения. Рассмотрим процесс на примере перехода с https на SSH.
Переходим в каталог локального репозитория. Смотрим, по какому адресу идет подключение к репозиторию:
git remote -v
Предположим, мы видим:
origin https://github.com/dmosk/reponame.git (fetch)
origin https://github.com/dmosk/reponame.git (push)
Поменяем протокол командой:
git remote set-url origin git@github.com:dmosk/reponame.git
Снова смотрим результат:
git remote -v
Теперь мы должны увидеть:
origin git@github.com:dmosk/reponame.git (fetch)
origin git@github.com:dmosk/reponame.git (push)
Теперь при следующем обращении к гиту, подключение будет выполняться с использованием SSH.
3. Сливаем несколько проектов (репозиториев) в один с сохранением истории
Предположим, что у нас есть два проекта, которые находятся в разных репозиториях:
- repo1
- repo2
У нас появилась необходимость объединить проекты в один с названием repo-merged, в корне которого будут 2 папки:
- /repo1 (с содержимым repo1).
- /repo2 (с содержимым repo2).
Лучше всего работать в отдельном каталоге, например:
mkdir /tmp/merged
cd /tmp/merged
Клонируем все 3 проекта:
git clone git@github.com:dmosk/repo1.git
git clone git@github.com:dmosk/repo2.git
git clone git@github.com:dmosk/repo-merged.git
Мы готовы начать.
а) Шаг 1 — подготовка локальных проектов к сливанию.
Если нам нужно объединить проекты без создания в целевом репозитории папок для содержимого каждого из репозиториев, то данный шаг можно пропустить.
Переходим в каталог первого проекта:
cd repo1
Создаем каталог с названием самого проекта
mkdir repo1
* мы условились, что в корне проекта repo-merged будут каталоги repo1 и repo2. При необходимости, можно их назвать как угодно.
Перенесем содержимое проекта в созданный каталог:
git mv -k * repo1/
Обратите внимание, что данная команда перенесет только видимые файлы. Скрытые, которые можно посмотреть командой:
ls -la
... останутся в корне. Их нужно либо перенести вручную в созданный каталог, либо оставить (но учитывать, что данные файлы будут сливаться), либо удалить, например:
git rm .gitignore
Коммитим изменения:
git commit -m "Prepared to merge"
Переходим ко второму проекту:
cd ../repo2
Повторяем действия:
mkdir repo2
git mv -k * repo2/
git commit -m "Prepared to merge"
Ни в коем случае не выполняйте push в основной репозиторий, так как это приведет к изменениям на git-сервере. Данные директории после сливания лучше удалить.
б) Шаг 2 — сливаем проекты.
Идем в каталог репозитория, в который будем сливать данные:
cd ../repo-merged
Добавляем пути до наших подготовленных репозиториев:
git remote add repo1 ../repo1
git remote add repo2 ../repo2
Скачиваем метаданные:
git fetch repo1
git fetch repo2
Сливаем проекты:
git merge repo1/master --allow-unrelated-histories
git merge repo2/master --allow-unrelated-histories
* обратите внимание, что в вашем случае основная ветка может быть не master.
Репозитории слиты.
в) Шаг 3 — заливаем изменения на сервер.
При желании, мы можем посмотреть на историю изменений проекта:
git log
Удаляем из настройки подключенные локальные репозитории:
git remote rm repo1
git remote rm repo2
Подтверждаем все сделанные изменения:
git commit -m "Merged"
И заливаем изменения репозитория repo-merged на сервер:
git push
Готово.