Командный интерпретатор bash позволяет задавать произвольные алиасы для разных команд и выражений. Алиасы не являются командами сами по себе, но им, как и командам, можно передавать аргументы. Алиасы позволяют сделать вызов громоздких команд очень простым, с легко запоминающимися названиями.
Использовать Git я привык исключительно из консоли, но на ввод длинных команд с разными аргументами тратится значительное количество времени. Поэтому я ввёл практику использования алиасов. Для безопасных команд я использовал короткие алиасы, которые по сути стали горячими клавишами, а для функциональных — простые короткие слова из состава команд Git. Если команда опасная, то можно сделать её в два слова, написанных через дефис, для исключения случайного ввода. На самом деле, использование алиасов для работы с Git широко практикуется, я решил лишь преподнести отдельный вариант подборки алиасов, которые для меня оказались очень удобными.
Формат задания алиаса имеет следующий вид:
alias name="<выполняемый код>"
Основной проблемой алиасов является то, что они не подхватываются автоматически механизмом автодополнения кода. Их написание отличается от тех команд, которые зарегистрированы в системе автодополнения, поэтому приходится дополнительно регистрировать алиасы, назначая им соответствующие спецификации автодополнения (compspec) через встроенную в bash команду complete
. В случае с Git над complete
существует обёртка __git_complete
, в которую необходимо передавать предопределённые функции-обёртки, начинающиеся с префикса _git_
и оканчивающиеся названием подкоманды git. В Ubuntu весь связанный с этим код можно посмотреть в файле /usr/share/bash-completion/completions/git
.
Алиас | Действие |
| Получить изменения с сервера |
| Просмотреть текущее состояние локального репозитория |
| Просмотреть текущее состояние локального репозитория и количество изменённых строк |
| Просмотреть изменения, сделанные в файлах и ожидающие подтверждения, в стандартном diff-формате |
| Просмотреть изменения, сделанные в файлах и ожидающие подтверждения, с выделением одним только цветом |
| Список последних коммитов в кратком формате. |
| Список последних коммитов с развёрнутой информацией о них. |
| Переход на другую ветку или коммит, создание новой ветки с опцией |
| Получить изменения с сервера и влить их в текущую ветку. |
| Сделать коммит (зафиксировать изменения). |
| Добавить файлы или изменения в будущий коммит. |
| Отменить добавление изменений в будущий коммит. |
| Отправить новые коммиты на сервер. |
| Отправить коммиты на сервер с перезаписью их истории, если другие люди не успели отправить туда свои коммиты. |
| Влить заданную ветку в текущую. |
| Добавить изменения в уже сделанный коммит или изменить его комментарий. |
| Выполнить перезапись истории коммитов, например, переместив коммиты в конец другой ветки. |
| Переименовывание или удаление локальной ветки |
| Применить в текущей ветке отдельные существующие коммиты. |
| Сохранить свои текущие изменения во временное хранилище. |
| Применить свои текущие изменения из временного хранилища, но не удалять и оттуда. |
| Забрать свои изменения из временного хранилища и применить их. |
Ниже приведено примерное содержимое файла ~/.bash_aliases
с основными алиасами Git и кодом их автоматической регистрации в механизме автодополнения командой строки.
#!/bin/bash
alias f="git fetch --tags"
alias s="git status"
alias ss="git status && git diff --shortstat"
alias d="git diff"
alias dd="git diff --word-diff=color"
alias l="git log -n 20 --graph --pretty=format:'%Cred%h%Creset %an: %s / %Cgreen%cr%Creset %Creset %C(yellow)%d%Creset' --abbrev-commit --date=relative"
alias ll="git log"
alias go="git checkout"
#или alias gg="git checkout"
alias pull="git pull"
alias commit="git commit"
alias add="git add"
alias reset="git reset"
alias push="git push"
alias push-fix="git push --force-with-lease"
alias merge="git merge"
alias amend="git commit --amend"
alias rebase="git rebase"
alias branch="git branch"
alias pick="git cherry-pick"
alias stash="git stash"
alias apply="git stash apply"
alias pop="git stash pop"
# Регистрируем алиасы в системе автодополнения
git_completions="/usr/share/bash-completion/completions/git"
if [ -f "${git_completions}" ]; then
source "${git_completions}"
# Получаем массивы алиасов и соответствующих им команд git
cmds=( $(alias | grep -v ss | grep -Po '(?<=git )[\w-]+' | sed -r 's/[ -]+/_/g') )
aliases=( $(alias | grep -v ss | grep git | grep -Po '(?<=alias )\w+') )
# Регистрируем каждый алиас
for (( i = 0; i < ${#aliases[@]}; i++ )); do
a="${aliases[$i]}"
cmd="${cmds[$i]}"
__git_complete "${a}" _git_"${cmd}"
done
fi
Для того, чтобы файл с алиасами применялся при входе в систему, необходимо добавить его подключение в файл ~/.bashrc
с помощью команды source
(или .
). Файл ~/.bashrc
запускается на исполнение всегда при старте командного интерпретатора bash, поэтому если файл редактировался из консоли, потребуется её заново открыть или запустить вложенный командный интерпретатор bash.
if [ -f ~/.bash_aliases ]; then
. ~/.bash_aliases
fi
Алиасы s
, d
и l
простые, дают необходимый минимум информации. Задумка двухбуквенных в том, чтобы дать слегка больше информации, если это требуется. С помощью f
можно получить последние изменения в репозитории и влить их в текущую ветку с помощью pull
или pull -r
. Через l
можно посмотреть, что за новые коммиты прилетели в ветку, или что было последним из изменений, а через ll
— подробно изучить коммиты. Переключиться на другую ветку можно через go
, создать новую ветку можно через go -b
. При создании коммита, в общем случае, сначала вводится s
, проверяется на какой мы ветке, какие файлы требуется добавить, затем d
, чтобы проверить свои изменения. Через add
добавляются файлы (или add -i
для выбора отдельных изменений в файлах), через commit -m
создаётся новый коммит. Если вдруг в тексте сообщения коммита оказалась опечатка, можно быстро всё поправить через amend
. Если в main-ветку успели прилететь новые коммиты, можно сделать rebase main
. И потом сделать push
. Если ветка своя собственная, то можно делать rebase -i
с исправлениям прошлых коммитов и отправить модифицированные коммиты через push-fix
.
Если шла работа, но срочно понадобилось переключиться на другую ветку, можно временно убрать свои изменения через stash
, переключиться на другую ветку через go
. Потом можно вернуть изменения с помощью apply
или pop
. Отдельные коммиты из других веток можно применять с помощью pick
, также это может быть полезным, если случайно сделать изменения в отделённом HEAD (например, в подмодуле).
Алиасы могут совпадать с существующими командами. Если такие команды обычно не используются, то это проблемой не является. Если же команды понадобятся, то в случае исполняемых файлов всегда можно указать полный путь к файлу. Не будет проблем и с командами, которые запускаются от имени суперпользователя, поскольку алиасы прописаны лишь для непривилегированного пользователя. Если используется язык Go, то с использованием алиаса go
могут возникнуть проблемы. В качестве решения можно изменить алиас на gg
или gc
, либо же сделать алиас golang
для команды go
. Здесь кому как удобнее.
В Ubuntu 21.10 при использовании алиаса над git checkout
выводятся сообщения об ошибках. Происходит это из-за того, что одна из переменных в целочисленных сравнениях оказывается пустой. Вариантом подавления вывода ошибок является замена в файле /usr/share/bash-completion/completions/git
сравнения через квадратные скобки на арифметическое сравнение через двойные скобки, например, (( var1 < var2 ))
, в которых можно использовать названия переменных без предшествующего знака $
. Такое исправление работает и в zsh, на который автодополнение тоже рассчитано.
Патч, решающий проблему
--- /usr/share/bash-completion/completions/git 2021-08-09 15:29:27.000000000 +0300
+++ ./git 2022-04-08 23:32:38.501198226 +0300
@@ -1011,7 +1011,7 @@
if [ "$cmd" = "remote" ]; then
((c++))
fi
- while [ $c -lt $cword ]; do
+ while (( c < cword )); do
i="${words[c]}"
case "$i" in
--mirror) [ "$cmd" = "push" ] && no_complete_refspec=1 ;;
@@ -1187,7 +1187,7 @@
done
local wordlist="$1"
- while [ $c -lt $cword ]; do
+ while (( c < cword )); do
for word in $wordlist; do
if [ "$word" = "${words[c]}" ]; then
if [ -n "${show_idx-}" ]; then
@@ -1221,7 +1221,7 @@
done
local wordlist="$1"
- while [ $c -gt "$__git_cmd_idx" ]; do
+ while (( c > __git_cmd_idx )); do
((c--))
for word in $wordlist; do
if [ "$word" = "${words[c]}" ]; then
@@ -1283,7 +1283,7 @@
__git_has_doubledash ()
{
local c=1
- while [ $c -lt $cword ]; do
+ while (( c < cword )); do
if [ "--" = "${words[c]}" ]; then
return 0
fi
@@ -1449,7 +1449,7 @@
{
local i c="$__git_cmd_idx" only_local_ref="n" has_r="n"
- while [ $c -lt $cword ]; do
+ while (( c < cword )); do
i="${words[c]}"
case "$i" in
-d|-D|--delete|-m|-M|--move|-c|-C|--copy)
@@ -2479,7 +2479,7 @@
__git_config_get_set_variables ()
{
local prevword word config_file= c=$cword
- while [ $c -gt "$__git_cmd_idx" ]; do
+ while (( c > __git_cmd_idx )); do
word="${words[c]}"
case "$word" in
--system|--global|--local|--file=*)
@@ -3213,7 +3213,7 @@
_git_tag ()
{
local i c="$__git_cmd_idx" f=0
- while [ $c -lt $cword ]; do
+ while (( c < cword )); do
i="${words[c]}"
case "$i" in
-d|--delete|-v|--verify)
@@ -3388,7 +3388,7 @@
local __git_C_args C_args_count=0
local __git_cmd_idx
- while [ $c -lt $cword ]; do
+ while (( c < cword )); do
i="${words[c]}"
case "$i" in
--git-dir=*)
На практике я использую несколько меньший набор алиасов, в списке же привёл все, какие могут пригодиться в повседневной работе. Надеюсь, этот список кому-то окажется полезным, удачного использования!