Skip to content

Instantly share code, notes, and snippets.

@zamber
Created March 29, 2018 09:25
Show Gist options
  • Select an option

  • Save zamber/0e00a0f3f1d6c086f8201a50c95c8b16 to your computer and use it in GitHub Desktop.

Select an option

Save zamber/0e00a0f3f1d6c086f8201a50c95c8b16 to your computer and use it in GitHub Desktop.

Revisions

  1. zamber created this gist Mar 29, 2018.
    608 changes: 608 additions & 0 deletions .gitconfig
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,608 @@
    [user]
    name = <name>
    email = <user>@<domain>
    [merge]
    tool = kdiff3
    [mergetool "kdiff3"]
    path = C:/Program Files/KDiff3/kdiff3.exe
    trustExitCode = false
    [diff]
    guitool = kdiff3
    [difftool "kdiff3"]
    path = C:/Program Files/KDiff3/kdiff3.exe
    trustExitCode = false
    [help]
    autocorrect = 1
    [alias]

    # Muscle memory aliases

    mt = mergetool

    # ! Rest taken from https://github.com/gitalias/gitalias/blob/master/gitalias.txt

    ##
    # One letter alias for our most frequent commands.
    #
    # Guidelines: these aliases do not use options, because we want
    # these aliases to be easy to compose and use in many ways.
    ##

    a = add
    b = branch
    c = commit
    d = diff
    f = fetch
    g = grep
    l = log
    m = merge
    o = checkout
    p = pull
    r = remote
    s = status
    w = whatchanged

    ##
    # Short aliases for our frequent commands.
    #
    # Guidelines:
    #
    # * Generally speaking, the alias should be in the same
    # order as the command name followed by its options.
    #
    # * Right: fb = foo --bar
    # * Wrong: bf = foo --bar
    ##

    ### add ###

    # add all
    aa = add --all

    # add by patch - looks at each change, and asks if we want to put it in the repo.
    ap = add --patch

    # add just the files that are updated.
    au = add --update

    ### branch ###

    # branch - edit the description
    be = branch --edit-description

    # branch and only list branches whose tips are reachable from the specified commit (HEAD if not specified).
    bm = branch --merged

    # branch and only list branches whose tips are not reachable from the specified commit (HEAD if not specified).
    bnm = branch --no-merged

    ### commit ###

    # commit - amend the tip of the current branch rather than creating a new commit.
    ca = commit --amend

    # commit - amend the tip of the current branch, and do not edit the message.
    can = commit --amend --no-edit

    # commit - amend the tip of the current branch, and edit the message.
    cam = commit --amend --message

    # commit interactive
    ci = commit --interactive

    # commit with a message
    cm = commit --message

    ### checkout ###

    # checkout - update the working tree to match a branch or paths. [same as "o" for "out"]
    co = checkout

    ### cherry-pick ###

    # cherry-pick - apply the changes introduced by some existing commits; useful for moving small chunks of code between branches.
    cp = cherry-pick

    # cherry-pick without making a commit, and when when recording the commit, append a line that says "(cherry picked from commit ...)"
    cp-nx = cherry-pick --no-commit -x

    ### diff ###

    # diff - show changes not yet staged
    dc = diff --cached

    # diff - changes about to be commited
    ds = diff --staged

    # diff - show changes but by word, not line
    dw = diff --word-diff

    ### clean ###

    # clean everything to be pristine
    cleanest = clean -ffdx

    ### grep ###

    # grep with grouping of the output lines
    gg = grep --break --heading --line-number

    ### log ###

    # log with a text-based graphical representation of the commit history.
    lg = log --graph

    # log with one line per item.
    lo = log --oneline

    # log with patch generation.
    lp = log --patch

    # log with items appearing in topological order, i.e. descendant commits are shown before their parents.
    lt = log --topo-order

    # log key - our favorite way to show our key performance indicators, i.e. our most useful summary.
    lk = log --graph --topo-order --abbrev-commit --date=short --decorate --all --boundary --pretty=format:'%Cgreen%ad %Cred%h%Creset -%C(yellow)%d%Creset %s %Cblue[%cn]%Creset %Cblue%G?%Creset'

    # log latest - show the 10 most recent lines using `lk`
    ll = log -n 10 --graph --topo-order --abbrev-commit --date=short --decorate --all --boundary --pretty=format:'%Cgreen%ad'

    ## ls-files ##

    # ls-files - show information about files in the index and the working tree; like Unix "ls" command.
    ls = ls-files

    # ls-ignored - list files that git has ignored.
    ls-ignored = ls-files --others --i --exclude-standard

    ### merge ###

    # merge but without autocommit, and with a commit even if the merge resolved as a fast-forward.
    me = merge --no-commit --no-ff

    ### pull ###

    # pull if a merge can be resolved as a fast-forward, otherwise fail.
    pf = pull --ff-only

    # pull with rebase - to provide a cleaner, linear, bisectable history.
    #
    # To integrate changes between branches, you can merge or rebase.
    #
    # When we use "git pull", git does a fetch then a merge.
    # If we've made changes locally and someone else has pushed changes
    # to our git host then git will automatically merge these together
    # and create a merge commit that looks like this in the history:
    #
    # 12345678 - Merge branch 'foo' of bar into master
    #
    # When we use "git pull --rebase", git does a fetch then a rebase.
    # A rebase resets the HEAD of your local branch to be the same as
    # the remote HEAD, then replays your local commits back into repo.
    # This means you don't get any noisy merge messages in your history.
    # This gives us a linear history, and also helps with git bisect.
    #
    # To automatically do "pull --rebase" for any branch based on master:
    #
    # git config branch.master.rebase true
    #
    # To automatically do "pull --rebase" for all branches:
    #
    # git config --global branch.autosetuprebase always
    #
    pr = pull --rebase

    ### rebase ###

    # rebase - forward-port local commits to the updated upstream head.
    rb = rebase

    # rebase - continue the rebasing process after resolving a conflict manually and updating the index with the resolution.
    rbc = rebase --continue

    # rebase - restart the rebasing process by skipping the current patch.
    rbs = rebase --skip

    # rbi - rebase interactive on our unpushed commits.
    #
    # Before we push our local changes, we may want to do some cleanup,
    # to improve our commit messages or squash related commits together.
    #
    # Let's say I've pushed two commits that are related to a new feature and
    # I have another where I made a spelling mistake in the commit message.
    # When I run "git rbi" I get dropped into my editor with this:
    #
    # pick 7f06d36 foo
    # pick ad544d0 goo
    # pick de3083a hoo
    #
    # Let's say I want to squash the "foo" and "goo" commits together,
    # and also change "hoo" to say "whatever". To do these, I change "pick"
    # to say "s" for squash; this tells git to squash the two together;
    # I also edit "hoo". I make the file look like:
    #
    # pick 7f06d36 foo
    # s ad544d0 goo
    # r de3083a whatever
    # This gives me two new commit messages to edit, which I update.
    # Now when I push the remote repo host receives two commits
    #
    # 3400455 - foo
    # 5dae0a0 - whatever
    #
    rbi = rebase --interactive @{upstream}

    # See https://blog.filippo.io/git-fixup-amending-an-older-commit/
    # This is a slightly modified version
    fixup = "!f() { TARGET=$(git rev-parse \"$1\"); git commit --fixup=$TARGET && GIT_EDITOR=true git rebase --interactive --autosquash $TARGET~; }; f"

    ### reflog ###

    # reflog - reference log that manages when tips of branches are updated.
    rl = reflog

    ### remote ###

    # remote - manage set of tracked repositories [same as "r"].
    rr = remote

    # remote show - gives some information about the remote <name>.
    rrs = remote show

    # remote update - fetch updates for a named set of remotes in the repository as defined by remotes.
    rru = remote update

    # remote prune - deletes all stale remote-tracking branches under <name>.
    rrp = remote prune

    incoming = !git remote update --prune; git log ..@{upstream}
    outgoing = log @{upstream}..

    # Push to all remotes
    push-to-all-remotes = !git remote | xargs -I% -n1 git push %

    ### revert ###

    # revert - undo the changes from some existing commits
    rv = revert

    # revert without autocommit; useful when you're reverting more than one commits' effect to your index in a row.
    rvnc = revert --no-commit

    ### show-branch ###

    # show-branch - print a list of branches and their commits.
    sb = show-branch

    ### submodule ###

    # submodule - enables foreign repositories to be embedded within a dedicated subdirectory of the source tree.
    sm = submodule

    # submodule update
    smu = submodule update

    # submodule update with initialize
    smui = submodule update --init

    # submodule update with initialize and recursive; this is useful to bring a submodule fully up to date.
    smuir = submodule update --init --recursive

    ### status ###

    # status with short format instead of full details
    ss = status --short

    # status with short format and showing branch and tracking info.
    ssb = status --short --branch

    ### ALIAS MANAGEMENT ###

    # Show our defined alias list
    aliases = "!git config --get-regexp '^alias\\.' | cut -c 7- | sed 's/ / = /'"

    add-alias = "!f() { [ $# = 3 ] && git config $1 alias.\"$2\" \"$3\" && return 0 || echo \"Usage: git add-(local|global)-alias <new alias> <original command>\" >&2 && return 1; }; f"
    add-global-alias = "!git add-alias --global"
    add-local-alias = "!git add-alias --local"

    # Rename an alias
    rename-alias = "!f() { [ $# = 3 ] && [ $2 != $3 ] && [ ! -z \"$(git config $1 --get alias.$2)\" ] && [ -z \"$(git config $1 --get alias.$3)\" ] && git config $1 alias.$3 \"$(git config $1 --get alias.$2)\" && git config $1 --unset alias.$2 && return 0 || echo \"Usage: git rename-(local|global)-alias <alias existing name> <new alias name>\nThe alias you are going to rename must exist and new name must not exist.\" >&2 && return 1; };f"
    rename-global-alias = "!git rename-alias --global"
    rename-local-alias = "!git rename-alias --local"

    # Last tag in the current branch
    lasttag = describe --tags --abbrev=0

    # Latest annotated tag in all branches
    lasttagged = !git describe --tags `git rev-list --tags --max-count=1`

    # Show our tags
    tags = tag -n1 --list

    # Diffs
    diff-all = !"for name in $(git diff --name-only $1); do git difftool $1 $name & done"
    diff-changes = diff --name-status -r
    diff-stat = diff --stat --ignore-space-change -r
    diff-staged = diff --cached

    # From https://gist.github.com/492227
    head = log -n1
    heads = !"git log origin/master.. --format='%Cred%h%Creset;%C(yellow)%an%Creset;%H;%Cblue%f%Creset' | git name-rev --stdin --always --name-only | column -t -s';'"
    lost = !"git fsck | awk '/dangling commit/ {print $3}' | git show --format='SHA1: %C(yellow)%h%Creset %f' --stdin | awk '/SHA1/ {sub(\"SHA1: \", \"\"); print}'"

    # Find text in any commit ever
    grep-all = !"f() { git rev-list --all | xargs git grep \"$@\"; }; f"

    # Given a merge commit, find the span of commits that exist(ed).
    # Not so useful in itself, but used by other aliases.
    # Thanks to Rob Miller for the merge-span-* aliaes.
    merge-span = !"f() { echo $(git log -1 $2 --merges --pretty=format:%P | cut -d' ' -f1)$1$(git log -1 $2 --merges --pretty=format:%P | cut -d' ' -f2); }; f"

    # Find the commits that were introduced by a merge
    merge-span-log = "!git log `git merge-span .. $1`"

    # Show the changes that were introduced by a merge
    merge-span-diff = !"git diff `git merge-span ... $1`"

    # Show the changes that were introduced by a merge, in your difftool
    merge-span-difftool = !"git difftool `git merge-span ... $1`"

    # Interactively rebase all the commits on the current branch
    rebase-branch = !"git rebase --interactive `git merge-base master HEAD`"

    # Sort by date for branches; can be useful for spring cleaning
    refs-by-date = for-each-ref --sort=-committerdate --format='%(committerdate:short) %(refname:short)'

    # Find all objects that aren't referenced by any other object (orphans).
    # To help an orphan, we create a new branch with the orphan's commit hash,
    # then merge it into our current branch:
    #
    # git branch foo <commit>
    # git merge foo
    #
    orphans = fsck --full

    # List all blobs by size in bytes.
    # By [CodeGnome](http://www.codegnome.com/)
    rev-list-all-objects-sort-by-size = !"git rev-list --all --objects | awk '{print $1}'| git cat-file --batch-check | fgrep blob | sort -k3nr"


    ### LOG ALIASES ###

    # Show log of changes, most recent first
    log-changes = log --oneline --reverse

    # Show log of new commits after you fetched, with stats, excluding merges
    log-fresh = log ORIG_HEAD.. --stat --no-merges

    # Show log with dates in our local timezone
    log-local = log --date=local

    # Show the log for my own user email
    log-me = !git log --author $(git config user.email)

    # Show log as a graph
    log-graph = log --graph --all --oneline --decorate

    # Show the date of the first commit
    log-first-date = !"git log --date-order --date=iso --pretty=%ad --reverse | head -1"

    # Show the recent day
    log-day = log --since yesterday

    # Summarize your own changes since yesterday, suitable for a daily standup meeting.
    log-standup = !git log --since yesterday --author $(git config user.email) --pretty=short

    # TODO
    log-refs = log --all --graph --decorate --oneline --simplify-by-decoration --no-merges
    log-timeline = log --format='%h %an %ar - %s'
    log-local = log --oneline origin..HEAD
    log-fetched = log --oneline HEAD..origin/master

    # churn: show log of files that have many changes
    #
    # * Written by (Corey Haines)[http://coreyhaines.com/]
    # * Scriptified by Gary Bernhardt
    # * Obtained from https://github.com/garybernhardt/dotfiles/blob/master/bin/git-churn
    # * Edited for sixarm_git_config repo by Joel Parker Henderson
    # * Comments by Mislav http://mislav.uniqpath.com/2014/02/hidden-documentation/
    #
    # Show churn for whole repo:
    #
    # $ git churn
    #
    # Show churn for specific directories:
    #
    # $ git churn app lib
    #
    # Show churn for a time range:
    #
    # $ git churn --since='1 month ago'
    #
    # These are all standard arguments to `git log`.
    #
    # It's possible to get valuable insight from history of a project not only
    # by viewing individual commits, but by analyzing sets of changes as a whole.
    # For instance, git-log-churn compiles stats about which files change the most.
    #
    # For example, to see where work on an app was focused on in the past month:
    #
    # $ git churn --since='1 month ago' app/ | tail
    #
    # This can also highlight potential problems with technical debt in a project.
    # A specific file changing too often is generally a red flag, since it probably
    # means the file either needed to be frequently fixed for bugs, or the file
    # holds too much responsibility and should be split into smaller units.
    #
    # Similar methods of history analysis can be employed to see which people were
    # responsible recently for development of a certain part of the codebase.
    #
    # For instance, to see who contributed most to the API part of an application:
    #
    # $ git log --format='%an' --since='1 month ago' app/controllers/api/ | \
    # sort | uniq -c | sort -rn | head
    #
    # 109 Alice Anderson
    # 13 Bob Brown
    # 7 Carol Clark
    #
    churn = !git log --all --find-copies --find-renames --name-only --format='format:' "$@" | sort | grep -v '^$' | uniq -c | sort | awk 'BEGIN {print "count\tfile"} {print $1 "\t" $2}' | sort -g


    ### LOOKUP ALIASES ###

    # whois: given a string for an author, try to figure out full name and email:
    whois = "!sh -c 'git log --regexp-ignore-case -1 --pretty=\"format:%an <%ae>\n\" --author=\"$1\"' -"

    # Given any git object, try to show it briefly
    whatis = show --no-patch --pretty='tformat:%h (%s, %ad)' --date=short

    # Show who contributed with summarized changes
    who = shortlog --summary --

    # Show who contributed, in descending order by number of commits
    whorank = shortlog --summary --numbered --no-merges

    # List all issues mentioned in commit messages between range of commits
    #
    # Replace `\\\"ISSUE-[0-9]\\+\\\"` regular expression with one matching your issue tracking system.
    # For Jira it should be as simple as putting your project name in place of `ISSUE`.
    #
    # Best used with tags:
    # $ git issues v1.0..v1.1
    #
    # But will work with any valid commit range:
    # $ git issues master..HEAD

    issues = !sh -c \"git log $1 --oneline | grep -o \\\"ISSUE-[0-9]\\+\\\" | sort -u\"

    ### WORKFLOW ALIASES ###

    # Clone a git repository including all submodules
    cloner = clone --recursive

    # Stash aliases
    save = stash save
    pop = stash pop

    # Stash snapshot - from http://blog.apiaxle.com/post/handy-git-tips-to-stop-you-getting-fired/
    # Take a snapshot of your current working tree without removing changes.
    # This is handy for refactoring where you can't quite fit what you've done
    # into a commit but daren't stray too far from now without a backup.
    #
    # Running this:
    #
    # $ git snapshot
    #
    # Creates this stash:
    #
    # stash@{0}: On feature/handy-git-tricks: snapshot: Mon Apr 8 12:39:06 BST 2013
    #
    # And seemingly no changes to your working tree.
    #
    snapshot = !git stash save "snapshot: $(date)" && git stash apply "stash@{0}"

    # Do everything we can to synchronize all changes
    get = !git pull --rebase && git submodule update --init --recursive
    put = !git commit --all --message="$1" && git push

    # Ignore all untracked files by appending them to .gitignore:
    ignore = "!git status | grep -P \"^\\t\" | grep -vF .gitignore | sed \"s/^\\t//\" >> .gitignore"

    # Do a push/pull for just one branch
    push1 = "!git push origin $(git branch-name)"
    pull1 = "!git pull origin $(git branch-name)"

    ##
    # Reset & Undo
    ##

    # Reset and undo aliases are ways to move backwards on the commit chain.
    # We find that novices prefer the wording "undo"; experts prefer "reset".
    reset-commit = reset --soft HEAD~1
    reset-commit-hard = reset --hard HEAD~1
    reset-commit-clean = !git reset --hard HEAD~1 && git clean -fd
    reset-to-pristine = !git reset --hard && git clean -ffdx
    reset-to-upstream = !git reset --hard $(git upstream-name)

    # Undo is simply a synonym for "reset" because "undo" can help novices.
    undo-commit = reset --soft HEAD~1
    undo-commit-hard = reset --hard HEAD~1
    undo-commit-clean = !git reset --hard HEAD~1 && git clean -fd
    undo-to-pristine = !git reset --hard && git clean -ffdx
    undo-to-upstream = !git reset --hard $(git upstream-name)

    # Nicknames
    uncommit = reset --soft HEAD~1
    unadd = reset HEAD
    unstage = reset HEAD

    # Discard changes in a (list of) file(s) in working tree
    discard = checkout --
    # Clean and discard changes and untracked files in working tree
    cleanout = !git clean -df && git checkout -- .

    # Ours & Theirs - easy merging when you know which files you want
    #
    # Sometimes during a merge you want to take a file from one side wholesale.
    #
    # The following aliases expose the ours and theirs commands which let you
    # pick a file(s) from the current branch or the merged branch respectively.
    #
    # * ours: checkout our version of a file and add it
    # * theirs: checkout their version of a file and add it
    #
    # N.b. the function is there as hack to get $@ doing
    # what you would expect it to as a shell user.
    #
    ours = !"f() { git checkout --ours $@ && git add $@; }; f"
    theirs = !"f() { git checkout --theirs $@ && git add $@; }; f"

    # Work In Progress: from https://gist.github.com/492227 and VonC on stackoverflow.
    # This enables a quick way to add all new and modified files to the index,
    # while cleaning the index from the files removed from the working tree;
    # this cleaning will facilite a rebase, because there won't be any conlfict
    # due to an "unclean" working directory (not in sync with the index).
    # The unwip will restore the deleted files to the working tree.
    wip = !"git add --all; git ls-files --deleted -z | xargs -0 git rm; git commit --message=wip"
    unwip = !"git log -n 1 | grep -q -c wip && git reset HEAD~1"

    # Assume
    #
    # Sometimes we want to change a file in a repo, but never check in your edits.
    # We can't use .gitignore because the file is tracked. We use update-index.
    #
    # If you interact with big corporate projects, such as projects in Subversion,
    # then you might run into the need to ignore certain files which are under
    # Subversion control, yet you need to modify them but not commit.
    # The assume-unchanged flag comes to the rescue.
    #
    # Suppose we want to edit passwords.txt and for god's sake never check it in:
    #
    # $ git status
    # modified passwords.txt
    # modified foo.txt
    #
    # $ git assume passwords.txt
    # $ git status
    # modified foo.txt
    #
    # $ git assumed
    # passwords.txt
    #
    # $ git unassume passwords.txt
    # $ git status
    # modified passwords.txt
    # modified foo.txt
    #
    # Thanks to http://durdn.com/blog/2012/11/22/must-have-git-aliases-advanced-examples/
    # Thanks to http://blog.apiaxle.com/post/handy-git-tips-to-stop-you-getting-fired/

    assume = update-index --assume-unchanged
    unassume = update-index --no-assume-unchanged
    assume-all = "!git st -s | awk {'print $2'} | xargs git assume"
    unassume-all = "!git assumed | xargs git update-index --no-assume-unchanged"
    assumed = !"git ls-files -v | grep ^h | cut -c 3-"
    [core]
    autocrlf = false
    eol = lf