Skip to content

Git tips

Richard Domander edited this page Sep 12, 2018 · 6 revisions

Here are some quick tips for working with Git on BoneJ.

Branching and pull requests

For bug fixes and new features it's recommended to create a new topic branch. When you've added all the necessary commits create a pull request (PR), and have it reviewed if possible. If the PR has merge conflicts, merge master to the topic branch with:

// Let's synchronize local master branch first
git checkout master     
git fetch origin
git pull
// Merge topic-branch with master
git checkout topic-branch
git merge master

after the conflicts have been solved, and the review completed, you can merge the PR with master.

When adding a larger feature like whole new wrapper plug-in with ops, it's better to divide it into several PRs, which add the functionality piece by piece. This way reviewing, merge conflicts and commit cleaning stay manageable. If the pieces cannot be added independent of each other, you can always branch the next piece from the last commit of the previous. For example, let's say you've completed the topic branch cool-op1 and created a PR. The reviewer's gone to make coffee, but you want to start working on cool-op2 now. Now you just type git checkout -b cool-op2 while you're on the cool-op1 branch instead of master. If the cool-op1 PR has been merged to master before cool-op2 is ready, then eventually you create a PR from it like always. If not, then you create PR, that uses cool-op1 as its base, i.e. you merge the two topic branches.

Fixing mistakes

The most important thing to realize about working with Git is that nothing you do is irreversible. So be brave and commit early and commit often, but learn how to fix things. Rebasing is the most powerful tool available. It allows you to rewrite commit messages, change the order of commits, "squash" them into one and delete them. In other words, it allows you to completely rewrite your commit history. This is why you should be extra careful, and why Git won't allow you to push rebased commits without the --force argument.

Resetting is another handy tool for fixing git mistakes. Calling git reset --soft allows you to return to an earlier point in the commit history, without losing any work. Let's say you forgot a file from the previous commit. You can fix this by calling git reset --soft HEAD~1, which moves one commit back in the history. Now just add the forgotten file, and commit again. You can use the relative HEAD~n option that jumps back n commits from the current point, or a specific commit number. git reset --hard is handy, when, for example, you want to pull remote master to your master, and git (erroneously) thinks there are merge conflicts. The command git reset --hard origin master overwrites your master with the remote. The local commit history is lost.

Forks

When working on a fork of another repository, you don't just have the local and remote repositories. You also have to keep track of upstream, which is the original repository you forked from. Whenever you need the master branch, for example when creating a new branch, make sure it's synchronized with upstream. You can do this by calling

git fetch upstream
git checkout master
git merge upstream/master

Miscellaneous

  • Calling git commit -a starts a new commit that includes all changed files.

  • When adding files to a commit, you can use tab-completion, directories and wild-cards. For example, running git add src/test/ adds all changed files in path src/test/ to the commit. Calling git add src/test/A* adds all files under src/test/ that start with an A.

  • Made a typo on the commit message, and haven't pushed yet? Just call git commit --amend.

  • Noticed you've been working on the wrong branch? Save your work with git stash, switch to the correct branch with git checkout correct-branch and call git stash apply. Now the changes are where they should be!

  • It doesn't hurt to be doubly sure of what you're doing.

    • git status shows which files have changed, and which are included in the next commit.
    • git diff shows which lines have changed in the files.
    • git branch shows which branch you're working on
  • When reviewing code, you can check out a pull request with

    git fetch origin pull/#ID/head:BRANCHNAME
    git checkout BRANCHNAME