Skip to main content

Git - Distributed version control

·11 mins
Recommended basics: Articles you should know

To get the full picture of this article, you should know about this topics:

(optional)
(optional)
(optional)

PHP Hypertext Processor

Learn how to build dynamic web applications with PHP. From generating dynamic HTML to serving API requests and running background processes, PHP offers an easy entry point into backend development. Perfect for junior developers, system administrators, and self-hosters.
(optional)

Node.js - JavaScript in Server Applications

Learn how to use Node.js to run JavaScript on the server side, from basic CLI applications to serving dynamic websites. Perfect for developers, sysadmins, and self-hosters.

You may also want to use the content map to find interesting articles that play into this one.


With Git you can keep track of changed files. You can also “save” a file in it’s current state and go back to that state later, if needed. Also you can compare different states of files or even folders. That’s why Git mainly is used for version control.

Do not confuse Git and GitHub, it’s not the same.

Git works fully offline, on your computer, without needing a complex setup. Git is a command line tool but there’s many public applications that wrap around git so you can have a graphical interface as well. This article will focus on the very basic understanding of it, using simple language and examples. I will use the CLI, since I want to show the core of git, not any tool specific use-cases.

Git comes with features to collaborate with other on the same folder or file. That’s why there’s many public solutions (like GitHub) that are used by teams to cover extended use-cases. This article is about basics of Git. Other topics related to it are covered in other/future articles. Check out the overview to follow along.

Receive high-quality, ad-free updates on software development. Sign up for our free newsletter today!

If you want to follow this article, please install git on your computer.

Git is stupid, it just copies files #

To understand Git it can help to understand, that good things can be achieved if the basic setup is solid / correct. Reading about a tool that version controls your files and make them shareable and decentrally comparable without a crazy complex setup sounds magical, right? So let’s put this into perspective: If you “save” your file / folder state, Git will just copy the files along with some information which you provide during “save”.

It cannot be more easy: Git just copies your files with some additional information.

From there, Git offers many more very important features, like file compares. But when it comes to your files, Git just copies and stores the whole file per each state.

How to use Git? #

Now let’s see how you can do basic / common actions with Git.

Configure Git… #

There’s two configurations that just make sense to configure in Git globally: Your name and your E-Mail address. After installing Git, run this two commands:

1
2
git config --global user.name "My Name"
git config --global user.email "my@nice.email"

Git will use this information later (see below).

How to activate Git? #

You can use Git in any folder. Since this article focus on the command line, just navigate (cd) into the particular folder and run git init:

> git init
Initialized empty Git repository in /Users/oliver/Downloads/git-test/.git/

Now this folder is a “Git repository”, you can use the git command here or in any subfolder. This means, on your computer, you can have other folders working as another “Git repository”. You can have as many as you like, there’s no limit.

As you can see in this message, git init will create a new folder called .git. This folder is used by Git to function, just ignore that folder, you’ll very likely not deal with it.

How to check the current status? #

You can check the current “status” at any time. Simply use git status:

> git status
On branch main

No commits yet

nothing to commit (create/copy files and use "git add" to track)

Since the folder still is empty, the status right now says “there’s nothing to do”. There’s a few words here, that probably sound unfamiliar: branch, main, commit, track. Just follow along, you’ll understand them a little later.

How to add a file to Git? #

OK let’s create a file now. I’ll call mine hello.txt and write hello world to it. After doing so, let’s check the status again:

> git status
On branch main

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	hello.txt

nothing added to commit but untracked files present (use "git add" to track)

Now you can see, that Git recognized the new file and informs us, that this new file currently is untracked. Before Git keeps track / monitors file changes, you need to tell it to do so, even if the file is within a Git repository.

You now have two options: Add this single file (using git add hello.txt) or add all untracked files (using git add .). Since you just have one file, the result will be the same. Add the file and check the status again:

> git status
On branch main

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
	new file:   hello.txt

Again there’s a new word unstage, I’ll not cover this topic in this article, since for newcomers it’s an edge-case.

How to “save” the current state? #

As you can see, Git now knows that there’s a new file. If you change the files content, still it’s a new file for Git. This is because you haven’t yet “saved” the current state. Git doesn’t do that automatically, it waits for us to decide that the current state is good to be “saved”.

