Syntax highlighting of
itnotes/git
= GIT =
<<TableOfContents()>>
== Полезные команды ==
=== Конфигурация ===
{{{#!highlight bash
git config --global user.name "John Doe"
git config --global user.email johndoe@example.com
# --- Установка редактора для коммитов
git config --global core.editor "vim"
# --- Храним доступы в файле ~/.git-credentials
# Доступы сохраняются там автоматически
git config --global credential.helper store
}}}
=== Ветвление ===
{{{#!highlight bash
# --- удаление веток по шаблону
git branch | egrep "KDK-[0-9]+" | xargs git branch -D
# --- фиксируем изменения из detached-ветки
# шаблон: git push <remote name> HEAD:<remote branch name>
git push origin HEAD:master
}}}
=== Клонирование и слияние ===
{{{#!highlight bash
# Клонирование крайнего коммита
git clone --depth=1 URL
# "Переход" к конкретному коммиту
git checkout [revision] .
# "Переход" на крайний коммит
git checkout -
# --- слияние со "схлопываением" коммитов
git checkout master
git merge --squash feature123
git commit -m 'merged feature #123'
# --- "перетаскивание файлов между ветками
git checkout gh-pages # переходим в целевую ветку gh-pages
git checkout master -- myplugin.js # "забираем" файл из ветки master
git commit -m "Update myplugin.js from master" # фиксируем изменения
}}}
=== Меняем историю ===
[[https://www.atlassian.com/ru/git/tutorials/rewriting-history/git-rebase|git rebase about|class=" moin-https"]]
{{{#!highlight bash
# --- схлопываем 3 коммита через rebase (в редакторе выбираем squash)
git rebase -i HEAD~3
# --- перетаскиваем коммит в ТЕКУЩУЮ ветку
git cherry-pick <commithash>
# --- удаляем историю
# источник: https://xebia.com/blog/deleting-your-commit-history/
git checkout --orphan temp_branch
git add -A
git commit -m "Initial commit"
git branch -D main
git branch -m main
git push --force origin main
}}}
=== Журнал и история ===
{{{#!highlight bash
# Список коммитов по автору
git log --author="John Smith"
# история изменений файла
git log -- app/some/file.rb
# отображение изменений конкретного файла
git log --all --full-history -- <path/to/file>
# отображение файла из заданного коммита
git show $REV:$FILE
# поиск по commit сообщению
git log --all --grep='Build 0051'
# вывод журнала в виде графа с изменением формата
git log --pretty="format:%H %s" --graph
}}}
=== Отображение изменений ===
{{{#!highlight bash
# отображение отслеживаемой ветки
git branch -vv
# Отображение хэша крайнего коммита
git rev-parse HEAD
# Отображение всех измененных файлов в текущей и develop ветвях .
# Можно использовать опцию --name-only
git diff --name-status develop
# Отображение измененных файлов только ветви notMainDev
# Если ветвь notMainDev влита, то ничего не выводится
git diff --name-only <notMainDev> $(git merge-base <notMainDev> <mainDev>)
# то же, но короче
git diff --name-only mainDev...
# статусы
# `A` Added
# `C` Copied
# `D` Deleted
# `M` Modified
# `R` Renamed. Статус может дополняться числом, например R100
# `T` have their type (mode) changed
# `U` Unmerged
# `X` Unknown
# `B` have had their pairing Broken
# `*` All-or-none
# Отображение изменений коммита
git show <revhash>
}}}
=== Индекс и откат ===
{{{#!highlight bash
# Удаление файла из кэша
git rm --cached some-file
# Удаление директории из кэша
git rm --cached -r some-directory
# remove all files from git cache
git rm -r --cached .
git add .
git commit -m ".gitignore is now working"
# --- откат изменений
git clean -f
git checkout -- *
# Изменение сообщения крайнего коммита
git commit --amend
# Мягкий откат коммита - файлы остаются скорректированными, отменена процедура коммита
git reset --soft HEAD^
# жесткий откат
git reset --hard HEAD^
# отмена индексации, был зеленый - стал красный
git reset HEAD filename
}}}
=== Прячем изменения ===
{{{#!highlight bash
# --- прячем изменения
git stash
# --- список спрятанных изменений
git stash list
# --- "вытащить" спрятанные изменения в текущей ветке
git stash apply
# --- "вытащить" изменения через указания индекса в списке
git stash apply stash@{2}
}}}
=== Метки ===
{{{#!highlight bash
# Создание метки (тэга)
git tag -a 1.0.1 -m "Version 1.0.1"
# Создание метки для коммита
git tag -a 0.2.0 9fceb02 -m "Version 0.2.0"
# Загрузка метки в репозиторий
git push origin 1.0.1
# Удаление метки из локального репозитория
git tag -d 1.0.2
# Удаление метки из удаленного репозитория
git push origin :refs/tags/1.0.2
# Список меток с сообщениями
git tag -l --format='%(tag) %(subject)'
# --- создаем ветку из тега
git fetch --all --tags
git checkout tags/v1.0 -b v1.0-branch
}}}
=== Submodules ===
{{{#!highlight bash
# https://git-scm.com/book/ru/v2/Инструменты-Git-Подмодули
# Добавление подмодуля в проект
git submodule add REPO_URL PATH
# отображение изменений
git diff --cached SUBMODULE
# клонирование репозитория с подмодулями
git clone REPO-URL
cd repo/submodule/dir
git submodule init
git submodule update
# тоже одной командой
git clone --recursive REPO-URL
# обновление модуля
cd submodule/dir
git fetch
git merge origin/master
# --- обновление всех модулей в repo
# @note Если необходимо обновится не из master, то в файле .gitmodules
# в соответствующей секции модуля необходимо добавить branch = ..., напр:
# branch = stable
git submodule update --remote
# отображение изменений в модуле
cd ../repo/root/dir
git diff --submodule
# конфигурация для отображения изменений в модулях командой git diff (без --submodule)
git config --global diff.submodule log
# --- если в проект добавлен git-модуль, то при выполнии git pull
# будет создана директория для модуля, но она будет пустая.
# Чтобы ее "заполнить", необхомо выполнить команды
git submodule init
# Подмодуль «.path/or/name/of/submodule» (remote url) зарегистрирован по пути «./»
git submodule update
# cd dir/with/new/git-module
# git submodule init
# Подмодуль «.path/or/name/of/submodule» (remote url) зарегистрирован по пути «./»
# git submodule update
# Клонирование в ...
}}}
[[https://gist.github.com/myusuf3/7f645819ded92bda6677|Удаление submodule|class=" moin-https"]]
* Delete the relevant section from the .gitmodules file.
* Stage the .gitmodules changes `git add .gitmodules`
* Delete the relevant section from .git/config.
* Run `git rm --cached path_to_submodule` (no trailing slash).
* Run `rm -rf .git/modules/path_to_submodule` (no trailing slash).
* Commit `git commit -m "Removed submodule"`
* Delete the now untracked submodule files `rm -rf path_to_submodule`
== Полезные ссылки ==
[[https://www.conventionalcommits.org/ru/v1.0.0-beta.2/|Conventional Commits|class=" moin-https"]]
https://git-scm.com/book/ru/v2
https://stackoverflow.com/questions/67699/how-to-clone-all-remote-branches-in-git
== Полезные утилиты ==
=== gitk ===
Графический интерфейс для git
https://stackoverflow.com/questions/1786027/how-to-view-file-history-in-git
{{{#!highlight bash
sudo apt install gitk
# show file change histroy
gitk path/to/file
}}}
== Credentials ==
При работе с git по http/https можно зафиксировать имя пользователя и включить временное запоминание пароля.
[[https://stackoverflow.com/questions/10054318/how-to-provide-username-and-password-when-run-git-clone-gitremote-git|StackOverflow|class=" moin-https"]]
{{{#!highlight bash
git config --global credential.helper cache
git config --global credential.https://github.com.username foo
git clone ...
}}}
Глобальная конфигурация
{{{
~/.gitconfig
[color]
ui = true
[user]
name = Nik Mikhaylichenko
email = nn.mikh@yandex.ru
[credential "https://github.com"]
username = nmix
}}}
Локальная конфигурация
{{{
# .git/config
[user]
name = Николай Михайличенко
email = n.mihailichenko@krasnodar.pro
[credential]
username = zoid
}}}
== Изменение commit message ==
{{{#!highlight bash
git commit --amend
git push --force
}}}
= Troubleshooting =
== fatal: Needed a single revision ==
При обновлении git-модулей для одного из модулей получаем ошибку
{{{#!highlight bash
git submodule update --remote
# ...
fatal: Needed a single revision
}}}
Проблема оказалось в том, что автор модуля toml переименовал ветку master в ветку main
Необходимо прописать наименовании новой ветки в конфигурации модуля
{{{
# .gitmodules
[submodule ".vim/bundle/vim-toml"]
path = .vim/bundle/vim-toml
url = https://github.com/cespare/vim-toml.git
branch = main # <------------------
}}}
== если что-то не работает ==
`GIT_TRACE=1 GIT_SSH_COMMAND="ssh -vvv" git clone https://git.example.com/my/app.git app`
== sign_and_send_pubkey ==
При попытке залить изменения на сервер, получаем ошибку
{{{#!highlight bash
git push -u origin master
sign_and_send_pubkey: signing failed: agent refused operation
git@bitbucket.org: Permission denied (publickey).
fatal: Не удалось прочитать из внешнего репозитория.
Удостоверьтесь, что у вас есть необходимые права доступа
и репозиторий существует.
}}}
Ошибка связана с некорректным файлом ''~/.ssh/id_rsa'', либо правами доступа к нему.
{{{#!highlight bash
ssh-add
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: UNPROTECTED PRIVATE KEY FILE! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '/home/zoid/.ssh/id_rsa' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
}}}
Необходимо скорректировать права доступа к файлу и повторить операцию
{{{#!highlight bash
chmod 700 .ssh/id_rsa
ssh-add
Enter passphrase for /home/zoid/.ssh/id_rsa:
...
Identity added: ...
}}}