1. 9
  1. 3

    I think I went a bit overboard lol. The funny thing is, I use them all frequently.

    alias g="git show"
    alias gh="git show HEAD"
    alias gs="git status"
    alias gl="git log"
    alias ga="git add"
    alias gaa="git add -A"
    alias gca="git commit --amend"
    alias gcm="git commit -m"
    alias gpr="git pull --rebase origin master"
    alias gpf="git push --force"
    alias gco="git checkout"
    alias gd="git diff"
    alias gbl="git branch -v"
    alias gbd="git branch -D"
    alias gri="git rebase --interactive"
    alias grc="git rebase --continue"
    alias gra="git rebase --abort"
    alias gst="git stash"
    alias gsta="git stash apply"
    alias gx="gco -- \*; git reset HEAD \*"
    alias gcp="git cherry-pick"
    alias gcpc="git cherry-pick --continue"
    alias gcpa="git cherry-pick --abort"
    alias gpar="git remote | xargs -L1 git push --all"
    
    1. 8

      A tip: --force-with-lease is a safer choice than just --force.

      1. 1

        alias g=“git show” alias gh=“git show HEAD”

        git show without any arguments will show you HEAD by default, so you don’t necessarily need a separate gh alias. (Of course, aliases are very personal and you should do whatever you like!)

      2. 3

        These are my most interesting aliases, I think, because they define concepts rather than abbreviations.

        • Mark removed files as deleted, and new files as added. Inspired by hg addremove.

          addremove = !git add . && git ls-files --deleted | xargs git rm
          
        • All files under version control in the current revision. Inspired by hg manifest.

          manifest = ls-tree -r --full-tree --name-only HEAD
          
        • Print the repository’s root directory. Inspired by hg root.

          root = rev-parse --show-toplevel
          
        • Print URLs of remote repositories. (git config --get-regex '^remote' is a simpler command, but its output isn’t aligned.) Inspired by hg paths.

          paths = "!grep -A2 '^\\[remote' $(git root)/.git/config"
          
        • Children of the current commit. A poor man’s hg log -r 'children(.)', because it can’t use any features of git log (such as rendering templates).

          children = "!bash -c 'c=${1:-HEAD}; set -- $(git rev-list --all --not \"$c\"^@ --children | grep $(git rev-parse \"$c\") ); shift; echo $*' -"
          
        • Create copies of the file as it was in the current and merged-in revisions, and in the common ancestor. Useful for non-trivial merges, and non-trivial file types like Jupyter notebooks.

          I forget the git arcana around specifying a multi-command shell command in the config (either use "...; ...; ..." and be limited to a one-line string, or join everything with && because ; gets eaten, wasn’t it?), but here is what git versions does:

          versions = !
              git show HEAD:./$1 > $1.local
              git show MERGE_HEAD:./$1 > $1.other
              git show $(git merge-base HEAD MERGE_HEAD):./$1 > $1.common
          
        1. 4

          These are useful concepts! A few look built-in (or behind just one flag):

          Mark removed files as deleted, and new files as added. Inspired by hg addremove

          This sounds like git add -A.

          All files under version control in the current revision. Inspired by hg manifest.

          I use git ls-files for this.

          Print URLs of remote repositories.

          I use git remote -v for this, although the output might be a little different from your alias.

          1. 2

            Thanks for the tips! I immediately updated my gitconfig. Two addenda to your your very helpful post:

            • It turns out even ordinary git add detects removals nowadays. The -A flag (a.k.a. –all, a.k.a. –no-ignore-removal) is the default behaviour now.

            • git ls-files needs to be git ls-files --full-name $(git root), else it will (a) render paths relative to the working directory, and (b) only show children of the working directory.

            • git remove -v’s output is indeed a bit different, but the simpler command is worth it.

        2. 2

          Mine, specifically calling out the ones I use constantly all day:

          pupr = !git push -u origin HEAD && hub pull-request -o
          cleanup = !git branch --merged | grep  -v '\\*\\|master\\|develop' | xargs -n 1 git branch -d
          lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
          
          1. 1

            I have a script git-wipu that does a git commit --ammend without changing the commit message and then force pushes it. I use it all the time when I’m on my own work-in-progress branch and I want to “accumulate” a single commit in small chunks. It’s like my git equivalent of instinctively saving a file every ten seconds.

            I also use the following aliases:

            alias shelve='git stash'
            alias unshelve='git stash apply'
            

            because I can never remember git stash on the few occasions that I need it.

            1. 2

              I did something similar with lots of sq! {SHA} commits until I found out about git commit --fixup which let’s you do similar, and then git rebase -i --autosquash it afterwards, which is a bit safer with repos others are working on - there’s some more detail on https://www.jvt.me/posts/2019/01/10/git-commit-fixup/ if that helps!

              (Originally posted at https://www.jvt.me/mf2/2020/02/s9zg3/ and hand syndicated)

              1. 2

                I didn’t even know that the --fixup & --autosquash flags existed.

                Thanks for the link; I’ll definitely look at incorporating these into my workflow!

                :-)

            2. 1

              Here’s most of mine (note this is from git alias these aren’t shell aliases, i use git aliases in my git aliases, i also removed the work related ones >.<) feel free to ask about some of these they’re a bit esoteric.

              b = branch
              ba = branch --all
              bcs = log --pretty=%H --first-parent --no-merges
              begin = !git init && git commit --allow-empty -m 'Initial empty commit'
              # get the branch name
              bn = rev-parse --abbrev-ref HEAD
              # branch with a new worktree uses the nwt alias later
              bwt = !git branch $1 ${2:-HEAD} && git nwt $1 #
              # what files are getting changed in a repo, really stupid
              churn = !git log --all -M -C --name-only --format='format:' $@ | sort | grep -v '^$' | uniq -c | sort -r | awk 'BEGIN {print count,file} {print $1 , $2}' | grep -Ev '^\s+$'
              ci = commit
              cia = commit --all
              # cherry-mark diff, useful for finding out if a commit is present in between branches
              cmd = log --no-merges --left-right --graph --cherry-mark --oneline
              co = checkout
              cp = log --no-merges --cherry --graph --oneline
              # similar to ^ but should report if a cherry pick was done
              cpd = log --no-merges --left-right --graph --cherry-pick --oneline
              # default remote name, aka origin, probably a better way 
              defremote = !git branch -rvv | grep -E 'HEAD' | awk '{print $1}' | sed -e 's|/HEAD||g'
              ds = diff --stat
              # abandon all hope!
              effit = reset --hard
              fa = fetch --all
              # find a common merge point between a commit and branch
              find-merge = !sh -c commit=$0 && branch=${1:-HEAD} && (git rev-list $commit..$branch --ancestry-path | cat -n; git rev-list $commit..$branch --first-parent | cat -n) | sort -k2 | uniq -f1 -d | sort -n | tail -1 | cut -f2
              # try to fix HEAD to point to origin/master or whatever remote/branch you want
              fixhead = !sh -c rem=${0:-origin} && branch=${1:-master} && git symbolic-ref refs/remotes/$rem/HEAD refs/remotes/$rem/${branch}
              fixup = commit --fixup
              # force push branch up
              fpbr = !git push --set-upstream --force $(git defremote) $(git bn)
              # used for worktree aliases, gets the GIT_DIR of the primary place also works in worktrees
              gr = !git rev-parse --absolute-git-dir | sed -e 's|/[.]git.*||' #
              hist = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative
              # safety first! don't allow yourself to push to origin on this checkout
              nopush = remote set-url --push origin no_push
              # new work tree, uses the gr alias to get the directory, then create a new work tree with DIR@branch 
              nwt = !git worktree add $(git gr)@$1 $1 #
              pbr = !git push --set-upstream $(git defremote) $(git bn)
              ra = rebase --abort
              ri = rebase --interactive --autosquash
              s = status --short --branch --untracked-files=no
              sc = !git clone --recursive $1
              short = rev-parse --short
              # use find-merge to show the common merge commit
              show-merge = !sh -c merge=$(git find-merge $0 $1) && [ -n "$merge" ] && git show $merge
              slog = log --oneline --decorate
              squash = commit --squash
              st = status --short --branch
              # submodules are annoying af to keep up to date
              sup = !git pull --rebase && git submodule update --init --recursive
              tlog = log --graph --color=always --abbrev-commit --date=relative --pretty=oneline
              trim = !git reflog expire --expire=now --all && git gc --prune=now
              # get the full history of a git --depth checkout/clone
              unshallow = pull --unshallow
              unstage = reset HEAD
              up = !git pull --rebase && git push
              wd = diff --color-words
              wsd = diff --color-words --ignore-space-at-eol --ignore-space-change --ignore-all-space
              wta = worktree add
              wtl = worktree list
              wtp = worktree prune
              # supposed to be worktree root, not sure its better than the other alias
              wtr = !git worktree list --porcelain | grep -B2 "branch refs/heads/$1" | head -n1 | sed -e 's|worktree ||' #
              
              1. 1

                git effit is fun ;)

              2. 1

                Thanks for info about [pretty] section.

                Mine:

                [alias]
                	# Add interactive
                	ai = add -I
                	b = branch
                	# Change last commit (mostly used for typos in commit messages)
                	ca = commit --amend
                	ci = commit
                	co = checkout
                	cob = checkout -b
                	lg = log --color --graph --abbrev-commit --pretty=simple-oneline
                	# Recommiting for quick fixes
                	rci = commit --amend --reuse-message HEAD
                	squash = rebase -i @{u}
                	st = status -sb
                	# TODOs and FIXMEs
                	todo = grep -Ee '\\bTODO:?\\b'
                	fixme = grep -Ee '\\bFIX(ME)?:?\\b'
                	com = checkout master
                	# Ignore files without adding them to .gitignore (useful in some temporary files created during debugging
                	skip = update-index --skip-worktree
                	unskip = update-index --no-skip-worktree
                	publish = push -u hauleth
                	# Check for merged branches and remove them
                	cleanup = "!git branch --format=\"%(if:notequals=*)%(HEAD)%(then)%(if:notequals=${1:-master})%(refname:lstrip=2)%(then)%(refname:lstrip=2)%(end)%(end)\" --merged master | xargs -rpxL1 git branch -d"
                
                [pretty]
                	simple-oneline = "%C(yellow)%h%C(auto)%d %s <%C(green)%aN%C(reset)> (%C(blue)%ar%C(reset))"
                
                1. 1

                  A few from my config:

                  amend = commit --amend
                  branch-recency = for-each-ref --sort='-authordate:iso8601' --format='%(authordate:relative)%09%(refname:short)' refs/heads
                  contributors = shortlog --summary --numbered
                  credit = "!f() { git commit --amend --author \"$1 <$2>\" -C HEAD; }; f"
                  delete-merged  = "!git branch --merged | grep -v '\\*' | xargs -n 1 git branch -d; git remote -v update -p"
                  undo = reset --soft HEAD^
                  unreleased = "!f() { git fetch --tags && git diff $(git tag | tail -n 1); }; f"
                  
                  1. 1
                    ❯ git config -l | grep alias
                    alias.staged=diff --staged
                    alias.glog=log --graph --decorate --color --oneline
                    alias.ulog=log --graph --decorate --color --oneline --boundary HEAD@{u}..
                    alias.olog=log --graph --decorate --color --oneline --boundary origin/master..
                    alias.find=!git ls-files | grep
                    alias.branches=!git --no-pager log --branches --no-walk --date-order --reverse --format='%C(auto)%h%d %Cred%cr%Creset %s'