演示

演示

这可能是一个奇怪的问题,但我想覆盖lsgit 目录中的行为。

我想从最后一次提交中提取一些差异统计信息,并将其附加到 的底部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,最简单的方法是按如下方式进行:

  1. 创建目录$HOME/bin
  2. 添加$HOME/bin到您的PATH。为此,请~/.bashrc在您最喜欢的文本编辑器中打开文件,然后将以下行添加到末尾:

    export PATH=$HOME/bin:$PATH
    

    请注意,前置 $HOME/bin到你的PATH,以便其中的可执行文件将优先于你的同名的其他可执行文件PATH(例如,在你的情况下,ls命令)

  3. 创建一个文件$HOME/bin/ls,其中包含我将在下面发布的内容。
  4. 使其可执行:chmod 755 $HOME/bin/ls
  5. 您可能需要重新启动终端。

其次,你的 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

相关内容