Skip to content

Git workflow tips and tricks

Koosemose edited this page Apr 11, 2017 · 1 revision

These aren't "Git problems and fixes" per se, but they are tips and tricks to help your git workflow be as easy for you and others to work with, aimed at both contributors and maintainers.

Git aliases

You can define aliases for common commands you use in git to make things shorter and easier to remember. You can see some of my configurations here, for example.

To set an alias you can either edit your .gitconfig file as shown at the link above, or add it from the command line, like

$ git config --global alias.slog="log --pretty=format:'%Creset%C(red bold)[%ad] %C(blue bold)%h %Creset%C(magenta bold)%d %Creset%s %C(green bold)(%an)%Creset' --abbrev-commit --date=short --graph --all"

This defines the command git slog which prints a much nicer (and more colourful!) commit log than the default view.

You can also define shell alias or functions in your .bashrc file for doing more complicated things. Two of my most frequently used commands are for handling Github pull requests:

#  Fetch a github pull request from <remote> and check it out locally in a branch named <remote>-pr-<pr number>
function gitpr ()
{
	if [ -z "$2" ]; then
		echo "Usage: gitpr <remote> <pr number>"
	else
		git fetch $1 pull/$2/head:$1-pr-$2 && git checkout $1-pr-$2
	fi
}

# You are on a feature branch which has been merged upstream, so checkout master, blast the old branch and sync up.
function gitpr-done ()
{
	cb=$(git rev-parse --abbrev-ref HEAD) # parse the ID of the current branch
	git checkout master
	git branch -D ${cb}
	git pull --ff-only upstream master && git push origin master --no-verify
}

# Fetch upstream then merge into current branch
function gitMerge () 
{
	git fetch upstream master
	git merge upstream/master
}

# Add Files, Commit, then push to current branch
# Call Like gitDone "Commit Message"
function gitDone () 
{
	git commit -m "$1"
	git push
}

# Add all code files (this should avoid weird commits)
function gitAddCode () 
{
	git add *.cs
	git add *.lua
}

Reverting a failed merge

Here Linus Torvalds himself tells you what to do if you merged a feature branch that broke something, then you reverted it, and now you are wondering why in the world you can't merge in the updated version of the feature which should be working.

In fact, go and read all of the howtos. They are a goldmine.

Branch workflow

Always work on a local feature branch. Don't make commits on master! Repeat after me: feature branches are for pushing, master is for pulling. Keep them separate. If you made some commits on master by mistake do this:

  • DO NOT PULL UPSTREAM/MASTER(yet). Create a feature branch pointing to your current version of master (the one with the extra commits that shouldn't be there):
$ git branch my-new-feature
  • Reset your master branch to point to upstream/master.
$ git reset --hard upstream/master
  • Now you can do any pulls and pushes you like. Keep your development on my-new-feature from now on!

If are building a bugfix or feature, always base your work branch on the oldest branch for which it makes sense. Here's what I mean. Let's say the latest stable version of the game is tagged v0.2.5 (just making numbers up here). This means that the master branch is currently taking features planned for the v0.3 release. Now let's say you find a bug that applies equally to v0.2.5 and v0.3 (i.e. the bug belongs to their common past). Then base your bugfix branch on v0.2.5 instead of master. This means that a maintainer can merge your PR into a bugfix branch on TeamPorcupine, which they can then directly merge into both v0.2.5 (bumping it to v0.2.6 as a result) and master. If instead you based your branch on master, they could not merge it into v0.2.5 since master contains features that are not a part of v0.2. v0.2 is feature frozen and accepting only bugfixes, so the maintainer would have to cherry-pick your commit. You basing your work on the oldest branch for which it makes sense saves them the hassle.