Tips & Tricks 26-Apr-2017


Given the success of both our Java 8 Best Practices Cheat Sheet and our Java 8 Streams Cheat Sheet, it looks like cheat sheets are going to become ‘a thing’ for RebelLabs! This time, we’re staring at the happiest source code management tool available today, Git. With every great tool, there is a CLI which praises all the great features and options, which leads to a vast amount of stuff you need to remember and be normal to recall within a keystrokes notice.

If like me, your memory is as apathetic as an asthmatic ant carrying heavy shopping, you might just demand a hand — or in this case, a cheat sheet! Here we’ll bear you a one-page data sheet rich with the Git direction of champions, the gems that make your SCM a bliss to work with, the… ok, enough’s enough, let’s get down to business. You can and maybe already have snapped the cheat sheet at the top of this page which adds you with a printable version. If you haven’t here’s a more current button for the less bold among you.




Well, we’ll start at the outset of course! In the start, Git created init and clone. Both of which give you an archive in which you can manage your source code. The difference being of development that your would use the init command to constitute a repository from scratch, whereas you’d use clone to literally clone, or copy an actual repository into the directory you ran the direction  from. Once this is done, we’re able to outset our workflow! Here are the two case in action, on the ZipRebel project:
$ git init myProject
Initialized empty Git repository in /Users/sjmaple/myProject/.git/

And as a clone:
$ git clone
Cloning into 'ziprebel'...
remote: Counting objects: 94, done.
remote: Total 94 (delta 0), reused 0 (delta 0), pack-reused 94
Unpacking objects: 100% (94/94), done.
Checking connectivity... done.


If we were to create a new feature for, example, we should consider building a new branch for all of our article code. This is a great best practice in my reaction as keeping your new article code separate from another development in your adept allows you to easily switch back and forth amid branches without cross-polluting your code. So how do we spawn our branches? Well that bit is simple! Simply use the branch command cursory in the term you’d like to call it, as follows:
$ git branch feature/unzip
In this case we’ve been very astute with our naming so it’s clear to read from the chapter name that we spawn the unzip article for our ZipRebel project. Although there was no assessment of this command, we can view all our chapter by using the same command, but without a framework:
$ git branch
* master

We can see a couple of stuff. First of all, we notice our new branch has been build, and secondly, our active branch we’re working on is adept, rather than the new branch. Incidentally, you can view all chapter, including remote division by adding a set of flags: git branch -av. We want to plunge into the feature/unzip branch to begin to summarize our new feature, so to switch division we’ll use the checkout command:
$ git checkout feature/unzip
Switched to branch 'feature/unzip'


This will switch our branch and amend our alive directory should the cipher bases be different. As we’ve only just build this new branch of development, there are no updates.


Let’s make an advance to our code — first we’ll… whooaooaaaaa there! We’re going to use jargon here which we’ll need to analyze and point at a state blueprint to understand fully. Check out this image:



Pretty, isn’t it. Files in our busy directory that incorporate all our files can be adapt and changed at any time, but that does not development where they sit in the diagram above until you function a git command on them. To see the state of all the case in your project, use the following command which will soon be engrained in your mind:

$ git status
On branch feature/unzip
nothing to commit, working directory clean

Let’s work on the flow of making a team of changes and see how this restore our status message. Simply by editing a set of files and not operating any other command other than a git rank gives us the following:

$ git status
On branch feature/unzip
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   src/main/java/org/zeroturnaround/ziprebel/
    modified:   src/test/java/org/zeroturnaround/ziprebel/

no changes added to commit (use "git add" and/or "git commit -a")

This show us we’ve altered a couple of files but haven’t combined them to staging (note that staging is also invoked to as the index too) ready for our next commit. We can add our files to the doing, or stage our files, by using the git add command by attribute each file alone, groups of files or calculate a wildcard which adds all alter files. We’ll do the latter now:

$ git add .
…to the sound of silence! However running the git condition command will show us it succeeded:
$ git status
On branch feature/unzip
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    modified:   src/main/java/org/zeroturnaround/ziprebel/
    modified:   src/test/java/org/zeroturnaround/ziprebel/

Now we see that git recognizes the modified files as the revision to be committed. Feels good to be on the same folio as your version control system, doesn’t it? You’ll see the HEAD token used in the amount here. The HEAD is a pointer or reference to the current branch. At this stop we could appoint to stage our file by constant git reset on a file which keeps development to that file, make the further advance that we can stage, or commit our advance to the local repository. Let’s do the latter:
$ git commit -m "Added unzip capability"
[feature/unzip 05db2cc] Added unzip capability
 2 files changed, 2 insertions(+), 2 deletions(-)

