DEV Community

Glitchbyte
Glitchbyte

Posted on

Learn Git in 10 Minutes

Image of Git

Every developer needs to learn Git. It's how we version control our code. By using git, we can step through every change we've ever made, forward and backward in time.

This is crucial when mistakes are made. Instead of having to rewrite everything manually, you can simply revert your changes or hop to an earlier commit.

It's only going to take us 10 minutes to cover 90% of git's usage.

Installing Git

First, we need to make sure git is installed on our system.

Windows:

# Using winget in a powershell window
winget install git-all

# Chocolatey
chocolatey install git-all
Enter fullscreen mode Exit fullscreen mode

MacOS:

# Using Homebrew
brew install git-all
Enter fullscreen mode Exit fullscreen mode

Linux:

// Ubuntu/Debian
apt install git-all

// Arch
pacman -Sy git-all

// CentOS/Fedora
yum install git-all
Enter fullscreen mode Exit fullscreen mode

You can find more info about installing git here.

Starting a git repo

We'll start by creating a new project. In my case, Ill be starting a new repo for a NES emulator I'll be writing in C. If you dont know where to store your projects, create a projects directory wherever you know you'll find it.

Start your own project and name it whatever you'd like.

I'll be naming my project DrNES and moving into the directory.

# Init project
mkdir -p DrNES

# Change dir into DrNES
cd DrNES
Enter fullscreen mode Exit fullscreen mode

Now that we have our project directory created and we're inside of it, we can start a git repo.

# Start a git repo
git init

# Check for .git directory
ls -al .git
Enter fullscreen mode Exit fullscreen mode

This makes the project directory we created into a git repo.

The Basics of Git

From here, we can create a few files for git to find.

In my case, Im going to create a source src folder with main.c in it and a README.md.

This is going to lay the base file structure for my repo.

# Create README
touch README.md

# Make src folder
mkdir -p src

# Add main.c to src
touch src/main.c
Enter fullscreen mode Exit fullscreen mode

For now these will be empty files.

Git Status

If we do a git status, we will see what git is currently tracking for changes.

git status

# Output
On branch main

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        README.md
        src/

nothing added to commit but untracked files present (use "git add" to track)
Enter fullscreen mode Exit fullscreen mode

Git Add

In order for git to start tracking these files, we need to use git add. This command can be used to add individual files or all files in the directory.

# Add one file to track
git add README.md

# Add everything in repo to track
# The '.' means to add everything in this directory
git add .

# Output
On branch main

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   README.md
        new file:   src/main.c
Enter fullscreen mode Exit fullscreen mode

In my case, I use git add . to make git track everything in my directory.

Git Commit

Once we've added our files to track, we need to commit to the changes. We use the git commit command to do this.

# Commit our changes
git commit -m "init commit"

# Output
[main (root-commit) 1b13406] init commit
 2 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 README.md
 create mode 100644 src/main.c
Enter fullscreen mode Exit fullscreen mode

Whenever we commit to our changes, we have to add a message to the commit for the git log. If we just did git commit, it would drop us into vim or whatever other editor you have set as the default.

To bypass being dropped into vim, we use git commit -m "My message here".

Git Push

Now we can use git push to push our changes to a remote repo.

To that, however, we need a remote repo, otherwise we will get the following error:

# Push git changes
git push

# Output
fatal: No configured push destination.
Either specify the URL from the command-line or configure a remote repository using

    git remote add <name> <url>

and then push using the remote name

    git push <name>
Enter fullscreen mode Exit fullscreen mode

Setting up a Github

At the moment, we dont have a remote repo to push our changes to.

Thats where something like Github or Gitlab come in.

These are remote servers that allow us to host and share our code with the world, provided by those two companies.

For my repo, Ill be using Github. I already have an account, but it should be simple to sign up for one.

Once you do, navigate to the "Repositories" tab and click "New" in top right hand corner.

Create a new repo photo

That will take you to a "Create new repository" page.

Options to fill out for creating new repo on Github

On this page, we want to:

  • Give the repo a name
  • Add a description
  • Set repo to public or private (your choice)
  • Click "Create repository"

We do not want to initialize the repo with a README, because we already have a README. As of right now, I dont want to add a .gitignore or license. I want this repo to be blank.

If we didnt already have a repo to push to Github, I would have added the README, added .gitignore, and selected a license.

