Permalink
Fetching contributors…
Cannot retrieve contributors at this time
105 lines (76 sloc) 4.77 KB
layout title date categories tags excerpt permalink thumbnail comment private
post
Secret sauces of Git
2016-06-10 00:00:00 -0700
articles
Git
Github
version control
Here I go through some advance use of Git as part of my daily workflow
true
false

Git is an essential part of my daily workflow. There are certain awkward situations that require use of certain Git commands that are normally not part of regular workflows.

As part of agile workflow at Rated People we use Atlassian JIRA – tightly coupled with many other integrated technologies – all together making a combined workflow of TDD, CD and CI. To make sure JIRA tickets are tracked correctly we enforce that each commit message should include JIRA ticket number in it. On failing to do so developers get an error and not able to push changes to remote.

Update last commit message:

Let's say, I forgot to add JIRA ticket number in a commit that I just finalised. Now I cannot push the changes until commit message is updated with a JIRA ticket number. In such situation, to edit most recent commit message I use following Git command:

{% highlight bash %} $ git commit --amend {% endhighlight %}

This will open commit message in default Git editor where I can edit the commit message and save the changes. Now I can push the latest commits with no problem.

You can set a default Git editor using $ git config --global core.editor {editor_name} where replace editor_name with correct editor name i.e. vim, pico, nano etc.

Update few commit messages:

But sometimes when I have some good music going in the headphones, I may randomly forget to add JIRA ticket number in multiple commit messages. In such case, above command to amend the last commit message is not useful anymore. Instead following command that uses rebase with a flag and number of commits to amend works better:

{% highlight bash %} $ git rebase -i HEAD~{n} {% endhighlight %}

Where n is number of commits to be listed. Here comes the interesting part as this command is completed in following two steps:

Step 1

Opens a list of specified number of commits in default editor in following format.

{% highlight bash %} pick commit_hash commit_message {% endhighlight %}

To update a commit message, we replace pick with reword and above line becomes: {% highlight bash %} reword commit_hash commit_message {% endhighlight %}

Beware that removing a complete line will result in lost of commit.

At the bottom it also lists out all the available options. {% highlight bash %}

Commands:

p, pick = use commit

r, reword = use commit, but edit the commit message

e, edit = use commit, but stop for amending

s, squash = use commit, but meld into previous commit

f, fixup = like "squash", but discard this commit's log message

x, exec = run command (the rest of the line) using shell

{% endhighlight %}

Saving the changes completes step 1 and enters into step 2.

Step 2

Each commit prefixed with word reword will open one after each other where commit messages can be updated as required. Save and exit to update the commit messages.

Pushing updated commit messages:

Now like me, if you were too quick to push the changes to remote then you cannot push any changes made to the commits using one of the above methods. Use --force flag to push changes to remote with updated commits.

{% highlight bash %} $ git push origin HEAD --force {% endhighlight %}

Remove remote branch:

Sometimes we create unwanted or wrong branches in remote but unable to delete those – perhaps due to limited permissions. Use following Git command to permanently delete a branch in remote:

{% highlight bash %} $ git push origin --delete {branch_name} {% endhighlight %}

Beware that this action CANNOT be undone. A branch deleted from remote cannot easily be recovered so proceed with caution and backup branches first.

Add changes to finalised commit:

Sometimes we finalise commits only to realise that there were few more changes that could have been part of the same commit. Enter Git soft reset:

{% highlight bash %} $ git reset --soft HEAD~{n} {% endhighlight %}

Where n is a number of one finalised commit message that will be reset softly. Once done with further changes use following command to finalise the commit again by retaining the existing commit message.

{% highlight bash %} $ git commit -c ORIG_MSG {% endhighlight %}

Fancy Git log:

A last but not lease and my favourite Git log command is combination of multiple flags that outputs an interactive view of Git history.

{% highlight bash %} $ git log -{n} --oneline --stats --color --graph --pretty {% endhighlight %}

Where n is number of commits to be shown as part of the log.