One Terasology Git Workflow

Terasology source is spread over lots of different repositories. I will use this post to show some commands and configurations which work for me when working with the codebase. Sidenote here: I use the git console for branch manipulation and my IDE for commits but that is personal preference.

Remotes

The common way to work on the engine is to fork the repository and then push to the fork. The typical name for a remote repository in git is origin however I tend to forget which of both repos is origin. Therefore I like to name my fork fork and the official repo movingblocks.

All remotes can be shown by using
git remote -v
In my case they are:

fork    git@github.com:oniatus/Terasology.git (fetch)
fork git@github.com:oniatus/Terasology.git (push)
movingblocks git@github.com:MovingBlocks/Terasology.git (fetch)
movingblocks git@github.com:MovingBlocks/Terasology.git (push)

Updating the fork

The fork can be updated by checking out the local develop branch or creating it via
git checkout fork/develop -b develop
Then we can pull from the official repository using
git pull movingblocks develop
and finally update the fork by pushing to it via
git push fork develop.

Feature branches

I never commit directly on develop but use the branch as base for feature branches. The reason for this is that we don’t control the content of the official develop branch and by adding features directly to my local branch I would force them to diverge.

Instead I create a feature branch from develop by using
git checkout -b do-amazing-stuff-here
and then add commits to this feature branches.

When everything is ready I push them to my fork by
git push fork do-amazing-stuff-here
and then create a PR using the GitHub webinterface.

Checkout PRs

From time to time it is useful to check out another contributors PR, e.g. to test it or to start building features on top of it before it is officialy merged.

Most of the time I want to test the PR but not contribute to it, therefore I need no local branch for it. Taking https://github.com/MovingBlocks/Terasology/pull/3138 as example. The id of this PR is included in the URL, it is 3138.

To checkout the PR without creating a local branch, we can use
git fetch movingblocks pull/3138/head && git checkout FETCH_HEAD
This will fetch the latest version of the PR and then checkout the git FETCH_HEAD which is a pointer to the last fetch position.

To checkout the PR as a new local branch we can use
git fetch movingblocks pull/3138/head:PR_3138 && git checkout PR_3138
Same as above, 3138 is the id of the PR. :PR_3138 tells git to create a new branch for this fetch. We could use any name here but I prefer to name the PR branches by their ids. The final git checkout PR_3138 will switch to the new branch.

Emergency switch

It happens rarely but sometimes it happens: The repository is such a mess that one would like to delete it and check out a new instance. I have a git alias for this case, stored in ~/.gitconfig:

[alias]
kill = !git reset --hard HEAD && git clean -f -d

By using this alias, git kill will reset the repository to the latest commit and delete all untracked files and directories. Use with care, loosing two hours of work in the wrong repository is a bad experience - but thats another story ;)

Written on December 26, 2017