Personal Knowledge Base

A personal knowledge base

Git

#Tips from Enki

#Show changes in a merge commit

git show -m dbfe3be

#Show Commits Made on a Branch

 git log --first-parent --no-merges origin/something

This will list the commits made on the origin/something branch and ignore merge commits (--no-merges) and the commits they brought in (--first-parent).

#Set User Email Address

git config --add user.email wes@example.com

#Change User Email Address of Last Commit

git commit --amend --reset-author

#Auto-stash when rebasing

This will stash changes to do a rebase, then pop them when done.

git config --add rebase.autoStash true

#Set Master to Track Origin

git config --add branch.master.remote origin
git config --add branch.master.merge refs/heads/master

Alternatively when pushing for the first time:

git push -u origin master

#History for Range of Lines in File

git log -L 1,+10:app/views/cases/edit.html.erb

Will show the history of lines 1-10 in app/views/cases/edit.html.erb.

#Delete Merged Branches

DANGER: This is pretty heavy handed but I had a stack of branches to clean up and it did the job. Use with caution and with backups in place.

git branch --merged | grep -v 'master' | xargs -n1 git branch -d

#Extract Pivotal Tracker ID from Branch Name

This is saved as .git/hooks/prepare-commit-msg to pre-fill the commit message with the Pivotal ID of the story the commit relates to:

# shell
#!/bin/zsh

function pivotal_id() {
  ref=$(git symbolic-ref HEAD 2> /dev/null) || \
  ref=$(git rev-parse --short HEAD 2> /dev/null) || return

  echo ${ref#refs/heads/} | grep -Eo '\d{5,}$' || \
  echo ${ref#refs/heads/} | grep -Eo '^\d{5,}'
}

id=$(pivotal_id)
if [[ ! -z "$id" ]]; then
  echo "1a\n\n[#$id]\n.\nw" | ed -s "$1"
fi

The resulting commit message opens like this:

â–‹

[#112866593]
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch multi-stripe_112866593
# Your branch is ahead of 'origin/multi-stripe_112866593' by 2 commits.
#   (use "git push" to publish your local commits)
#
# Changes to be committed:
#>------modified:   db/schema.rb

#Run Linters on Added and Changed Files Before Push

Save this file as .git/hooks/pre-push (and make sure it's executable). Git will then run the script before pushing to the remote and run linters on added and modified files.

#shell
#!/bin/sh

# An hook script to verify what is about to be pushed.  Called by "git
# push" after it has checked the remote status, but before anything has been
# pushed.  If this script exits with a non-zero status nothing will be pushed.
#
# This hook is called with the following parameters:
#
# $1 -- Name of the remote to which the push is being done
# $2 -- URL to which the push is being done
#
# If pushing without using a named remote those arguments will be equal.
#
# Information about the commits which are being pushed is supplied as lines to
# the standard input in the form:
#
#   <local ref> <local sha1> <remote ref> <remote sha1>

remote="$1"
url="$2"

z40=0000000000000000000000000000000000000000

while read local_ref local_sha remote_ref remote_sha
do
  if [ "$local_sha" = $z40 ]
  then
    # Handle delete
    :
  else
    if [ "$remote_sha" = $z40 ]
    then
      # New branch, examine all commits
      range="$local_sha"
    else
      # Update to existing branch, examine new commits
      range="$remote_sha..$local_sha"
    fi

    # Run linter on added and modified ruby files
    ruby_files=`git diff --diff-filter=AM --name-only "$range" | grep '\.rb$'`
    [ $? -eq 0 ] && rubocop --force-exclusion $ruby_files
    coffee_files=`git diff --diff-filter=AM --name-only "$range" | grep '\.coffee$'`
    [ $? -eq 0 ] && coffeelint $coffee_files
  fi
done

exit 0
Last modified: 26 September 2018