Git – the version control technology that everyone thinks they know, but most of us don’t.
*This article is written assuming the user has at least some basic knowledge of git.
In my opinion, we know Git like people of Metropolis know Clark Kent. They know he is a reporter; they know he is a good one, but they don’t know about all the superpowers he has. They don’t know he is The Superman.
But as we move more towards cloud applications, cloud deployments, and look into setting up successful development – production pipelines, it is necessary that we know of all these superpowers that Git has! (And not just push-pull)
However, even the Superman had to spend some time learning how to control his powers. So, even we need to know how to control ours (using Git of course). Let’s do that by getting to know some basics of Git.
There are a number of services that allow Git as a version control solution. What all of these services basically do, is provide us a small cloud storage, and keep whatever data that we send to them, and store them in the storage called repositories. The only part that differs git from the other cloud storages is its ability to keep track of changes made to each file and the ability it gives us to roll back to previous changes that we made. Some examples of such services include GitHub, Gitlab, Visual Studio Team Services, and BitBucket.
Now let’s assume that we have Git installed on our systems and move onto something really interesting.
Git remote
Once we decide our Git service provider, we need to inform our local copy of Git of this decision. We call this information – Remotes. Remotes are basically stored variables that point to our chosen cloud storage. This is how we tell the local git on which (remote) location we would like to store our data. So, to go ahead add a new remote we usually follow:
git remote add origin https://github.com/user/repo.git
Now notice the different parts of this command:
‘git remote add‘ : Tells git that you want to add a new remote (location).
‘origin’ : Tells git what you will refer this remote as.
‘https://github.com/user/repo.git’ : Tells git the location of your remote.
We now have added one location, where git can store our files. But what happens when we need to maintain two repositories? Say, one for cloud deployment and another one for development?
Simple, we just add a remote with a different name.
So we can now do:
git remote add cloudDeploy https://azurewebsites.com/user/anotherRepo.git
And to see all the remotes we have added so far, we can do:
> git remote -v /*and our output:*/ origin https://github.com/user/repo.git (fetch) origin https://github.com/user/repo.git (push) cloudDeploy https://azurewebsites.com/user/anotherRepo.git (fetch) cloudDeploy https://azurewebsites.com/user/anotherRepo.git (push)
Git add – commit – push
Now that we have set up our remotes, we are ready to push our code to the remote!
To do that, let us consider an example folder structure that looks like this:
C:\miracleProjects\gitExample C:. │ index.js │ README.md │ └───app
Considering I made some changes to the index.js file, I would now like to push it to the remote. Hence to do that, we do:
git add index.js
Which adds one file to the list of files that we would like to push to the remote – this is called staging the file for the commit.
To select all the changed files we do:
git add .
To get an interactive prompt that allows us to choose which code to stage, we do
git add -p
During this, using ‘y’ will stage that chunk of the code, ‘n’ will discard it from staging and ‘s’ will split it into smaller chunks and ‘q’ will quit the prompt.
Once we have staged the files that we would like to push, we now make a commit.
Commits are basically milestones during our development process. If something goes wrong in the future we can come back to this milestone and start again from where we left off here.
git commit -m "<Commit message for later reference>"
and finally, push
git push origin master
This will of course, push the code to our remote named as ‘origin’ and a branch in that remote, named as ‘master’.
Creating and Maintaining Branches
Branches in Git is undoubtedly the best part of using Git.
Let’s say we have a very stable code in one of our projects. However, circumstances changed and now we want to add a new feature to this application and write a bunch of new code, which might break the actual code that we have. Now to do this without touching our original code, we create a branch, aka. we “branch out”.
git checkout -b newFeature
Great! We have a new branch. A new copy of our code. We’re free to add any new code that we want. But what if we want to once see what our original project looked like?!
git add . /* stage all the files in current directory with changes */ git commit -m "<message of your choice>" /* commit these changes in the files and switch to other branch */ git checkout <branch of original project / master>
Git Merge
Let’s fast-forward to the end of the addition of this new feature we talked about. This code that we added anew now works and we would like to make it a part of our original project.
Simple:
git checkout <the branch we want to merge into> git merge newFeature
Now we have all of our files from our ‘newFeature’ branch into the branch of our choice, which most probably is the ‘master’ branch. The main branch.
Merging single files/folders
We did talk about merging an entire branch into another – which means all the changed files/folder are added to the target branch. However, there are times when we don’t want to do that. We only would like to add a folder/directory or a file to the main branch. How do we do that?
/* make sure you're on the branch that you want to merge into */ git checkout newFeature parentDirectory\file-name.js
This will allow us to individually pick files that we want to merge.
Merging part of the single file
Now let’s imagine, that we need to do only a part or two of the file! So we do:
/* make sure you're on the branch that you want to merge into */ git checkout newFeature parentDirectory\file-name.js --patch
Pushing to a different branch
Finally, the case where we want to push to another remote branch from a different local branch
git push cloudDeploy newFeature:master
Where,
cloudDeploy : Is the remote that you would want to push to
newFeature : is the local branch that you would want to push from
master : is the remote branch that you would like to push to
And that is all for this article folks!
Conclusion and further reading
Having read through the article, I think it is safe to say that we now know git good enough to have it manage our code for us! If not, It certainly beats having to use zip files to share code and maintain it!
Additionally, there are still a lot more interesting parts of Git that we could not cover in this article. However, our friends at Atlassian Bitbucket are there for our help! They have this rather descriptive and noteworthy documentation that walks you right through all the nuances of using Git!
Hi Shrikar,
Nice illustration. Great analogy. However, I would suggest placing emphasis on “he” than “The Superman,” to make your statement more effective 🙂
As a IT veteran, I thought your blog showed a depth of your knowledge of the subject and a passion to share it with others as well. Hope you and the team keep more blogs coming.
Best,
Paddy