GIT CLUES AND GIMMICKS


Sometimes I think about Git, I think about it as a time capsule one can travel with at a specific point of time in the source code history. Even though it might seem pretty simple, Git is an extremely powerful tool which, handled inappropriately, could generate a big mess. I strongly consider that before you start playing and trying different tricks with Git, you should have an understanding of its basics, knowing how it works under the hood and mastering the basic commands (e.g. init, clone, push, pull, status, log, etc) and concepts (e.g. repository, branch, commit, etc).

18333fig0302-tn

So, considering you are already familiar with Git, here is the list of some of the most interesting and helpful Git tips and tricks I am aware of.

But… Let’s define some key concepts first:

  • public branch – a branch where several people push the changes to (with or without using merge/pull requests);
  • private branch – a branch where only you (and only you) push changes to.

Reflog. Revert operations


I remember that in the beginnings, when I started to use Git, I was sometimes afraid of running commands. I was thinking that could mess the things up. For instance, the first contact with   gitrebase command generated a few “Ohh ****! What did I just do?!” reactions due to some duplicated or even missing commits. Soon after that, I realized that I should start getting deeper into the Git world.

Personally I don’t like using a tool in a certain manner just because this way I will get the result I expect, without knowing what exactly happened on the way to that result.  It’s like driving a car without a steering wheel. Everything is working fine until you reach the first curve on the road. What will happen next? I guess you can imagine.

So, back to our business, it’s extremely important to understand the concepts. I read a lot about Git, followed some tutorials, and the Git world completely changed into my mind. While using it, I started to feel more comfortable than before, and more important I started becoming aware of its power. And one of the most powerful things Git is offering is git reflog  command.

Using reflog you can go back in time by reverting almost every action you already have done with Git. Even if it was a rebase or a reset or other “damaging” operations. Even more, it’s extremely easy to use it. In order to prove that to you, let’s take a quick example.

To move to the desired state you just need to run a checkout using the absolute reference:

or using the relative reference:

and you will end up in a detached HEAD state you could create a new branch from.

And that’s it. All the operations from the specified state above are now reverted.

Revert. Undo commit changes


You must have encountered at some point the situation when the revert of some changes to be requested. Here comes to help the revert command:

What does it do? It just reverses the effect of some earlier commits (often faulty ones) by creating a new commit containing all the reversed changes. Simple as that. Why use it instead of other practices for reverting changes? It’s the only way to do a safe changes revert, since it doesn’t alter the commit history. It is usually used for reverting changes on public branches where changing the commit history is inadvisable.

Let’s take a look at the other commands capable of doing reverts.

Rebase

You can run this command and then just remove the line(s) corresponding to the unwanted commit(s). This way they will disappear. It’s probably the simplest and cleanest solution for doing commit reverts. However it has one flaw which prevents you from using it on public branches: it alters the commit history.

Reset

It removes all the commits applied on top of the specified one. It’s a cleaner way to revert changes, but the commit history is changed as well, so it’s generally applicable only on private branches.

Checkout

It brings the specified file to an earlier version (of the specified commit). You will have the revert changes in the working directory, so you can commit them as you wish.

The conclusion is that even though it’s not the cleanest one, git revert  is the “safest” operation to do a revert. Also, please note that the above commands are not 100% interchangeable (in regards to the cases they can treat), but there are situations when all four approaches lead to the same result.

Log. Prettier format


When it comes to git log things are pretty simple. You just type in the command, hit enter, and the commit history will show up, the commit history being the list of the commits presented in a chronological descending order, each with its summary including by default the commit hash, the author, the date when the commit has been recorded, and the commit message. Not much information, but presented in a sprawling way (6 rows for each commit).

Let’s take a look at the default log:

I would say that it could be better.

I generally prefer to keep things simple. So, instead of using the basic log command, I add two options:

  • oneline – shows each commit on a single line. Besides, instead of displaying the full 40-byte hexadecimal commit ID, it shows only a partial prefix.
  • decorate – prints out the ref names of any commits that are shown.

Here is how it looks like:

The option “–oneline” reduces the space in rows filled by a commit from 6 rows to just one. The option “–decorate” adds the ref names (local/remote branches + HEAD). Using this two options we create a more compact and meaningful git log. We still have the commit hash in its short version, we don’t have the author and the commit date, but generally these are things we don’t care about. We still have the commit message, and, even more, we have the refs which are often useful. All of this in just one line. Much better than the default one, don’t you think?

Well… Though there are cases when we need to know the commit date and the author. In order to add those I prefer to use:

Wow! There’s a pretty complicated command, right? First, let’s see how it looks like:

Pretty good I’d say. There’s a color format also to help you better distinct different types of information, but I can’t show it to you here.

Ok, but it would be a real burden to type the above command in every time you need it, right? So, let’s do the alias trick. In regards to aliases I personally considered them an extremely simple, but powerful technique to burst your productivity. So, in order to register the aliases we will add the following lines to “~/.bash_profile” (considering you are using a *nix OS):

We are now reaching the point where we have not only a better look for the commit history, but we are having a quicker way to access it by using the commands gl  and gh .

Diff. Between commits, cached


Git diff is a pretty straightforward command showing the differences between the working tree and the last commit, in it’s basic form git diff. I guess you already know how it looks like.

It can be used though for slightly different scenarios or needs. One of them is showing the differences between two commits:

Another one is showing the differences between the last commit and all the changes from the working directory and the staging area. I found this useful when I don’t necessarily want to unstage some files, but I still want to compare all the changes within them. In order to do that we will have to run:

These are two simple ways to use git diff which helps you to cover a couple of diff scenarios encountered even in a basic use of git.

Branch. Check which branch is merged


I suppose you already know what the basic git branch command does, so I will get straight to the point. The following is a simple, but often useful command. I guess that at least once in a while it is the time to clean up branches. I mean to cut the old and/or redundant branches from your git “tree”.

Using the following:

you get the list of all branches already merged with the currently checkout branch.

You can also do the opposite:

to get the list of all the unmerged branches.

So, you will always know if it’s safe or not to remove a specific branch.

Checkout. Fetch a file from another branch


It probably happened to you to need a specific version for a file, version found on another branch which was not merged at that moment. Do you remember the checkout command listed above that brings the file to one of its earlier versions? It looks like this:

The specified file will have the version specified by the commit argument after the above command is run. We used it earlier in the context of the same branch when we wanted to revert some of the changes applied to the file. The good thing is that the specified commit does not necessarily need to belong to the currently checkout branch. So, you can bring whatever version you want for whatever file you want from whatever commit (branch) you want.

The alternative I could see is to:

  • stash your eventual changes from the working tree;
  • checkout the commit where the version you need is;
  • copy the code;
  • go back to the original branch (checkout);
  • pop the stash;
  • paste the code you just copied into the file.

It’s not complicated, but a waste of time, since all these steps could be squashed into a single one.

I hope you have found some useful stuff in here that could help you to become more proficient and productive in regards to Git usage. Please note that all the things I presented have a considerably dose of subjectivity, since they are mold to my needs so far.

Previous HDMI BRINGS IMPROVEMENT TO HDR, GAMING etc
Next Spidercam Tech makes Premier League debut in Manchester United vs Liverpool match

No Comment

Leave a reply

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