= Git: основные команды :title-separator: {sp}| :category: Программирование :tags: программирование, git :toc: == Ссылки * https://githowto.com/ru/changes_not_files[GitHowTo] * https://git-scm.com/book/ru/v2[ProGit] * https://github.com/maxliscia/git-pocket[Git Pocket Guide] == Установка В Debian/Ubuntu: [source,sh] ---- sudo apt-get install git ---- == Термины [width="100%",cols="18%,20%,62%",options="header",] |=== |Термин |Англ |Определение |Рабочий каталог |working tree, working directory |Набор файлов в текущем каталоге |Репозиторий |repository, repo |Контейнер, хранящий историю изменений файлов проекта |Индекс |index, staging area |Область между рабочим каталогом и репозиторием, в котором осуществляется подготовка к фиксации |SHA-1 |SHA-1 |Уникальный идентификатор, отражающий информацию об истории |Ветка |branch |Именованная последовательность в истории изменений |Фиксация (коммит) |commit |Набор файлов, записанных в историю одновременно |`HEAD` |`HEAD` |Имя ссылки на последнюю фиксацию в текущей ветке |Метка |tag |Именованная ссылка на некоторую фиксацию в истории |=== == Состояния Файлы в рабочем каталоге могут отслеживаться системой контроля версий (tracked) или нет (untracked). Отслеживаемые файлы, которые на диаграмме обозначены зелёным фоном, могут быть неизменёнными (unmodified), изменёнными (modified) или подготовленными к фиксации (staged). [.text-center] .Состояния [plantuml] ---- @startuml participant untracked as "Неотслеживамые\n(untracked)" box "Отслеживаемые" participant staged as "Подготовленные к фиксации\n(staged)" #55FF55 participant unmodified as "Неизменённые\n(unmodified)" #99FF99 participant modified as "Изменённые\n(modified)" #77FF77 end box untracked -> staged : git add staged -> unmodified : git commit unmodified -> modified : редактирование modified -> staged : git add modified -> untracked: git rm --cached unmodified -> untracked: git rm --cached staged -> untracked: git rm --cached @enduml ---- Основные команды, осуществляющие взаимодействие между рабочим каталогом, индексом, локальным и удалённым репозиторием, приведены на диаграмме ниже. [.text-center] .Команды [plantuml] ---- @startuml participant workspace as "Рабочий каталог\n(working dir)" participant index as "Индекс\n(index)" #77FF77 participant local as "Локальный репозиторий\n(local repository)" #FF7777 participant remote as "Удалённый репозиторий\n(remote repository)" #7777FF workspace -> local : git commit -a workspace -> index : git add (-u) index -> local : git commit local -> remote : git push == Обновление с сервера == remote -> workspace : git pull (rebase) remote -> local : fetch == Откат изменений == local -[#red]> workspace : git checkout HEAD index -[#red]> workspace : git checkout == Сравнение == local -[#blue]> workspace : git diff HEAD index -[#blue]> workspace : git diff @enduml ---- == Настройка [width="100%",cols="15%,35%,50%",options="header",] |=== |Команда |Ключи |Описание |`git config` |`--global user.name "John Doe"` |Имя текущего пользователя |`git config` |`--global user.email "mail@example.com"` |Почта текущего пользователя |`git config` |`--list` |Вывод текущей конфигурации |`git config` |`--global --list` |Вывод глобальной конфигурации |=== == Инициализация [width="100%",cols="15%,35%,50%",options="header",] |=== |Команда |Ключи |Описание |`git init` |`` |Создать пустой репозиторий в каталоге `` |`git clone` |`` `` |Создать в каталоге `` копию репозитория, находящегося по адресу `` |`git clone` |`--recursive ` `` |Создать в каталоге `` копию репозитория, находящегося по адресу ``, с учётом подмодулей |=== == Подмодули [width="100%",cols="15%,25%,60%",options="header",] |=== |Команда |Ключи |Описание |`git submodule` |`add ` |Добавить в каталог `` текущего репозитория подмодуль, находящийся по адресу `` |`git submodule` |`update --recursive --remote` |Обновить подмодули |`git submodule` |`sync --recursive` |Заменить адреса подмодулей на указанные в файле `.gitmodules` |=== Удаление подмодуля: [source,sh] ---- git submodule deinit git rm ---- == Фиксация [width="100%",cols="15%,25%,60%",options="header",] |=== |Команда |Ключи |Описание |`git add` |`` |Подготовить файл `` к фиксации |`git commit` | |Зафиксировать подготовленные файлы |`git commit` |`-a` |Зафиксировать все отслеживаемые файлы, которые были изменены |`git rm` |`` |Удалить файл из индекса и рабочего каталога |`git rm` |`-f ` |Force deletion of files from disk |`git rm` |`--cached ` |Untrack file (without deleting) |=== == Информация [width="100%",cols="15%,25%,60%",options="header",] |=== |Команда |Ключи |Описание |`git status` |`-s`            |Вывод информации о рабочем каталоге в краткой форме |`git log` |`--oneline` |Вывод журнала изменений в краткой форме |`git ls-files` | |Вывод списка отслеживаемых и подготовленных файлов |=== == $push branches (see tags for pushing tags) [width="100%",cols="15%,25%,60%",options="header",] [cols=",,",options="header",] |=== |Команда |Ключи |Описание |`git push` |` ` |Push branch to remote |`git push` |` --all` |Push all branches to remote |`git push` |`--d ` |`--delete` remote branch |=== == $remote * Remote connections are like bookmarks named after remote repos * `git clone` automatically creates a remote connection usually called `origin` [width="100%",cols="15%,25%,60%",options="header",] [width="100%",cols="36%,26%,38%",options="header",] |=== |Команда |Ключи |Описание |`git remote` |`-v` |List remote repository endpoints |`git branch` |`-r` |List remote repository branches |`git remote` |`add ` |Create namespaced connection to a remote repository |`git remote` |`rename ` |Rename connection |`git remote` |`rm ` |Remove connection |`git remote` |`add origin ` |Set remote origin |=== Reference: https://git-scm.com/docs/git-remote *Remove remote origin:* [source,shell] ---- # Remove `origin` settings from .git/config git remote rm origin # Remove `FETCH_HEAD` which still points to remote git rm .git/FETCH_HEAD ---- == $fetch-pull [width="100%",cols="15%,25%,60%",options="header",] |=== |Команда |Ключи |Описание |`git fetch` |`` |Fetch all branches from remote (without merge) |`git fetch` |` ` |Fetch specific branch |`git merge` |`/` |Merge fetched remote |`git pull` |`` |Fetch and merge in one command |=== Reference: https://git-scm.com/docs/git-fetch, https://git-scm.com/docs/git-pull == $branch [cols=",,",options="header",] |=== |Команда |Ключи |Описание |`git branch` | |List branches |`git branch` |`` |Create new branch |`git checkout` |`` |Switch to branch, or commit |`git branch` |`-m ` |Rename branch |`git merge` |`` |Merge changes from `` to current branch |`git branch` |`-d ` |`--delete` branch |=== Reference: https://git-scm.com/docs/git-branch == $diff [cols=",,",options="header",] |=== |Команда |Ключи |Описание |`git diff` | |Compare *`working directory`* and *`index`* | |`–-cached` |Compare *`index`* and *`latest commit`* | |`HEAD` |Compare *`latest commit`* and *`working directory`* | |`--stat` |Optional short format | |` ` |2 points in time to compare | |` | ` |Compare whole directory or limit to file |=== Reference: https://git-scm.com/docs/git-diff *Examples:* [source,shell] ---- ## compare changes made to README.md between working tree (default) and latest commit (HEAD) $ git diff --stat HEAD ./path/README.md ## compare changes made to README.md between 2 specific points in time (e.g. 2 commits) $ git diff --stat a649900 24bdd58 ./path/README.md ---- == $tag [width="100%",cols="36%,26%,38%",options="header",] |=== |Команда |Ключи |Описание |`git tag` | |List tags |`git tag` |`` |Create tag, from latest commit, lightweight |`git tag` |`-a -m ""` |Create tag, with `--annotate`, from latest commit |`git tag` |`-a -m "" ` |Create tag, with `--annotate`, from specific commit |`git tag` |`-d ` |`--delete` tag |`git show` |`` |Show tag data and message |`git checkout` |`` |Switch to specific point tag (not editable) |`git push` |` ` |Push specific tag to `` (recommended) |`git push` |` --tags` |Push all tags to `` (only if necessary) |=== Инициализация репозитория в каталоге `dir`: [source,sh] ---- git init dir ---- Клонирование репозитория `repo`, принадлежащего пользователю `user`, с сервера `gitlab.2` в каталог `dir`: [source,sh] ---- git clone git@gitlab.2:user/repo.git dir ---- Просмотр состояния рабочего каталога и репозитория: [source,sh] ---- git status ---- Краткая форма вывода состояния: [source,sh] ---- git status -s ---- Добавление файла `README.md` под версионный контроль и подготовка к фиксации: [source,sh] ---- git add README.md ---- Удаление файла `README.md` из индекса репозитория: [source,sh] ---- git rm --cached README.md ---- Зафиксировать файлы, подготовленные к фиксации: [source,sh] ---- git commit ---- Зафиксировать все отслеживаемые файлы, которые были изменены: [source,sh] ---- git commit -a ---- Отправить все ветки репозитория на сервер с меткой `origin`: [source,sh] ---- git push origin ----