Git Tips and Tricks

The following are useful git tips and tricks.

Cleanup to a given branch

Often times a git repo needs to be brought up-to-date with the remote quickly. Using a feature branch style also means that branches need to be cleaned up as well. The following does all that.

Info

If you copy the below into git-cleanup and put it in your path, then Git will automatically consider it a subcommand. So within a git repo just run git cleanup main (note the space) will move your to the main branch, sync it with the remote, and delete any synced branches.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/env bash

# Unset the PAGER to prevent interactive behavior
unset PAGER

# Update main to remote, and branches that were deleted in the remote
# NOTE: "-d" will only delete if everything is merged, which doesn't work for
# squash commits.  so use "-D" instead

git fetch -p \
&& git checkout main \
&& git pull \
&& git branch -v | grep "\[gone\]" | awk '{print $1}' | xargs git branch -D

branch=$(git branch | grep "*" | awk '{print $2}')

if [[ "$branch" != "main" ]]; then
  echo "Left on branch $branch, manual cleanup may be required"
  git branch
  exit 1
fi

Find the hash of the latest commit

1
2
3
4
5
# If you know you are in the HEAD commit
git rev-parse HEAD

# or, one that works regardless
git log --pretty="oneline" | head -n1 | awk '{print $1}'

Find the files that changed

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
ANCESTOR="master"
COMMMIT="HEAD" # replace with commit hash if you could be in detached head

# sync the acenstor branche to ensure it has full history
git fetch origin "$ANCESTOR:remotes/origin/$ANCESTOR"

# diff to the anscestor
git diff --name-only "origin/$ACTIVE_BRANCH"..."$COMMIT"

# Unfortunately this doesn't catch if you are on $ACTIVE_BRANCH.
# So you need to check the the last commit if the above produces no output
git diff --name-only "$COMMIT^..$COMMIT"