We could have done both the add and execute in the same duty if we knew we’re building a small change and we know there’s nobody else to commit, by constant the following command while we had altered files that were not yet in staging:
$ git commit -am "Added unzip capability"
[feature/unzip 8c10510] Added unzip capability
 2 files changed, 2 insertions(+), 2 deletions(-)


The -a flag will add all hunted files from the working list into staging before performing the violate. (Note that newly created files in your running directory are untracked until you manually add them). But wait, what does a carry out even mean? Well, that’s a great question! Essentially a git commit document a snapshot of your changes, marks your name, email address and commit message giving you a commit id. In our case above, we were given ids 05db2cc and 8c10510 for our example commits. These can be used later to correct, blame or pinpoint point in time of the code. Talking of blame isgit blame a fun command that annotates each line in a file with advice about who was last to change each line of code and in which execute etc. This could output a fair bit of text, so consider using a line range -L flag to limit the output to object manageable.


When a file can exist in different places with different content, it’s great to understand what has changed between the places. For example, I might want to know what the change are between my workspace file and my execute the file. Well, a number of options are available. In fact, the diff command is an acutely useful command with many use cases. We’ll cover a pretty here.

First of all, let’s acknowledge  you want to analyze all changes between your working directory and your play area. That’s easy! Just call!git diff If you want to compare your staging area with your local archive, you can call git diff --cached. Equally simple. You can even compare files across a couple of executed, by using their commit ids, like this: git diff 05db2cc 8c10510. It’s a mighty tool, so make sure you use git diff --help to view all possibilities to find what’s legal for your use case.

Finally, once you’ve completed your feature evolution in your new branch, you’ll need to consolidation it back into the main branch. So first of all, go to the arm you want to merge your article branch into. In this case, we’ll run.git checkout master Next we call the merge command passing in the branch which we want to absorb into our active branch. So we run.git merge feature/unzip All being well, our code will be naturally merged and we don’t have to worry about a single thing! However, life being the pain in the accepted that it is, our merge might have a conflict that we have to solve! The git status direction will help you understand where the conflict exists. If you open the file, you’ll notice some markers: <<<<<<<>>>>>>>, and=======, that surround the lines that conflict, along with the changes that each branch is trying achieve.

Now we’re at a fork in the road. What should we do? Well certainly you write the best code, so you could wipe out the opposing conflict code keeping your own pursue by a new do into the main branch. Alternatively, even though rather unlikely, this other developer wrote better code than you so you valor choose their code above your’s before committing. More likely, however, you’ll need to build a mutant hybrid of the two changes and check in frankenstein’s monster code into the central branch. In any case, you will need to fix the file, and then add and carry out the change to enjoy the results of your masterful conflict resolution skills.


So far all of our changes, including our depot changes have been local. We haven’t even touched our remote repository or voiced it even, since our git clone all the way up back at the outset of our post. At some stage, we’ll demand to sync up our local and remote archive and we have a few direction that can help us conclude this: pullpush and fetch.

Let’s start with what hit if we have an out of appearing local repository. This can happen if others restore the remote repository with new features, bug fixes, and code. We want to catch  these changes, in fact, I needed to say pull or fetch, but didn’t want to restate the command names, and update our local archive with the latest and greatest code. The least noisy way of doing this is by using the fetch command, which grabs all the latest do from the remote archive and imports them into a distant branch. Note here that it doesn’t add them to a local chapter in your workspace. Note that you can view remote branches with git branch -avas mentioned previously. If could merge manually from here if you chose to. Alternatively, instead of using the fetch command, you could call git pull, which performs a git fetch followed by a git merge under the covers. Another trick you can use is

If could merge manually from here if you chose to. Alternatively, instead of using the fetch command, you could call git pull, which functions a git fetch followed by a git consolidate under the covers. Another rule you can use is,git pull --rebase which performs agit fetch followed by a git rebase. What’s a rebase I hear you cry? It’s a mechanism that allows you to apply your local commits on top of the arriving commits, rather than to have two strings in parallel that need to be merged.

Lastly, the push command is pretty much adverse of a git fetch. We simply assign commits from our local repository to our secluded repository. There’s always the possibility some files can be overwritten here, so be careful!