Become a Git Wizard with 7 Simple Tricks

With git, it’s possible to do things that must be considered pure magic for anyone using older version control systems. Learn 7 simple tricks that will help you take the leap beyond commit, push and pull and let you leverage the powers of git. With these 7 tricks, you will be the git Wizard of the office.

This is a summary of my talk at Tech Days Sweden 2015. The explanations here are very brief, if you would like me to explain anything of this in more detail in a separate post, please leave a comment.

Multiple remotes

When working with open source projects on github add multiple remotes.

  • origin is your own fork.
  • upstream is the original repo you forked.

When I’ve cloned AuthServices, this is how I clone the fork and then add the original as a remote. Finally I set up my local master branch to track the upstream/master instead of the never-updated master in my fork.

$ git clone https://github.com/AndersAbel/AuthServices
$ cd AuthServices
$ git remote add upstream https://github.com/KentorIT/AuthServices
$ git branch -u upstream/master

The Azure integration with GitHub is awesome. Just push the changes to GitHub and it’s live on Azure a few moments later. It’s great – until it goes wrong and it is all black magic that can’t be debugged. There is a simple solution though, instead of pushing the change to GitHub – push it directly to Azure. That will show the actual build output in the git console.

$ git remote add azure https://tdswe15.scm.azurewebsites.net/TDSwe15.git
$ git push azure master
Counting objects: 1, done.
Writing objects: 100% (1/1), 173 bytes | 0 bytes/s, done.
Total 1 (delta 0), reused 0 (delta 0)
remote: Updating branch 'master'.
remote: Updating submodules.
remote: Preparing deployment for commit id 'cb26b193bd'.
remote: Generating deployment script.
remote: Running deployment command...
remote: Handling .NET Web Application deployment.
remote: All packages listed in packages.config are already installed.
remote:   TDSwe15 -> D:\home\site\repository\TDSwe15\bin\TDSwe15.dll
remote:   Transformed Web.config using D:\home\site\repository\TDSwe15\Web.Release.config into obj\Release\TransformWebConfig\transformed\Web.config.
remote:   Copying all files to temporary location below for package/publish:
remote:   D:\local\Temp\8d2d9734c47b075.
remote: ..
remote: KuduSync.NET from: 'D:\local\Temp\8d2d9734c47b075' to: 'D:\home\site\wwwroot'
remote: Finished successfully.
remote: Deployment successful.
To https://tdswe15.scm.azurewebsites.net/TdSwe15.git
   5a9f3ca..cb26b19  master -> master

Only Commit Some Changes

I’ve explained most of this previously in the Partial Commits with Git post.

What’s added is that in the session I also showed git add -p which allows staging only parts of the changes of a single file.

Rebase to Hide Bugs

If there is a bug 3 commits back, it can be hidden through the use of rebase.

  1. Make a new commit, fixing the bug. The commit message doesn’t matter as it will be lost later.
  2. Use git rebase -i HEAD~4 to bring up an editor with the commits.
  3. Move the fix commit (the one created in step 1) immediately below the commit that introduced the bug and change the prefix from pick to fixup.
  4. Save the file and exit

Cherry-pick to Break out a Commit to a separate Branch

If an unrelated commit has been done in a branch, it can be moved to a separate branch.

  1. Check out master or whatever branch you want to start your new branch from.
  2. Use git checkout -b MyNewBranch to create the new branch
  3. Get the commit with git cherry-pick XYZ where XYZ is the hash of the commit that you want to have in the new branch.
  4. Repeat if you have more commits to add to the new branch.

Now the new branch is created. To finalize, the offending commit should be omitted from the original branch. That is done through a rebase, just like shown above but instead of moving the commit – just delete (or comment out) the line with the commit.

Simple Check Out of Pull Requests

In the .git/config file in the repository, find the section for the remote that contains the pull requests (probably named upstream if you followed my advice above). Add a line to fetch the pull requests. The section should now look like this:

[remote "upstream"]
  url = https://github.com/KentorIT/authservices
  fetch = +refs/heads/*:refs/remotes/upstream/*
  fetch = +refs/pull/*/head:refs/remotes/upstream/pr/*

Now a git fetch will bring down all pull requests. They can be checked out with git checkout pr/42.

Merge --no-ff to Keep Branch Structure on Merge

When merging a branch, use the --no-ff option to prevent git from doing a fast forward. With a fast forward it’s not possible to see what commits where work-in-progress on the feature branch. If there are such commits, it can be good to preserve them, but keep them as a separate track in the revision graph. That is done by adding the --no-ff switch to the merge command.

Use Git Reflog to Get Back

It’s easy to get lost and make mistakes. It’s bad when a mistaken git reset --hard results in a branch with valuable code being lost. Using git reflog will show how HEAD have been moved to different commits. In the list, the hash of the important (and now lost) branch can be found.

A Compact but Detailed Version Graph

To get a compact, but yet detailed version graph in the console I use an alias git lg.
git-lg

To define the alias and make it available in all repositories on the local machine, enter this command:

$ git config --add --global alias.lg "log --all --graph --pretty='%h %C(cyan)%cd %C(auto)%d %C(bold yellow)%an%n%C(reset)%<(139,trunc)%s%n'"

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.