After we've created our Github repo, its going to ask whether we want to "create a new repo" or "push an existing one".

We're doing the latter, so we will follow those directions.

Pushing an existing repo to Github

We do this in our terminal where our project repo is.

Lets look at each command:

  • git remote add origin github.com/User/myrepo.git tells our local git repo where to find our remote git repo.
  • git branch -M main creates a main branch in our local repo. This main branch should be protected, more on that later.
  • git push -u origin main allows us to push our changes to the upstream repo main branch -u origin main

Our git push may error out.

This is because we have to define an authentication method with Github.

We have two options:

Once we have that situated, we can try our git push again.

# Push changes to Github
git push -u origin main

# Output
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 10 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (4/4), 301 bytes | 301.00 KiB/s, done.
Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
To https://github.com/0xGlitchbyte/DrNES.git
 * [new branch]      master -> master
branch 'master' set up to track 'origin/master'.
Enter fullscreen mode Exit fullscreen mode

If we go back to Github, we should see something like this:

What the repo looks like after being pushed to Github

That's how we know our repo has been successfully pushed.

Best Practices for Git

Now that we have successfully added, committed, and pushed changes to Github, we want to start developing.

Remember I said we want to protect main?

Best practice is to develop on a separate branch besides main so we dont push changes that will mess up the main branch.

So we will create a dev branch.

# Create dev branch
git branch dev

# Switch to dev branch
git switch dev

# Push changes from local dev to remote dev
git push -u origin dev

# Output
Enumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Delta compression using up to 10 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 410 bytes | 410.00 KiB/s, done.
Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
remote:
remote: Create a pull request for 'dev' on GitHub by visiting:
remote:      https://github.com/0xGlitchbyte/DrNES/pull/new/dev
remote:
To https://github.com/0xGlitchbyte/DrNES.git
 * [new branch]      dev -> dev
branch 'dev' set up to track 'origin/dev'.
Enter fullscreen mode Exit fullscreen mode

Now when we git add and git commit on this branch, it wont affect our main branch.

Since main is our source of truth branch, where all production ready code gets push to, we need to do a pull request in Github to merge dev into main.

Once all changes have been approved and the pull request has been merged into main, other people can use git pull to get the latest changes.

You can also setup a .gitignore file in your directory. This file will allow you to exclude files and file types to be excluded from being added for staging commits.

Different Git commands to be aware of

Git Clone

If you find a repo you come across that you'd like to contribute to, you can use git clone to pull it from a remote server (i.e. Github) to your local machine.

# Cloning the DrNES repo with HTTPS
git clone https://github.com/0xGlitchbyte/DrNES.git

# Cloning with SSH and changing the folder name
git clone git@github.com:0xGlitchbyte/DrNES.git dr_nes
Enter fullscreen mode Exit fullscreen mode

Git Fetch

git fetch updates your remote-tracking branches under refs/remotes/<remote>/. This operation is safe to run at any time since it never changes any of your local branches under refs/heads. This is used instead of pull when you just want to update the remote references.

git fetch 
Enter fullscreen mode Exit fullscreen mode

Git Remove

git rm will remove files from your git repo and filesystem, if you specify it.

# Remove files from cache
git rm --cache
Enter fullscreen mode Exit fullscreen mode

Git Log

git log allows us to see a log of our commits. This is useful when we'd like to view changes passed commits may have done, or to switch to a different commit.

git log

# Output
commit 124d9e29ac5ddac77c911c83c2100ca54f9d04d0 (HEAD -> dev, origin/dev)
Author: 0xGlitchbyte <49317853+0xGlitchbyte@users.noreply.github.com>
Date:   Sun Nov 5 15:40:47 2023 -0500

    added hello world

commit 1b134069e7dd4469b3439b02b82b2a0d9db4e535 (origin/master, master)
Author: 0xGlitchbyte <49317853+0xGlitchbyte@users.noreply.github.com>
Date:   Sun Nov 5 14:22:22 2023 -0500

    init commit
Enter fullscreen mode Exit fullscreen mode

Git Show

git show shows us the details and metadata of our last commit

git show

# Output
commit 124d9e29ac5ddac77c911c83c2100ca54f9d04d0 (HEAD -> dev, origin/dev)
Author: 0xGlitchbyte <49317853+0xGlitchbyte@users.noreply.github.com>
Date:   Sun Nov 5 15:40:47 2023 -0500

    added hello world

