#!/bin/bash # GIT FUNCTIONS # git checkout with tab completion # bash override for zsh gco alias if [ -n "$BASH_VERSION" ] && [ -f ~/.config/aliases/.git_bash_autocomplete ]; then . ~/.config/aliases/.git_bash_autocomplete fi # git create stast with message git_stash_msg() { if [ -z "$1" ]; then e_warn "Stash changes with message! Don't be lazy..." else local msg="$*" git stash -m "$msg" e_succ "Succesfully stashed changes as '$msg' on branch '$(git branch --show-current)'." fi } # git apply stash by number git_apply_stash() { if [ $# -eq 0 ]; then e_warn "Please specify stash number!" return 1 elif [ $# -gt 1 ]; then e_warn "Please specify only one stash number!" return 1 else git stash apply stash@"{$1}" fi } # git echo stasth diff by number # useful combined with '| xc' git_stash_patch() { if [ $# -eq 0 ]; then e_warn "Please specify a stash number!" return 1 elif [ $# -gt 1 ]; then e_warn "Please specify only one stash number!" return 1 else git stash show -p stash@"{$1}" fi } # drop stash by number with confirmation # I accidentally dropped stashes, because I mix up gsp and gsd git_stash_drop() { if [ $# -eq 0 ]; then e_warn "Please specify a stash number!" return 1 elif [ $# -gt 1 ]; then e_warn "Please specify only one stash number!" return 1 else printf "Are you sure you want to drop stash #$1? (Y/N): " read -r confirm if [[ "$confirm" =~ ^[yY]$ ]]; then git stash drop stash@"{$1}" e_info "Stash #$1 dropped." else e_warn "Aborted. Stash #$1 not dropped." fi return 0 fi } # git diff with optional filename from git diff --names-only | nl git_diff_numbered() { local files file files=() while IFS= read -r line; do files+=("$line") done < <(git diff --name-only) if [ $# -eq 0 ]; then printf "%s\n" "${files[@]}" | nl elif [ $# -eq 1 ] && [[ $1 =~ ^[0-9]+$ ]]; then if [ -n "$BASH_VERSION" ]; then file="${files[$1 - 1]}" else file="${files[$1]}" fi [ -n "$file" ] && git diff "$file" else e_err "Invalid argument! Provide number from the output of 'gdn'." fi } # git restore file based on the number from git diff --names-only | nl git_restore_by_number() { local files file files=() while IFS= read -r line; do files+=("$line") done < <(git diff --name-only) if [ $# -eq 0 ]; then e_err "Missing argument! Provide number from the output of 'gdn'." elif [ $# -eq 1 ] && [[ $1 =~ ^[0-9]+$ ]]; then if [ -n "$BASH_VERSION" ]; then file="${files[$1 - 1]}" else file="${files[$1]}" fi [ -n "$file" ] && git restore "$file" else e_err "Invalid argument! Provide number from the output of 'gdn'." fi } # git add untracked files, commit and push git_commit_push() { if [ -z "$1" ]; then e_err "No commit message provided!" return 1 else local message="$*" git add -u git commit -m "$message" git push e_succ -e "\nCommit '$message' succesfully pushed to branch: '$(git branch --show-current)'." fi } # git list stashes git_stash_list() { printf "%s\n" "$(git stash list)" } ### Git aliases # git status fake_alias gst if [ -n "$BASH_VERSION" ]; then alias gst='git status' fi # git fetch all fake_alias gfa if [ -n "$BASH_VERSION" ]; then alias gfa='git fetch --all --prune' fi # git diff fake_alias gd if [ -n "$BASH_VERSION" ]; then alias gd='git diff' fi # git diff classic with less pager alias gdc="git -c core.pager='less' diff" # git diff numbered alias gdn=git_diff_numbered # (with filenum works only in repo root) next_line # git commit and push with message alias gcpm=git_commit_push # git checkout with tab completion fake_alias gco # git submodule update fake_alias gsu if [ -n "$BASH_VERSION" ]; then alias gsu='git submodule update' fi # git stash with message alias gstm=git_stash_msg # git stash list alias gstl=git_stash_list # git stash patch <#> alias gstp=git_stash_patch # git stash apply <#> alias gsta=git_apply_stash # gti stash drop <#> alias gstd=git_stash_drop # git restore alias grs='git restore' # git restore by number from gdn alias grsn=git_restore_by_number # run pre-commit on changed files only alias pc='pre-commit run --files $(git diff --name-only)'