MyTetra Share
Делитесь знаниями!
Как посмотреть какие команды генерирует git gui
Время создания: 21.01.2022 13:27
Текстовые метки: git, git-gui, команды, генерирует, создает, консоль, tcl, tk
Раздел: Компьютер - Программирование - Системы контроля версий (VCS) - Git
Запись: xintrea/mytetra_syncro/master/base/1642760840vc8e3lhufg/text.html на raw.github.com

Наверное, многим пользователям графического интерфейса git gui приходила в голову мысль, что хорошо бы видеть, какие команды под капотом генерирует эта графическая надстройка. Интерфейс этой Open Source программы, мягко говоря, не самый очевидный, и чтобы понимать, что программа делает, нужно видеть создаваемые ей команды Git.


Сразу скажу, что на практике оказалось, что толку от видимости этих команд не очень то и много. Это происходит по причине того, что git gui генерирует очень заковыристые команды даже для простых действий. Например, для переключения на другую ветку, вместо команды "git checkout <имяВетки>" интерфейс сгенерирует нечто подобное:



git rev-parse --verify HEAD

git symbolic-ref -m {checkout: moving from master to new_branch} HEAD refs/heads/new_branch



Итак, как модифицировать git gui, чтобы увидеть его команды git?


Для начала понадобятся исходники git (ибо git gui входит в состав git) из официального зеркала репозитария:



https://github.com/git/git



После получения исходников, их надо собрать в том виде, в котором они есть, без модификации и без инсталляции. Для этого нужны команды:



make configure

./configure

make



Если сборка завершилась успешно, это значит, что можно начинать модифицировать исходники. Если при сборке возникли проблемы, их нужно устранить. Например, доустановив autotools или другие пакеты, которых не хватает.


Программа git gui написана на Tcl/Tk. А это значит, что данный интерфейс работает просто по факту интерпретации файлов *.tcl. Однако базовая часть git gui сделана в виде следующего файла:



/git-master/git-gui/git-gui.sh



Данный bash-скрипт представляет из себя скрипт с BASH-заголовком и несколькими строками с командами BASH, самая последняя из которых - это вызов tcl-интерпретатора wish. Все последующие строки - это исполняемый Tcl-код.


В данном коде имеется процедура, через которую происходит вызов консольных команд. Достаточно в нее поместить "дебажный" вывод в консоль, и все генерируемые bash-команды git будут выводиться в консоль:



proc _trace_exec {cmd} {


# Add debug output

puts stdout "Command: $cmd"


if {!$::_trace} return

...



После такого исправления надо выйти в корневую директорию репозитария (т. е. выйти из каталога git-gui), и выполнить команду make:



$ make

   SUBDIR git-gui

   GEN git-gui

   SUBDIR gitk-git

   SUBDIR templates



Будет перегенерирован файл /git-master/git-gui/git-gui, который представляет из себя немного модифицированный файл /git-master/git-gui/git-gui.sh, в котором будут жестко прописаны пути к некоторым системным директориям.


Полученная программа git-gui, если сборка была без задания префикса, предполагает, что в системе существует каталог /usr/local/share/git-gui/lib, в котором расположены все файлы, скопированные из директории /git-master/git-gui/lib. Это копирование происходит при инсталляции самосборного git из-под пользователя root командой:



# make install



То есть, надо либо проинсталлировать самосборный git, при этом снеся системный, либо извращаться как-то по-другому. Просто скопировать бинарник git-gui поверх системного, без дополнительных действий, не получится.


Можно поступить по-другому: для вызова git-gui сделать алиас на вызов файла



/полный/путь/к/каталогу/репозитарияGit/git-gui/git-gui.sh



После чего при команде git gui будет запускаться модифицированный git gui, который будет писать в консоль генерируемые им команды. Удобство этого метода в том, что даже не нужно запускать перекомпиляцию.


Кстати, в том же файле существует процедура git, в которую тоже можно добавить отладочный вывод:



proc git {args} {


# Add debug output

puts stdout "Command: git $args"

set fd [eval [list git_read] $args]



Эта процедура, по задумке, должна обрабатывать все вызовы git, однако на практике некоторые команды git формируются в обход ее. Но мало ли как со временем изменятся исходники, возможно что в какой-то момент код приведут к единому стандарту формирования команды, и через эту функцию будут видны все git-команды.


И в завершении, вот пример того, какие команды генерирует git gui в процессе своей работы:



Command: /usr/bin/git --version

Command: /usr/bin/git --exec-path

Command: /usr/lib/git-core/git-rev-parse --git-dir

Command: /usr/lib/git-core/git-rev-parse --show-prefix

Command: /usr/lib/git-core/git-config --null --list

Command: /usr/lib/git-core/git-rev-parse --show-toplevel

Command: /usr/lib/git-core/git-rev-parse --is-bare-repository

Command: /usr/bin/git --html-path

Command: /usr/lib/git-core/git-rev-parse --verify HEAD

Command: /usr/lib/git-core/git-update-index -q --unmerged --ignore-missing --refresh

Command: /usr/lib/git-core/git-diff-index --cached --ignore-submodules=dirty -z e5180694881c1639b745b375bc756022299b6f82

Command: /usr/lib/git-core/git-diff-files -z

Command: /usr/lib/git-core/git-ls-files --others -z --exclude-standard

Command: /usr/lib/git-core/git-check-attr conflict-marker-size -- anyfile.txt

Command: /usr/bin/nice /usr/lib/git-core/git-diff-files --textconv -p --color -U5 -- anyfile.txt

Command: /usr/lib/git-core/git-check-attr encoding -- anyfile.txt

Command: /usr/lib/git-core/git-update-index --add --remove -z --stdin

Command: /usr/lib/git-core/git-var GIT_COMMITTER_IDENT

Command: /usr/lib/git-core/git-rev-parse --verify HEAD

Command: /usr/lib/git-core/git-rev-parse --verify HEAD

Command: /usr/lib/git-core/git-write-tree

Command: /usr/lib/git-core/git-cat-file commit e5180694881c1639b745b375bc756022299b6f82

Command: /usr/lib/git-core/git-commit-tree f2c280db3402bc9d08cf0334d20954de3ebd8b17 -p e5180694881c1639b745b375bc756022299b6f82 <.git/

GITGUI_EDITMSG

2299b6f82

Command: /usr/lib/git-core/git-update-ref -m {commit: Третье изменение файла} HEAD 340219a1031814a116857ff9b9b02e60823c7a59 e518069488

1c1639b745b375bc756022299b6f82

Command: /usr/lib/git-core/git-for-each-ref --format=%(refname) refs/heads

Command: /usr/lib/git-core/git-for-each-ref --tcl --sort=-taggerdate {--format=list %(refname) [list %(objecttype) %(objectname) [conc

at %(taggername) %(authorname)] [reformat_date [concat %(taggerdate) %(authordate)]] %(subject)] [list %(*objecttype) %(*objectname) %(*a

uthorname) [reformat_date %(*authordate)] %(*subject)]} refs/heads refs/remotes refs/tags

Command: /usr/lib/git-core/git-for-each-ref --format=%(refname) refs/heads

Command: /usr/lib/git-core/git-for-each-ref --sort=-taggerdate --format=%(refname) refs/tags

Command: /usr/lib/git-core/git-for-each-ref --tcl --sort=-taggerdate {--format=list %(refname) [list %(objecttype) %(objectname) [conc

at %(taggername) %(authorname)] [reformat_date [concat %(taggerdate) %(authordate)]] %(subject)] [list %(*objecttype) %(*objectname) %(*a

uthorname) [reformat_date %(*authordate)] %(*subject)]} refs/heads refs/remotes refs/tags

Command: /usr/lib/git-core/git-for-each-ref --format=%(refname) refs/heads

Command: /usr/lib/git-core/git-for-each-ref --sort=-taggerdate --format=%(refname) refs/tags

Command: /usr/lib/git-core/git-check-ref-format heads/new_branch

Command: /usr/lib/git-core/git-rev-parse --verify refs/heads/master^0

Command: /usr/lib/git-core/git-rev-parse --verify refs/heads/new_branch^0

00000000000000000000000

Command: /usr/lib/git-core/git-update-ref -m {branch: Created from master} refs/heads/new_branch 340219a1031814a116857ff9b9b02e60823c7

a59 0000000000000000000000000000000000000000

Command: /usr/lib/git-core/git-rev-parse --verify HEAD

Command: /usr/lib/git-core/git-symbolic-ref -m {checkout: moving from master to new_branch} HEAD refs/heads/new_branch

Command: /usr/lib/git-core/git-rev-parse --verify HEAD



Так же в этом разделе:
 
MyTetra Share v.0.59
Яндекс индекс цитирования