Chapter 3: Practically Using Git

Creating Cars 🚓 on Git = Working Directory → Staging Area → Repository

Suryaa Jha
Suryaa Jha’s Blog
14 min readApr 26, 2021

--

At end of this chapter, all versions of the car in Git’s repository

In this chapter, we will create the car project on our laptop which was discussed in the analogy chapter. We will exactly mimic all the scenarios Ram dealt with in his four days of work on the car project. Of course, we are software engineers and not mechanical engineers, therefore we will create our car through graphics. For creating the car, we will use Scalable Vector Graphics(SVG) which is an HTML/XML-like graphics coding language. You don’t need to know a lot about SVG’s syntax and semantics. In a nutshell, it has some basic HTML-like tags that can be used to create certain shapes. For example, it has a “<rect>” tag, that can be used to create a rectangle.

<rect width="300" height="100" fill="red" />

The above SVG tag creates a rectangle with a height, width of 100, 300 units respectively, and fills it with red color. Following are the meanings of tags we are going to use for creating our car graphics.

  1. <svg> … </svg> : It marks starting and ending of image created using SVG elements.
  2. <rect /> : Used to create rectangular shape.
  3. <ellipse /> : Used to create egg like shape.
  4. <g> … </g> : Grouping multiple structure like rect, ellipse into one container.
  5. <path> … </path>: Create a multiside polygon.

Though it is not required, if you are interested in knowing details of how to use these elements, you can refer to the w3schools course on SVG.

I highly recommend, reading the analogy chapter before reading this one. You should follow along with all the commands as you read this chapter. I have shared SVG files as we use it, it's okay(recommended) to copy-paste SVG files on your machine, instead of typing. However, I encourage you to type “Git commands” on your own. After all, we are here to learn Git and not SVG’s.

We will mimic all the work done by Ram in the previous chapter and use Git to store all versions of the car as we build it. There is only 1 difference, I have added Day 0 where we build “Version 0” of our car project. Version 0 constitutes a car assembler that assembles all parts of the car into a full “final” car.

Requirements

  1. Git Install
  2. Python3 (for car assembler) Install
  3. Browser (To view how our final car will look like)

Let start mimicking the work done by Ram, but before that, we will build and store Version 0 of our car project.

Day 0

  • Create a directory(folder) with your project name “svg-car”.
  • Open the folder using a text editor. You are free to use any text editors like notepad, atom, sublime, etc. It's just about writing some piece of text.
  • Open Shell or Terminal app and change directory to “svg-car”.
$ cd svg-car
  • Initialize the git repository, this creates 3 sections Working Directory, Staging Area, and Repository.
$ git init
$ git init
git init” creates 3 sections in our project
  • Inside “svg-car” create 2 new files
svg-car
├── car_assembler.py
└── car_assemble.svg
source for “car_assembler.py”
source for “car_assemble.svg”

It's okay if you don’t understand the Python programming language or what the python code is doing. Let me quickly mention what we have written in those 2 files …

  1. car_assemble.svg →This file will hold the structure of our car, as you work, you will see that we will create, specific files for different parts of the car like wheels.svg, car_frame.svg, etc and include those files in car_assemble.svg. It's kind of like a container file. This will also be, input to the “car_assembler.py” python script.
  2. car_assembler.py →This is a python script, which takes car_assemble.svg as input and replaces tags like, <include file=“abc.svg”/> with the contents of the included file and creates the output SVG file “final_car.svg”. We will use www.svgviewer.dev to view how the output file looks at different versions of our project.
  • Git can also hint you how you should operate Git. These hints are given as the output of the “git status” command.
$ git status
$ git status
  1. Both the files are untracked(Git is not watching).
  2. No versions(commits) are stored yet.
  3. It is advising to use the “git add” command to add untracked files to the staging area.
  • Let’s take that advice and use “git add” to add both the files to the staging area.
$ git add car_assembler.py car_assemble.svg
  • Once again run the git status command to see that both files are added to the “staging area”.
$ git status
$ git status

As you can see car_assembler.py, car_assemble.svg are shown in green and are under section “Changes to be committed:” This tells us that both the files are in the staging area. To cross-verify you can run git ls-files which lists all files present in the staging area.

$ git ls-files
$ git ls-files
  • Now we are happy with the version of our project, let's create a savepoint(commit) in the repository. We will use the command “git commit”, which takes an argument “-m” for the message. Messages are used to comment on what changes we made to our project on a particular commit.
$ git commit -m 'V0: Add Car Assembler'
$ git commit -m ‘V0: Add Car Assembler’

You can run the “git log” command to list all saved(committed) versions of your project in Git’s repository.

$ git log
$ git log

We are ready with the assembler, this will be used to construct the car as we will see further in this chapter.

Day 1

  • As we know Ram worked on the car frame on Day 1. Let us work on the car frame in our working directory. Create a new file “car_frame.svg”. Your directory structure should look like this
svg-car
├── car_assembler.py
├── car_assemble.svg
└── car_frame.svg (new file added)
0 directories, 3 files