Whatever you “save” in Git will be stored long term. This state then get’s a unique identifier. To “save” somthing, you can tell Git to commit the current state. While doing so, you can provide a commit message that should summarize all changes you have done. For the start this message doesn’t matter. This information is just for you. Git doesn’t bother. Mid-term I’d recommend to get used to writing a good commit message. I probably will write a whole article on it.

Now go ahead and use git commit to store your current state. You can define the message using -m argument. I’ll go with “create hello.txt with demo content” for my commit message. My command looks like this:

> git commit -m "create hello.txt with demo content"
[main (root-commit) 0aebd08] create hello.txt with demo content
 1 file changed, 1 insertion(+)
 create mode 100644 hello.txt

Good job, you have just created your first commit in Git. Here’s a catch: My commit has 0aebd08 as an identifier, your’s very likely not, even if you have picked the same file name and content. That is by purpose. This article is about basics of Git. Other topics (like this identifier) related to is are covered in other/future articles. Check out the overview to follow along.

Receive high-quality, ad-free updates on software development. Sign up for our free newsletter today!

Now, let’s check the status again:

> git status
On branch main
nothing to commit, working tree clean

Well done: All your files are tracked and saved in Git.

How to see latest changes in Git repositories? #

Imagine you’ll continue to use this Git repository not just today, but for multiple years. Over time you’ll add new files, change existing, maybe even delete old ones. At some point, you’ll want to look back: What did you do in the last time?

As you learned today, you can tell Git what files to keep track of and you tell Git when to store a particular state of your folder, along with a message. Git will create commits for you, while every commit knows it’s previous one. This enables Git to show a history of changes: The git log.

> git log
commit 0aebd08b670442b829cc7073e65113b081878e12 (HEAD -> main)
Author: Oliver Lippert <info@reliable.codes>
Date:   Sun Jul 20 12:29:02 2025 +0200

    create hello.txt with demo content
(END)

In my case, it’s one entry only. However, you can see that this log is a high-level view of the recent activity:

  • You can see the full identifier of the commit (0aebd08b670442b829cc7073e65113b081878e12 in this case)
  • You can see who created this commit (only relevant if you work in teams)
  • You can see when this commit was created
  • And you can see the commit message

How to see a particular change? #

To see what a particular commit had changed, you can ask use git show to see it’s changes:

> git show 0aebd08b670442b829cc7073e65113b081878e12
commit 0aebd08b670442b829cc7073e65113b081878e12 (HEAD -> main)
Author: Oliver Lippert <info@reliable.codes>
Date:   Sun Jul 20 12:29:02 2025 +0200

    create hello.txt with demo content

diff --git a/hello.txt b/hello.txt
new file mode 100644
index 0000000..3b18e51
--- /dev/null
+++ b/hello.txt
@@ -0,0 +1 @@
+hello world
(END)

This is very cryptic. It starts with a similar output like git log and then shows the changes. In this case, we have a new file created with the single line hello world.

How to go back to a particular change? #

Change your hello.txt (I rewrite it to “hello earth”), commit your changes and check your logs:

> echo 'hello earth' > hello.txt

> git add .

> git commit -m "changed target audience"
[main a5275bb] changed target audience
 1 file changed, 1 insertion(+), 1 deletion(-)
 
> git log
commit a5275bb59e58fd0e9f183874c8cadaa75d8e6538 (HEAD -> main)
Author: Oliver Lippert <info@reliable.codes>
Date:   Sun Jul 20 13:44:26 2025 +0200

    changed target audience

commit 0aebd08b670442b829cc7073e65113b081878e12
Author: Oliver Lippert <info@reliable.codes>
Date:   Sun Jul 20 12:29:02 2025 +0200

    create hello.txt with demo content
(END)

It can happen, that you need to go back to a particular commit. You can do that by checking out that identifier:

> git checkout 0aebd08b670442b829cc7073e65113b081878e12

> cat hello.txt
hello world

Now your whole folder is back at the state of the previous commit.

Important: This doesn’t delete any commit. You can again go back to your second change with using git checkout again.

Conclusion: Git is crazy complicated and hard #

If you’re a newcomer and made it until here: Congratulation. I must agree, that using Git solely on the command line is not very easy. But you’ve made it through the hard part, just follow along to see how all this can be done way more easy.

