Расширение СУЩЕСТВУЮЩЕЙ команды git - PullRequest
0 голосов
/ 18 мая 2018

Хорошо задокументировано, что я могу добавить новую команду в git, поместив скрипт / программу git-foobar в свою переменную $ PATH, которую затем можно вызвать как git foobar.

Но что если яхотите расширить существующую команду git?Например, команда git worktree имеет глаголы add, list, lock и т. Д. У меня есть очень специфический способ организации, где я храню и как я называю рабочие деревья.Я написал скрипт `git-worktree 'с функцией main, которая выглядит следующим образом:

declare action=$1
shift;

if [[ "$action" =~ -h ]]
then
    script-usage
    return  0
fi

case $action in
    create | delete )
        if [[ "$1" =~ -h ]]
        then
            script-usage
            return  0
        else
            "git-worktree-${action}" "$@"
            return $?
        fi
        ;;
    *)
        "${git_bin}/git-worktree" "$@"
        return $?
        ;;
esac

Если я набираю' create 'или' delete ', я вызываю функции, определенные в другом месте моего скрипта.Для всего остального я просто передаю настоящую команду git worktree.

За исключением того, что она не совсем работает.Ввод git-worktree выполняет мой сценарий.Ввод git worktree НЕ запускает мой скрипт.

Есть ли что-то, чего мне не хватает, или я не могу расширить существующие команды git таким же образом, каким я могу добавлять новые команды?

Ответы [ 3 ]

0 голосов
/ 18 мая 2018

Вы должны будете следовать шаблону, используемому hub , где у вас есть альтернативный сценарий, который вы называете в своей оболочке как git.Этот альтернативный скрипт будет перехватывать соответствующие встроенные команды и исполнять ваш пользовательский скрипт переопределения.

#!/usr/bin/env bash

# my-git.sh

declare action=$1
shift;

case $action in
    worktree )
        exec git-worktree "$@"
        ;;
    *)
        exec git "$action" "$@"
    ;;
esac

Предполагая, что вышеупомянутый скрипт находится в вашем пути где-то как my-git.sh, вы можете просто alias git=my-git.sh, и он долженработа

0 голосов
/ 18 мая 2018

Я пришел к тому же выводу, что и ответ Брайана Филипса - вам нужно выполнить собственную диспетчеризацию для расширения существующих команд git.В отличие от Брайана, я усложнил задачу, настаивая на том, чтобы диспетчерская программа все еще называлась «git».: -)

В .profile найдите и запишите реальные места git

## PERSONALBIN is my local bin dir
tempath=$(echo $PATH | sed "s|;$PERSONALBIN:|;|")
REALGIT=$(PATH=$tempath; hash -r ; which git)
export REALGIT

В качестве альтернативы, если вы не отслеживаете свой личный мусорный ящик в envvar, и выуверены, что за git в PATH находится система git, вы можете заменить приведенную выше настройку REALGIT на:

REALGIT=$(hash -r; which -a git | head -2 | tail -1 )

В $PERSONALBIN/git вызовите мой скрипт или реальный git:

declare command=$1; shift
declare extend_script="git-${command}"
if which "$extend_script" 1>/dev/null 2>/dev/null
then
  echo "--- Dispatched to a local git- script"
  "$extend_script" "$@"
else
  echo "--- Dispatched to git"
  "${REALGIT} "${command}" "$@"
fi
exit $?

Если бы это была новая команда git foobar, я мог бы написать $PERSONALBIN/git-foobar, чтобы просто делать то, что я хочу.Однако, поскольку я расширяю существующую команду, я должен отправить все, что моя команда не обрабатывает.Итак, в $PERSONALBIN/git-worktree:

declare action=$1
shift;

if [[ "$action" =~ -h ]]
then
    script-usage
    exit 0
fi

action_func_name="git-worktree-${action}"
if declare -F "$action_func_name" >/dev/null
then
    "$action_func_name" "$@"
else
    ## Dispatch to real git worktree
    "${REALGIT} worktree "$action" "$@"
fi
exit $?

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

0 голосов
/ 18 мая 2018

Вы не сможете переопределить встроенные команды.

В соответствии с кодом на github.com/git/git/blob/master/git.c#L606, git вызоветвстроенные реализации, использующие скомпилированные реализации для сопоставления команд, а не оболочки для переопределения.

Если он не может найти указанную вами команду (как встроенную, так и внешнюю), он попытаетсячтобы найти объявленный псевдоним, а затем попробуйте запустить THAT.

Таким образом, вы можете использовать пользовательскую команду с именем, НЕ используемым в качестве встроенного.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...