You can see what this SVG looks like on the www.svgviewer.dev app. Simply copy the content from the above SVG file and paste it over there.

Creating new file “car_frame.svg” in Working Directory
  • We have created our car_frame. Let's add it into the staging area so that we can store(commit) this version in our repository. Before that, let us see the status of our project using “git status”
$ git status
$ git status

Under untracked files, we can see a new file “car_frame.svg”. By default files are untracked by Git, to track and stage this file, we will use the “git add” command. Let's add this file to the staging area for committing this version of our project.

$ git add car_frame.svg
Adding “car_frame.svg” to Staging Area form Working Directory using “git add
  • Running git status again shows that car_frame.svg is added to the staging area.
$ git status
$ git status

However, I told you earlier that, staging area holds a copy of all the files. But the above command shows only car_frame.svg under staging area (Changes to be committed:) This happens because “git status” only shows what new files/changes are added to the staging area. To know, all files inside the staging area, you can use “git ls-files”.

$ git ls-files
$ git ls-files

As we can see, all three files are present inside the staging area.

  • To see what changes you added to your project, since the last time you saved a snapshot(commit), you can use the command “git diff”. (Press “q” to quit from the “git diff”)
$ git diff --staged
$ git diff — staged

It's clear that we added a single file car_frame.svg, all the lines are green because this is a new file and nothing has been deleted(which git shows in red).

  • Let say we just missed adding a door to our car_frame. Let's quickly add the door to our car frame in our working directory. Create a new file door.svg
svg-car
├── car_assembler.py
├── car_assemble.svg
├── car_frame.svg
└── door.svg (new file added)
0 directories, 4 files
Creating new file “door.svg” in Working Directory

Also, include both the files in our “car_assemble.svg” so that we can use our python “script car_assembler.py to assemble all parts into a “final_car.svg.

  • Open “car_assemble.svg” and edit the file to look like below. Look at the changes added to line no 7 and 8. We have included both the car_frame.svg and door.svg in our container file(car_assemble.svg).
$ git diff
$ git diff

As you can see lines 7 and 8 are added in car_assemble.svg, shown in the green(changes added) color.

Let's add all changes in our staging area using the “git add ”command.

$ git add car_assemble.svg door.svg
Adding “door.svg” to Staging Area form Working Directory using “git add

You can run “git status” to confirm the changes added to the staging area.

$ git status
$ git status

If you want to see how our car looks like now, you can run the following command.

$ python3 car_assembler.py 

This will create a new file “final_car.svg”, simply copy-paste the file contents to www.svgviewer.dev (might need to zoom the preview). If you run “git status ”again you will find “final_car.svg” as an untracked file. Since this is an output file and can be generated by executing “car_assembler.py”, there is no need to track this file in our repository. The output file should look like this …

  • Finally, create a new snapshot(commit) of the project by running “git commit”.
$ git commit -m 'V1: Create car frame with door'
$ git commit -m ‘V1: Create car frame with door’
Storing “Version 1” of car project in Repository using “git commit
  • You can run “git log” to see all the versions of your car stored permanently in our repository. Also as we mentioned in our analogy chapter, git marks this version as active. More specifically git has a pointer HEAD that points to the active version. As you can see below, HEAD is pointing to the last version(commit) in our repository.
$ git log
$ git log

Day 2

  • Let us add wheels to our car. Create a new file “wheels.svg” in the svg-car folder
svg-car
├── car_assembler.py
├── car_assemble.svg
├── car_frame.svg
├── door.svg
├── final_car.svg
└── wheels.svg (new file added)
0 directories, 6 files
New file “wheels.svg” created in Working Directory

As you can observe we just created wheels.svg file but not linked with our car, therefore we need to include this file in our car_assemble.svg so that our car_assembler.py can create a car with wheels. Let’s modify our car_assemble.svg

Notice on line number 9 <include file=”wheels.svg” /> is added. You can run the “git status” to see “wheels.svg” is under untracked files as it's a newly created file. You can also run the “git diff” to see changes to existing tracked files.

$ git status
$ git status
$ git diff
$ git diff

As in our analogy, let us say we also wish to add a spare tire before we stage our changes. Create a new file “spare_tyre.svg” and modify “car_assemble.svg” to look as below

New file “spare_tyre.svg” created in Working Directory

Now stage all the modified files to the staging area so that we can store version 2 of our application.

$ git add wheels.svg spare_tyre.svg car_assemble.svg
Adding “door.svg”, “spare_tyre.svg”, etc to Staging Area form Working Directory using “git add

Finally, we can create a new snapshot and store the version of the car in our repository. We will use the “git commit” command

$ git commit -m 'V2: Wheels and spare tire added'
$ git commit -m ‘V2: Wheels and spare tire added’
Storing “Version 2” of car project in Repository using “git commit

You can see all versions currently in our repository by using the “git log” command

$ git log
$ git log

To view how our car looks as of version 2, you can re-execute car_assembler.py and copy-paste the contents of “final_car.svg” to www.svgviewer.dev

$ python3 car_assembler.py

After executing the python script, “final_car.svg” should be like …

