Now that we have git installed locally, we can start playing around with some of the basic commands. The first thing you want to do is initialise a git repository. As far as I know, there are two ways to accomplish that:
- Clone an existing Repo
- Initialise an empty Repo
Cloning an existing repo will pull the entire git history of the project from a remote server unto your local machine. Usually, you’ll do this when you wish to contribute to an existing project. The project will have a clone url (either Http or SSH).
So, to clone an existing project like EventBus on your local machine. Simply run command:
$ git clone https://github.com/greenrobot/EventBus.git
This creates a folder on your box named EventBus. If you wish to clone the project into a different folder named event_bus_local for instance, then run:
$ git clone https://github.com/greenrobot/EventBus.git event_bus_local
Asides cloning, you can create a git repository using the
git init command. Run this within the project folder you intend to initialise. This will create an empty git repository.
$ cd full/path/to/project/folder $ git init
Tracking Status, Adding Files and Committing
Through the lifecycle of any project, developers will add files, modify existing files, delete redundant files etc. Git provides a number of features for adding files, tracking updates, committing changes. Before we dive into these features, we need to be aware of the states in which git repository files can exist. Usually there’s about 4 states:
- New / Untracked State: implying that the file was just created and is not being tracked by git.
- Modified State: in this state, the file is already tracked by git, but changes have been made since the last commit.
- Staged State: the current state of the file has been captured so it will be saved in the next commit.
- Committed State: the staged state of the file has been saved into the git repo.
Let’s run a few commands to watch the transitions between states.
$ mkdir test-repo && cd $_ $ git init
What we have done is create a new directory called
test-repo and navigate into it. The
$_ is a placeholder for the previous command argument to avoid retyping it. Then we run
git init command inside the empty repo to initialise it.
If you run
ls -a within your test-repo, you should see a .git folder. This is the folder that makes your project a git repo; it stores project metadata, branch information, commit history, and a bunch of other stuff required for version control.
In order to check the current state of the git repository, we run
git status. This should give a similar output to the one below:
$ git status On branch master No commits yet nothing to commit (create/copy files and use "git add" to track)
Git automatically creates a master branch on an empty repository. If you’re using git to manage a software project, the master branch would usually refer to the working version of the code that is deployed on the live environment. Git uses branches to concurrently maintain multiple versions of a codebase. I’ll still get into branches later. But for now, notice that the command echoed out ‘No commits yet’. This means that we have not made any commits and git is waiting for us to start adding files. Now let’s add a dummy file.
$ echo 'Hello World' > hello.txt
This creates a hello.txt file in the project folder with contents Hello World. If you run
git status again, you’ll see a different output.
$ git status On branch master No commits yet Untracked files: (use "git add <file>..." to include in what will be committed) hello.txt
Our hello.txt file has been recognised as an untracked file. Git has no history of it and so we need to commit it. Before committing changes, the changes must be staged.
You stage changes with the
git add. The git add command takes an argument which is the file you wish to stage. We could just type
git add hello.txt, or more tersely, run
git add . so that all changes are added. Try running
git status again.
$ git add . $ git status On branch master No commits yet Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: hello.txt
As you can see, git recognises hello.txt as a new file that is ready to be committed. Now let’s commit our new file that has been staged.
$ git commit -m "Created hello.txt"
This will simply save the staged changes and attach a commit message. Now that we have committed, our working directory is clean.
The best time to commit is when you have accomplished a unit of work and intend to save a snapshot of your project files.
There’s one more file state we haven’t touched on yet. Which is the modified state. When a file is in the modified state, it means the file has been previously committed to the git repository, but has undergone updates since its last commit. We’ll now make some changes to our committed hello.txt file.
$ echo 'Hello World' >> hello.txt
We have appended a new line to the hello.txt file. Now if you run
git status again, you should see the output below.
$ git status On branch master 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: hello.txt no changes added to commit (use "git add" and/or "git commit -a")
Git has recognised that hello.txt has changed since our last commit. To view the exact change that happened, run a
git diff command.
$ git diff hello.txt diff --git a/hello.txt b/hello.txt index 557db03..8254f87 100644 --- a/hello.txt +++ b/hello.txt @@ -1 +1,2 @@ Hello World +Hello World
Notice at the end of the output, we have a +Hello World. This is an indication a new line was added to the hello.txt file. Of course, a minus sign will signify a line that was removed. We can now commit the new changes to hello.txt.
$ git commit -am "Updated hello.txt"
Since hello.txt has already been tracked on git, we don’t have to explicitly type
git add. We can use a
-am switch with the commit command and git will add and commit at once.
So far, we have been able to log two commits on our new git repository. In order to view the history of commits on a repository, we use the
git log command. This will output all the commits on the repo in reverse chronological order (meaning most recent first).
$ git log commit 8e7c6555efa7bf3cfb7a2ad0f566a52f883d4cf0 (HEAD -> master) Author: Julian Dumebi Duru <firstname.lastname@example.org> Date: Sun May 24 21:43:55 2020 +0100 Updated hello.txt commit f8437c70ec701b3e74fc586c6a088f09795bfc15 Author: Julian Dumebi Duru <email@example.com> Date: Sun May 24 21:12:09 2020 +0100 Created hello.txt
We have our two commits listed out with their commit messages. You can always restrict the log output to the most recent n commits by using the command
git log -n, where n is a non-negative integer.
$ git log -1 commit 8e7c6555efa7bf3cfb7a2ad0f566a52f883d4cf0 (HEAD -> master) Author: Julian Dumebi Duru <firstname.lastname@example.org> Date: Sun May 24 21:43:55 2020 +0100 Updated hello.txt
The weird looking string ‘8e7c6555efa7bf3cfb7a2ad0f566a52f883d4cf0’ is known as the commit hash. In computer science, hashing is used to derive a string value by applying some mathematical calculation on an input. So in many ways, the hash is mathematically related to the current content of our repository. The log command also outputs the author of the commit as well as the date.