From b7f48e8b024499d7bdbcedff08d3a13ce9b67216 Mon Sep 17 00:00:00 2001 From: eneller Date: Mon, 4 Mar 2024 21:25:38 +0100 Subject: [PATCH] scripts: git-ignore, git-root needs to be improved --- .local/bin/git-ignore | 122 ++++++++++++++++++++++++++++++++++++++++++ .local/bin/git-root | 29 ++++++++++ 2 files changed, 151 insertions(+) create mode 100755 .local/bin/git-ignore create mode 100755 .local/bin/git-root diff --git a/.local/bin/git-ignore b/.local/bin/git-ignore new file mode 100755 index 0000000..e380a2e --- /dev/null +++ b/.local/bin/git-ignore @@ -0,0 +1,122 @@ +#!/usr/bin/env bash + +GIT_DIR=$(git rev-parse --git-dir 2>/dev/null) + +function show_contents { + local file="${2/#~/$HOME}" + if [ -f "$file" ]; then + echo "$1 gitignore: $2" && cat "$file" + else + echo "There is no $1 .gitignore yet" + fi +} + +function cd_to_git_root { + local error_level="$1" + + if ! git rev-parse --git-dir &>/dev/null; then + if [ "$error_level" = '--warn' ]; then + echo "Warning: Not currently in a Git repository" >&2 + elif [ "$error_level" = '--error' ]; then + echo "Error: Not currently in a Git repository" >&2 + exit 1 + fi + fi + + local result= + if result=$(git rev-parse --show-toplevel 2>/dev/null); then + cd "$result" || exit + fi +} + +function global_ignore() { + if ! git config --global core.excludesFile 2>/dev/null; then + if [ -f "$HOME/.gitignore" ]; then + echo "$HOME/.gitignore" + else + echo "${XDG_CONFIG_HOME:-$HOME/.config}/git/ignore" + fi + fi +} + +function show_global { + show_contents Global "$(global_ignore)" +} + +function add_global { + local global_gitignore + global_gitignore="$(global_ignore)" + if [ -z "$global_gitignore" ]; then + echo "Can't find global .gitignore." + echo "" + echo "Use 'git config --global --add core.excludesfile ~/.gitignore-global' to set the path to your global gitignore file to '~/.gitignore-global'." + echo "" + else + add_patterns "$global_gitignore" "$@" + fi +} + +function show_local { + cd_to_git_root --warn + show_contents Local .gitignore +} + +function add_local { + cd_to_git_root --warn + add_patterns .gitignore "$@" +} + +function show_private { + cd_to_git_root --error + show_contents Private "${GIT_DIR}/info/exclude" +} + +function add_private { + cd_to_git_root --error + test -d "${GIT_DIR}/info" || mkdir -p "${GIT_DIR}/info" + add_patterns "${GIT_DIR}/info/exclude" "$@" +} + +function add_patterns { + echo "Adding pattern(s) to: $1" + local file="${1/#~/$HOME}" + dir_name=$(dirname "$file") + if [ ! -d "$dir_name" ]; then + mkdir -p "$dir_name" + fi + if [ -s "$file" ]; then + # If the content of $file doesn't end with a newline, add one + test "$(tail -c 1 "$file")" != "" && echo "" >> "$file" + fi + for pattern in "${@:2}"; do + echo "... adding '$pattern'" + (test -f "$file" && test "$pattern" && grep -q -F -x -- "$pattern" "$file") || echo "$pattern" >> "$file" + done +} + +if test $# -eq 0; then + show_global + echo "---------------------------------" + show_local + echo "---------------------------------" + show_private +else + case "$1" in + -l|--local) + test $# -gt 1 && add_local "${@:2}" && echo + show_local + ;; + -g|--global) + test $# -gt 1 && add_global "${@:2}" && echo + show_global + ;; + -p|--private) + test $# -gt 1 && add_private "${@:2}" && echo + show_private + ;; + *) + add_local "$@" + ;; + esac +fi + diff --git a/.local/bin/git-root b/.local/bin/git-root new file mode 100755 index 0000000..a8d538e --- /dev/null +++ b/.local/bin/git-root @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +git_root() { + git rev-parse --show-toplevel +} + +# get the relative path of current path according to root of repo +git_root_relative() { + rel=$(git rev-parse --show-prefix) + if [ -z "$rel" ]; then + # git rev-parse --show-prefix will output empty string when we are in the root dir + echo "." + else + echo "$rel" + fi +} + +if test $# -eq 0; then + git_root +else + case "$1" in + -r|--relative) + git_root_relative + ;; + *) + git_root + ;; + esac +fi \ No newline at end of file