这可能是一个奇怪的问题,但我想覆盖ls
git 目录中的行为。
我想从最后一次提交中提取一些差异统计信息,并将其附加到 的底部ls
。当在根git项目,我想制作一个这样的特定提示:
app/
test/
.gitignore
test.py
run.py
README.md
+ 11 lines
- 3 lines
Last commit: "add a new test for deployment" (Oct 14, 2014)
当比根更深时,我想创建一个像这样的提示(比如说我 cd 到test/
然后使用该ls
命令):
test/
├── __init__.py
├── test_deploy.py
└── test_add_user.py (+3 lines since last commit)
加分点:用绿色/红色表示加/减线,并在 git 信息上用统一的标签表示。
如何实现这一点?
答案1
首先,为了创建自定义的ls
,最简单的方法是按如下方式进行:
- 创建目录
$HOME/bin
添加
$HOME/bin
到您的PATH
。为此,请~/.bashrc
在您最喜欢的文本编辑器中打开文件,然后将以下行添加到末尾:export PATH=$HOME/bin:$PATH
请注意,前置
$HOME/bin
到你的PATH
,以便其中的可执行文件将优先于你的同名的其他可执行文件PATH
(例如,在你的情况下,ls
命令)- 创建一个文件
$HOME/bin/ls
,其中包含我将在下面发布的内容。 - 使其可执行:
chmod 755 $HOME/bin/ls
。 - 您可能需要重新启动终端。
其次,你的 new$HOME/bin/ls
应该像这样:它检查当前目录是否是 git 存储库,并且
- 如果没有,它就简单地委托给正常的
/bin/ls
可执行文件。 - 如果是,它会创建您要求的输出,具体取决于当前文件夹是否是 git 存储库的根目录或者是否更深。
我很快就为你编写了一个这样的脚本。它绝不是完美的,但它应该非常接近你想要的,你可以轻松地从那里开始。:-)
#!/bin/bash
# determine if we're in a git repo, what the root dir is, and assign it to GIT_ROOT, all in one swoop
GIT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
# if not in git repo, relay to normal ls
if (( $? )); then
/bin/ls "$@"
# if in git repo, are we in root dir?
elif [ "x$GIT_ROOT" = "x$PWD" ]; then
# first, normal ls with 1 file per line, also pass along other parameters
/bin/ls -1 "$@"
echo
# a few git stats
GIT_DIFF=$(git diff --stat | tail -1)
# any insertions?
echo $GIT_DIFF | grep insertion >/dev/null
if (( ! $? )); then
# bonus points: color in green
echo -e "\e[0;32m+ $(echo $GIT_DIFF | sed 's/.*, \([[:digit:]]\+\) insertion.*/\1/;') lines\e[0m"
fi
# any deletions?
echo $GIT_DIFF | grep deletion >/dev/null
if (( ! $? )); then
# bonus points: color in red
echo -e "\e[0;31m- $(echo $GIT_DIFF | sed 's/.*, \([[:digit:]]\+\) deletion.*/\1/;') lines\e[0m"
fi
# Finally, display last commit message and date
git log -1 --pretty='Last commit: "%s" (%ad)'
# otherwise, we're depper in a git repo
else
echo -e "\e[1;34m${PWD##*/}\e[0m"
IFS=$'\n'
for file in $(tree -C | tail -n +2 | head -n -2); do
filename=$(echo $file | cut -d" " -f 2-)
echo -n $file
# a few git stats
GIT_DIFF=$(git diff --stat "$(echo $filename | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g")")
# any insertions?
echo $GIT_DIFF | grep insertion >/dev/null
if (( ! $? )); then
# bonus points: color in green
echo -ne " \e[0;32m(+ $(echo $GIT_DIFF | sed 's/.*, \([[:digit:]]\+\) insertion.*/\1/;') lines since last commit)\e[0m"
fi
# any deletions?
echo $GIT_DIFF | grep deletion >/dev/null
if (( ! $? )); then
# bonus points: color in red
echo -ne " \e[0;31m(- $(echo $GIT_DIFF | sed 's/.*, \([[:digit:]]\+\) deletion.*/\1/;') lines since last commit)\e[0m"
fi
echo
done
fi
演示
注意:输出颜色很好看,尽管这里显然不会显示出来。
$ ls
app
README.md
run.py
test
test.py
+ 11 lines
- 3 lines
Last commit: "add a new test for deployment" (Fri Nov 21 04:20:37 2014 +0100)
$ cd test/
$ ls
test
├── bla
├── __init__.py
├── test_add_user.py (+ 3 lines since last commit)
└── test_deploy.py