diff --git a/src/main.c b/src/main.c
index e69de29..18e3a28 100644
--- a/src/main.c
+++ b/src/main.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int main() {
+  printf("Hello World!");
+  return 0;
+}
(END)
Enter fullscreen mode Exit fullscreen mode

Git Diff

git diff allows us to view the difference between two commits.

# Will compare last commit to current changes
git diff

# Output
diff --git a/src/main.c b/src/main.c
index 18e3a28..139eeca 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,6 +1,9 @@
 #include <stdio.h>

 int main() {
+  // I have added some comments here
   printf("Hello World!");
+
+  // And here!
   return 0;
 }
(END)
Enter fullscreen mode Exit fullscreen mode

Git Stash

git stash allows us to stash away any changes we have made in our current branch. This is useful when we want to keep our changes, but go back to a clean working directory to try something else.

git stash

# Output
Saved working directory and index state WIP on dev: 124d9e2 added hello world
Enter fullscreen mode Exit fullscreen mode

Git Reset

git reset will reset our changes back to a clean working directory without saving them.

git reset
Enter fullscreen mode Exit fullscreen mode

Git Branch

git branch will show a list of all current branches in the git repo.

git branch

# Output
* dev
  master
(END)
Enter fullscreen mode Exit fullscreen mode

Git Merge

git merge allows you to join two development histories together. You use git merge when you want to reconcile other branches into main, for example. When you merge histories, its important to note you will have to reconcile any conflicting differences between the two.

# Merge dev into master with a message
git merge -m "My message here" dev
Enter fullscreen mode Exit fullscreen mode

Git Rebase

git rebase allows you to easily change a series of commits, modifying the history of your repository. You can reorder, edit, or squash commits together. You may not want to merge back into main just yet, so you can pull a version, rebase, and continue development from the point you rebased.

git switch dev
git rebase main
Enter fullscreen mode Exit fullscreen mode

Git Restore

git restore allows you to restore or discard unstaged files in your git repo.

# Restore a file
git restore filename.txt
Enter fullscreen mode Exit fullscreen mode

Git -h

git -h is shorthand for git --help. It will list all the options you can use with git. man git will give you the manual page on linux for git.

git -h

usage: git [-v | --version] [-h | --help] [-C <path>] [-c <name>=<value>]
           [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
           [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--bare]
           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
           [--super-prefix=<path>] [--config-env=<name>=<envvar>]
           <command> [<args>]

These are common Git commands used in various situations:

start a working area (see also: git help tutorial)
   clone     Clone a repository into a new directory
   init      Create an empty Git repository or reinitialize an existing one

work on the current change (see also: git help everyday)
   add       Add file contents to the index
   mv        Move or rename a file, a directory, or a symlink
   restore   Restore working tree files
   rm        Remove files from the working tree and from the index

examine the history and state (see also: git help revisions)
   bisect    Use binary search to find the commit that introduced a bug
   diff      Show changes between commits, commit and working tree, etc
   grep      Print lines matching a pattern
   log       Show commit logs
   show      Show various types of objects
   status    Show the working tree status

grow, mark and tweak your common history
   branch    List, create, or delete branches
   commit    Record changes to the repository
   merge     Join two or more development histories together
   rebase    Reapply commits on top of another base tip
   reset     Reset current HEAD to the specified state
   switch    Switch branches
   tag       Create, list, delete or verify a tag object signed with GPG

collaborate (see also: git help workflows)
   fetch     Download objects and refs from another repository
   pull      Fetch from and integrate with another repository or a local branch
   push      Update remote refs along with associated objects

'git help -a' and 'git help -g' list available subcommands and some
concept guides. See 'git help <command>' or 'git help <concept>'
to read about a specific subcommand or concept.
See 'git help git' for an overview of the system.
Enter fullscreen mode Exit fullscreen mode

Final Thoughts

Git is an important tool to learn, but its not difficult to learn.

The majority of the time, youll be using these commands:

  • git add
  • git commit -m
  • git push
  • git pull
  • git clone

The rest are good to learn, but will be used on a case by case basis.

You can use git on any files you'd like to version control, from code to text documents.

The more you practice, the better youll get at it.

Top comments (0)