Day 3

As you might recall, initially the client asked Ram to paint his car yellow. In the same way, let's quickly paint our car yellow. If you look closely in “car_frame.svg”, on line number 4, the <path> element is using an attribute fill, lets change the value of this attribute to yellow. Your car_frame.svg should look like this …

If you do “git diff” now, you can see that line number 4 is changed such that the value of attribute fill of <path> element is changed from fill=“rgb(196,195,187)” to fill=“yellow”. Quickly add the changes to the staging area …

$ git diff
$ git diff
$ git add car_frame.svg

And commit

$ git commit -m 'V3: Paint car in yellow'
$ git commit -m ‘V3: Paint car in yellow’
Storing “Version 3” of car project in Repository using “git commit

Once again if you wish to see the car, execute car_assembler.py and copy-paste the content of final_car.svg to www.svgviewer.dev

$ python3 car_assembler.py

After executing the python script, “final_car.svg” should be like …

Day 4

Let's mimic the situation when the client asked Ram to change the color of the car from “yellow” to “red”. If this project wasn’t tracked with Git, we would have to recreate everything from scratch. But since we have saved each version of our project in Git’s repository, we can checkout(bring) Version 2 of the car from the repository to the working directory. We choose Version 2 because it represents an unpainted car. But first, let us see all of our car versions in the repository.

$ git log
$ git log

Let's checkout(bring) version 2 using the “git checkout” command. You need to tell the commit ID of Version 2 in the git checkout command. You can find the commit ID from the git log’s output as it is shown in the above screenshot. Please keep in mind that your commit ID can be different from mine. Let say my commit ID for version 2 is “XYZABCXYZ”

$ git checkout XYZABCXYZ # replace XYZABCXYZ by your commid ID of V2
checkout(bring) “Version 2” from Repository to Working Directory through Staging Area
$ git checkout XYZABCXYZ

You get a very lengthy output. Git is warning you that “You are in ‘detached HEAD’ state.” In very simple terms, detached HEAD means you have checked out a snapshot(commit) that doesn’t have any branch(pointer) pointing to it. Git branching is another Git hot feature that we will look into in detail in the next chapter. But for now, we need to create a branch(pointer) to point to the current commit which we have checked out. You need to give a name to it, branch names usually represent the work we are about to do on the checkout out snapshot. Let's create a branch(pointer) with the name red_car.

$ git branch red_car  # Creates a new branch(pointer) pointing to XYZABCXYZ i.e commit checked out in working directory

One last thing, you also need to switch to this new branch before you can create new snapshots(commits) with your changes. You can use the new git command “git switch”. Earlier(even now, most people still use) switching branches was done by “git checkout”.

$ git switch red_car 
OR
$ git checkout red_car # I am used to this command
$ git checkout red_car

As you can see, we don't see any “detached HEAD” message. We are good to go. Don’t worry, if you didn’t understand, the branching concept. I will explain it in more detail in upcoming chapters. For now, let's quickly wrap up our requirement of painting the car yellow. But before that, you can execute car_assembler.py and copy-paste “final_car.svg” on www.svgviewer.dev, the contents of final_car.svg will look like …

$ python3 car_assembler.py

You can verify, that we have time-traveled back to Version 2 of our car project. We can paint our car red, in the same way as we painted our car yellow on Day 3. Modify fill attribute of <path> in car_frame.svg to yellow color as below.

Similarly, if you do “git diff” now, you can see that line number 4 is changed such that the value of attribute fill of <path> element is changed from fill=“rgb(196,195,187)” to fill=“red”. Quickly add the changes to the staging area …

$ git diff
$ git diff
$ git add car_frame.svg

And commit,

$ git commit -m 'V4: Paint car in red'
$ git commit -m ‘V4: Paint car in red’
Storing “Version 3” of car project in Repository using “git commit

Once again if you wish to see the car, execute car_assembler.py and copy-paste the contents of file “final_car.svg” to www.svgviewer.dev

$ python3 car_assembler.py

The contents of final_car.svg should look like …

If you run the “git log” command, we can see that we have all versions/snapshots/commits in our repository. Since we have multiple lines of development, we need to pass the “all” parameter to the log command.

$ git log --all
$ git log — all

Running “log” by adding the “graph” parameter, shows how our project diverged from Version 2. On one line of development, pointed by ‘master’ branch we have a version of car project which was painted in yellow, on the other hand, another line of development, pointed by ‘red_car’ branch we have a version of car project which is painted in red

$  git log --all --oneline --graph
$ git log — all — oneline — graph

In this way, we learned how to operate Git. We learned how to use the three sections of Git through an analogy and also mimic all scenarios through code. That’s all from my side for this chapter, hope you found this and the preceding chapter useful. I will catch you soon when we discuss other git features.

In the next chapter, we will learn about the general pattern of using Git in day-to-day life. Don't worry it's going to be a short one.

--

--

Suryaa Jha
Suryaa Jha’s Blog

Software Engineer → Fitness Freak → Writer → Reader → Spiritual → Experiencing my childhood