Let’s quickly conclude / summarize the basic part’s of Git:

  • You can create a Git repository in any folder.
  • In a Git repository, you need to tell Git what to keep track of.
  • Once Git tracks your files, you need to tell Git when to save a particular set of changes.
  • For every change Git will track your name, your email, the current date, a message and a unique identifier.
  • Git will chain together the current change with the previous, which makes up the history.

How to really use Git #

Git is a very famous version control system. Not the only one, but widely used. That’s why many tools integrated Git for you as a user. reliable.codes is mainly about coding, that’s why I use Git to version my source code of my projects (e.g. PHP, JavaScript / NodeJS and more). I rarely use Git on the command line, in most cases I use the Git integration of my IDE.

Good to know:

If you work with source code, using Git in your IDE really can bring you to the next level. As long as you understand the basic use-cases of Git, you can speed up your work significantly and create a safe environment for yourself, allowing much space for failure without loosing any previous work.

Git behind the scenes (being nerdy about Git) #

If you felt triggered by my initial statement “Git is stupid”, you may want to read this section. Let me clarify: I like stupid things. Now, let’s get nerdy about Git commits:

What actually is a commit?
A commit is a file within the .git folder.

Don’t believe me? Let’s validate that on our commit a5275bb59e58fd0e9f183874c8cadaa75d8e6538:

> cat .git/objects/a5/275bb59e58fd0e9f183874c8cadaa75d8e6538
x��Aj1
      {�+t-�׶�PJ�[N���u�﷤?�q3Lٮ�e���2��UJ���Zc��LQ��KCNAKS"��۵�:�rEɉ1��ϥ0�d)M����;������ܭ�q�w�޷'^����a���	�$%8�Gt�9:~�'\9�z�
C���.�s?� P�%

Ok this is hard to read, let’s use Git to fix this:

> git cat-file -p a5275bb59e58fd0e9f183874c8cadaa75d8e6538
tree 9d8c5ad59dfff7874fea08397cf0764acfa112b4
parent 0aebd08b670442b829cc7073e65113b081878e12
author Oliver Lippert <info@reliable.codes> 1753011866 +0200
committer Oliver Lippert <info@reliable.codes> 1753011866 +0200

changed target audience

As you can see, this identifier references basically a text file. This text file has some structured information:

What is a git tree?
A Git tree is comparable to a file tree. It’s another text file telling us about the file structure in the repository at the time of the commit.
What is a git parent?
Git uses the parent to store the identifier of the previous commit.
What is a git author?
It’s the person that did the changes in this commit.
What is a git committer?
It’s the person that create the commit.
How can author and committer be different in git?
When using git commit you can add --author attribute to tell Git about the real author, even if you create the commit.

Let’s now see what’s behind a git tree:

> git cat-file -p 9d8c5ad59dfff7874fea08397cf0764acfa112b4
100644 blob f90ff54f82c585181e1c4f321d415daa5badc351	hello.txt

Again, the identifier of the tree is just another file what we can lookup with Git. It will point to even more identifiers that either are another tree or a file. Let’s now lookup the single entry that is existing in this Git repository right now:

> git cat-file -p f90ff54f82c585181e1c4f321d415daa5badc351
hello earth
Receive high-quality, ad-free updates on software development. Sign up for our free newsletter today!

If you put all this together you end up with this structure

  • A git repository has multiple commits.
  • A commit has some meta data and one tree.
  • A tree can point to other trees.
  • A tree points to blobs.
  • blobs at the end store file content (only).
flowchart TD repo["Git repository"] commit tree blob content["file content"] repo --> commit commit --> tree tree --> tree tree --> blob blob --> content

I guess this makes sense. It is the most simple approach while being bullet-proof against error’s: Don’t store changes, but full files / folders.

This “stupid” solution enables Git to build complex features on top, without risking loosing / messing up any data.

Oliver Lippert
Author
Oliver Lippert
I pay attention to the details. I think deeply about the purpose of functions, the clarity of variable names, and the importance of commit messages. Long-term thinking is crucial. Writing code is straightforward, but projects become more challenging as they grow. With over 15 years of experience, I’ve gained insights that I apply in coding, code reviews and business discussions.