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.
- Make a new commit, fixing the bug. The commit message doesn’t matter as it will be lost later.
- Use
git rebase -i HEAD~4
to bring up an editor with the commits. - Move the fix commit (the one created in step 1) immediately below the commit that introduced the bug and change the prefix from
pick
tofixup
. - 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.
- Check out
master
or whatever branch you want to start your new branch from. - Use
git checkout -b MyNewBranch
to create the new branch - 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. - 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
.
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'" |