首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >扩展现有的git命令

扩展现有的git命令
EN

Stack Overflow用户
提问于 2018-05-18 23:24:34
回答 3查看 257关注 0票数 0

我可以通过将脚本/程序git-foobar放在我的$PATH上向git添加一个新命令,然后我可以作为git foobar调用它,这是有文档记录的。

但是,如果我想要扩展现有的git命令呢?例如,git worktree命令有动词add、list、lock等。我有一种非常具体的方式来组织我保存的位置以及如何命名工作树。我已经写了一个脚本‘`git worktree’,它有一个"main“函数,如下所示:

代码语言:javascript
复制
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命令?

EN

回答 3

Stack Overflow用户

发布于 2018-05-19 00:14:43

您需要遵循hub使用的模式,其中有一个在shell中别名为git的替代脚本。该替代脚本将拦截相关的内置命令并执行您的自定义覆盖脚本。

代码语言:javascript
复制
#!/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即可,它应该可以工作

票数 2
EN

Stack Overflow用户

发布于 2018-05-19 01:32:05

我得出了与Brian Philips的答案相同的结论-您需要自己进行调度来扩展现有的git命令。与Brian不同的是,我坚持将调度程序命名为“git”,从而使任务变得更加困难。:-)

.profile中,查找并记录真实的git位置

代码语言:javascript
复制
## PERSONALBIN is my local bin dir
tempath=$(echo $PATH | sed "s|;$PERSONALBIN:|;|")
REALGIT=$(PATH=$tempath; hash -r ; which git)
export REALGIT

作为另一种选择,如果您没有在环境变量中跟踪您的个人git,并且您确定就在您的git in PATH后面是系统git,您可以将上面的REALGIT设置替换为:

代码语言:javascript
复制
REALGIT=$(hash -r; which -a git | head -2 | tail -1 )

$PERSONALBIN/git中,调用我的脚本或真正的git:

代码语言:javascript
复制
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

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2018-05-18 23:48:03

您将无法覆盖内置命令。

根据github.com/git/git/blob/master/git.c#L606上的代码,git将使用编译后的实现调用内置实现来匹配命令,而不是使用shell来覆盖。

如果它找不到您指定的命令(无论是作为内置命令还是作为外部命令),它将尝试查找声明的别名,然后尝试运行该别名。

因此,您唯一的选择是使用一个自定义命令,该命令的名称没有用作内置命令。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50414621

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档