Getting away with Git

2019/09/02

Categories: Tools Tags: git terminal tools

The latest post from Bitbucket, where they reveal the upcoming end of Mercurial support, got me thinking about how much I value git’s help in everyday tasks.
What better way to revisit some classic terminal commands and checkout alternative tools than a new post! :)

Git is already a industry standard for most developers (just checkout this 2018 Stackoverflow survey), so it’s good to have it at your fingertips.

The goal here is not to do a full tutorial, that can be found almost everywhere. Instead, I’d like to cover those quirky yet often essential commands.
Let’s go trough by checking out a remote repository, do some changes, push back, create a new branch and push it to origin again. This should cover the more usual daily git workflow.

I’ll show off by starting in a directory of choice and cloning this existing repo (it would be best if you followed along with your own git repository ie. on Github, Bitbucket or similar):

$ git clone https://github.com/orbjet/blazing-vue.git

Cloning into 'blazing-vue'...
remote: Enumerating objects: 19, done.
remote: Total 19 (delta 0), reused 0 (delta 0), pack-reused 19
Unpacking objects: 100% (19/19), done.

Now we have the repo unpacked and ready for work. Let’s create a new branch and make some changes.

Following the commands below, we’re creating a new branch my-branch and checking it out.
Next we’re adding a file named myFile.txt and committing it with a message added some text. Finally we push the changes back to it’s origin.

$ git checkout -b my-branch 
Switched to a new branch 'my-branch'

$ git add myFile.txt 
$ git commit -m "added some text" 
[my-branch b6ab2c6] added some text
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 myFile.txt

$ git push -u origin my-branch
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 320 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote:
remote: Create a pull request for 'my-branch' on GitHub by visiting:
remote:      https://github.com/orbjet/blazing-vue/pull/new/my-branch
remote:
To https://github.com/orbjet/blazing-vue.git
 * [new branch]      my-branch -> my-branch
Branch my-branch set up to track remote branch my-branch from origin.

A quick note on the “-u” flag, this makes it possible for the upstream repo to track changes with the new locally created branch. Without it, this will not work.

The previous steps assume that you want to create a branch based on master. But what about creating a sub-branch. A branch based from another branch?
Let’s create a new branch from the one we had last and list all the branches we have:

$ git checkout -b my-sub-branch my-branch
Switched to a new branch 'my-sub-branch'

$ git branch
  master
  my-branch
* my-sub-branch

Now, if someone was working and merging into the master branch or someone was adding changes to the my-branch branch, the my-sub-branch would fall behind with keeping up up-to-date changes.
A good rule of thumb is to merge the parent branch into your own working branch. Why? Well that should save you from the merge hell and potentially long lasting file-conflict resolvement. The more your branch is “solo”, the more you’ll end up fixing when returning your changes back to master. Unlike rebase, this method will preserve historical changes on the commited files.


After all this branching and messing around, it would be good to do some cleaning, right?! :) So, after a pull request is made to master, depending on the git provider, you should have the option to delete the branch after merge.
The question arises, what happens to the local branches tracking those that are long gone?

$ git remote prune origin --dry-run
Pruning origin
URL: https://github.com/orbjet/blazing-vue.git
 * [would prune] origin/my-branch

The prune command makes it easy to delete orphan branches on your local machine. Using –dry-run gives a preview of the deletion.

$ git remote prune origin
Pruning origin
URL: https://github.com/orbjet/blazing-vue.git
 * [pruned] origin/my-branch

If we check the state of the repository, we’ll see that the remote refenrece is removed. What’s left is to actually delete the local branch.

$ git branch -a
* master
  my-branch
  remotes/origin/HEAD -> origin/master
  remotes/origin/master

$ git branch -d my-branch
Deleted branch my-branch (was 701de72).


Ok, this should cover the terminal-living developer. I came to a really nice discovery some time ago, and been stuck with it since. Two GUI based Git clients that I’d like to mention here. One is from a small team that made Fork and the other is from the excellent Sublime team.
Fork is a nifty little git client built with passion and care. It’s free and can outperform some of the bigger, payed ones. Before shifting to Sublime Merge, I had quite a run with Fork, and would gladly recommend to give it a try.

The one I got stuck with the longest is Sublimemerge. Whoa! What speed and agility it gives with one click and one key press. Support for partial commits, easier diff overview, creating/deleting branches, pulling/pushing… I can’t showcase better than the official site, so go and check that out. One thing to note is it’s price, at the time of writing is 99$. That might put off many, but the trial mode does not limit the user and if you really find it useful you should support the developers (for even better features!).

Sublime Merge is built on the same custom platform as Sublime Text, providing unmatched responsiveness. With a powerful, cross-platform UI toolkit, an unmatched syntax highlighting engine, and a custom high-performance Git reading library, Sublime Merge sets the bar for performance.

So, as you can see Git is really a great tool. What a statement! :)
Every post I create here is backed up by this versatile tool. After every major change, I end up commiting and pushing to my online repo. This gives me the possibility to continue making changes where ever I end up checking out.
And no matter what, I can always revert to a point in time of the repository.