DEV Community

Cover image for Git for grad students (part 1)
TuanNQ
TuanNQ

Posted on • Edited on

Git for grad students (part 1)

In this series, I'll show you the basic workflow of how a team of developers use Git and Github / Gitlab to work and colab together.

If you aspire to be a developer but don't understand how all the Git, Github / Gitlab, development workflow stuff fit together and solving what problem, achieving what purpose, then this article is for you. I write this for the past me as a student years ago and for you to not have to go through all the struggle with Git I've been through.

More background on why I wrote this article

When I was in university, my professors / teachers taught me all kind of fancy theories and algorithm stuffs. From Assembly, C to OOP Java, to Database, to Network Theory,... they covered all and more. Memorize all of that? That's great, that's what a future software engineer should know.

But there was a rumor. Only when you start working at a company as an intern, that's when the real learning begin. People will pretend you know nothing, expect nothing from you and teach you every silly little stuffs.

One of that stuff is how to use Git.

If you search Google to try understanding what Git is and how to use Git, you're probably gonna be hit with a bunch of jargon and technical details that you not hope to understand. Hell one of my senior even send me an 8 hours course on Udemy on how to use Git. Damn how can you even begin to code if just understanding what tools you supposed to use would take a PhD?

Luckily that's not the case. Using a tool does not requires to know all technical details about it. It's more about knowing what problem does it solves.

So first, let's try to understand what problem we're facing. You don't want to use the wrong tool for the wrong situation.

Wrong tool for wrong place: but I already like him!

What problem are we trying to solve?

Imagine you work on a group project to create a presentation. You create a new Google Slides in your Google Drive and share it to each other. To a team of developers, the Google Slides file is equivalent to the project, and the Google Drive is equivalent to Github / Gitlab. You can imagine Github / Gitlab is the Google Drive / Dropbox for developers.

Github and Gitlab is equivalent to Google Drive

But here come the next challenge. How to prevent someone in your group accidentally change your slides?

In the Google Slides world we have no way, but luckily in the development world we can achieve that with the combination Git and Pull Request (or in Gitlab is Merge Request).

Let me explain.

To solve the accidentally changed problem, imagine each time anyone want to the edit group's slide would have to do this:

  • Create a copy of the group's Google Slides file
  • Work on that copied file
  • Ask the leader to review
  • Only when the leader agree that the changes are merged into the group's file

Make a copy to group's file

Group's leader review then merge

This is wayyy complicated and messy in the Google Slides world, but luckily it's quite simple in the development world with the help of Git. You just need to know a few basic Git command.

But first, let's understand what Git is, what does it do and what problem does it solve. For now I can foreshadow a little bit:

  • Download from Google Drive = git clone
  • Make a copy of the file = create a new branch
  • Upload to Google Drive = git push
  • Ask the leader to review the changes = create new Pull Request (Merge Request)
  • Download again to see the updated version = git pull
  • 2 people change the same slide = conflict

What is Git?

Git is a software that you can install on your computer (like Chrome, VSCode, Team Viewer,...). You can go to https://git-scm.com/ to download and click a bunch of "Yes" to install it.

So what does Git do? From a simple viewpoint of me an ordinary developer, Git does 2 things:

  • Versioning
  • Branch

What is versioning?

Do you know that you can change back to an older version of a Google Docs file? Like if someone accidentally delete something important in a Google Docs, the whole team would frantically roll back to the last Friday version hoping to see that important thing is still there?

Git offers the same thing for developers. You can create a new version of your project or rollback to old version anytime you want!

Here's a simple diagram about Git versioning:

Git version simple demonstration

Create a new version

In the Git world, if you want to make a new version of your project, it called "commit". Each version has a message. Here's the command to tell git to create a new version:

git commit -m "Your message"
Enter fullscreen mode Exit fullscreen mode

But before telling Git to create a new version, let's imagine you have to tell it which files has changed.

For example, let's say your project has one file index.js. You change to content from console.log("hi there") to console.log("hello there"). First, you will have to tell Git the file index.js has changed:

git add index.js
Enter fullscreen mode Exit fullscreen mode

Git stage file hi to hello there

Then you create a new version with the message "change from hi to hello there":

git commit -m "change from hi to hello there"
Enter fullscreen mode Exit fullscreen mode

Git commit file hi to hello there

To summary, there are 2 steps in order to create a new version of project:

  • git add
  • git commit -m

Why do we need to do the git add? Can't Git automatically figure what files has changed to create new version with those files for us? Imagine this situation.

Let's say you have 2 files index.js and main.js. But you don't want to create a new version that include main.js just yet. In that case you'd tell Git to just commit index.js but ignore main.js.

git add index.js
Enter fullscreen mode Exit fullscreen mode

Git staging ignore main.js file

then

git commit -m "change to hello there"
Enter fullscreen mode Exit fullscreen mode

Git commit main.js file

The 2 steps git add and then git commit -m is for that flexibility.

This happens a lot in the "real world": you often have to change some config files in order to run the project on your local machine. You'd tell Git to only cares about the file that you actually coding on and ignore those config files.

Git please ignore environment variables file

Let's explains a little more about all the cool terminology people are saying: "staging" and "untracked files".

There are 3 kinds of files:

  • The files you changed but not tell Git
  • The files you changed and tell Git
  • The files you already commit

3 kinds of files

When people talking about:

  • Staging area: imagine that is "Files that Git knows is changed"
  • Staging that file: git add that file
  • Untracked files: imagine that is "Files you don't tell Git that changed"

Git 3 kinds of files with terminology

To show the all files are in the staging area and all untracked files, you can use git status:

git status
Enter fullscreen mode Exit fullscreen mode

Here's an example of mine:

On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   packages/solid-project/src/App.tsx

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)   
        modified:   packages/solid-project/src/hooks/createWindowHeight.ts
Enter fullscreen mode Exit fullscreen mode

This means that I have a createWindowHeight.ts file that I've not yet tell Git about and an App.tsx file that I already tell Git (git add) but not commit yet.

Git status example explain

From now, instead of saying "tell Git about what files has changed", I'll say "staging that file". What I said about git add equals to "tell Git about what files has changed" is vastly simplify and definitely not technically correct. git add is more like "I want you, Git, to care about the changes of this file". I told you that above because I think for "beginner", "imagine" it's equal is good enough. Now equip with basic idea and terminology you can read the Pro Git book at https://git-scm.com/book/en/v2 to really understand how Git works.

View all your project's versions

After understanding how to create a new version, next, let's talk about how to view all versions of your project. To see all versions your project has, use the command:

git log
Enter fullscreen mode Exit fullscreen mode

Here's an example of my project:

commit 3f345bfcbbcbaf56f2b7a90a72fb6558a255d3df (HEAD -> master)
Author: Your Name <you@example.com>
Date:   Thu Jan 30 00:53:33 2025

    add examples

commit 67851c04de24214b25099cd5e3a128c06bd4551a
Author: Your Name <you@example.com>
Date:   Mon Dec 9 13:44:31 2024

    initial commit
Enter fullscreen mode Exit fullscreen mode

Here's a diagram to explain it:

Git log explain

My project currently has 2 versions:

  • Version 67851c04de24214b25099cd5e3a128c06bd4551a
  • Version 3f345bfcbbcbaf56f2b7a90a72fb6558a255d3df

Currently I'm at the latest version 67851c04de24214b25099cd5e3a128c06bd4551a. That's what the HEAD means.

In previous diagrams, for the sake of easy-to-understand, I tell you "version 1", "version 2", "version 3", but Git uses unique string to label each version. Instead of saying "version 1", Git says "version 67851c04de24214b25099cd5e3a128c06bd4551a".

In fact, the string Git use to label each version is so unique that you can just take 5 - 10 characters of it for Git to know which version. For example, "version 67851c", "version 3f345bfc",...

From now I'll call those unique string "version hash".

Practice a little bit

Let's practice a little bit before going to the next section. We'll use the result of this section for the next section. If you don't want to type anything yet, it's fine. I'll draw a bunch of diagrams so that you can still understand this section without having to type anything.

First, let's create a new directory. I'll call mine simple-git-tutorial.

Next, open a terminal in that directory and type:

git init
Enter fullscreen mode Exit fullscreen mode

This command is to tell Git to start versioning all files inside this directory.

Tell Git to init a folder

A little bit of extra information: when you git init in a directory, git will create a folder named ".git" inside it to store all information needed to manage that directory.

Here's an example of mine:

Git hidden folder

If you're not seeing it on Windows, you might need to go to View and then turn on Hidden items to see it!

Window show hidden directory

Next, let's add a file called index.js with the following content:

console.log("hi there");
Enter fullscreen mode Exit fullscreen mode

Now, let's create a new version of this project:

git add index.js
Enter fullscreen mode Exit fullscreen mode

Tell git to stage index.js file

then:

git commit -m "add hi there"
Enter fullscreen mode Exit fullscreen mode

Tell git to commit index.js file

To view all versions, type:

git log
Enter fullscreen mode Exit fullscreen mode

Here's an example of mine:

commit e1c439a92efef55036a54250a8fa58d8db2e7981
Author: Your Name <you@example.com>
Date:   Thu Jan 30 13:28:32 2025

    add hi there
Enter fullscreen mode Exit fullscreen mode

Let's practice again by changing the console.log in index.js file from "hi there" to "hello there":

console.log("hello there")
Enter fullscreen mode Exit fullscreen mode

Now, let's create a new version of this project:

git add index.js
Enter fullscreen mode Exit fullscreen mode

Tell Git to stage modified index.js file

then:

git commit -m "change to hello there"
Enter fullscreen mode Exit fullscreen mode

Git commit index.js change to hello there

To view all versions, type:

git log
Enter fullscreen mode Exit fullscreen mode

Here's an example of mine:

commit 56908bb558478bc61d7319b870beb459d9853ae1
Author: Your Name <you@example.com>
Date:   Thu Jan 30 13:29:56 2025

    change to hello there

commit e1c439a92efef55036a54250a8fa58d8db2e7981
Author: Your Name <you@example.com>
Date:   Thu Jan 30 13:28:32 2025

    add hi there
Enter fullscreen mode Exit fullscreen mode

Here's a diagram showing what versions we have in our small project:

Our small project so far explanation

See a previous version

Now we can create a new version and view all version, let's talk about how we can see a previous version like in Google Docs.

In order to switch to any version, use git checkout and then the version hash.

For example, if I want to see the version e1c439a92efef55036a54250a8fa58d8db2e7981, I'd use:

git checkout e1c439a92efef55036a54250a8fa58d8db2e7981
Enter fullscreen mode Exit fullscreen mode

Since Git only need 5 - 10 characters of the version hash to recognize, I could have just use this:

git checkout e1c439a
Enter fullscreen mode Exit fullscreen mode

Git checkout back to previous version

If you open index.js, you'll see the content change from:

console.log("hello there")
Enter fullscreen mode Exit fullscreen mode

back into:

console.log("hi there")
Enter fullscreen mode Exit fullscreen mode

That's great, if I want to return to the latest version, I can just plug in the latest version's hash with git checkout like so:

git checkout 56908bb5
Enter fullscreen mode Exit fullscreen mode

Our small project so far explanation

"But wait!", you said horrifyingly. In order to find the latest version hash, I have to use git log. But my git log does not print out the latest version anymore:

commit e1c439a92efef55036a54250a8fa58d8db2e7981 (HEAD -> master)
Author: Your Name <you@example.com>
Date:   Thu Jan 30 13:28:32 2025

    add hi there
Enter fullscreen mode Exit fullscreen mode

Oh no I lost the latest version

Don't worry, just use git log --all. Here's an example of mine:

commit 56908bb558478bc61d7319b870beb459d9853ae1 (master)
Author: Your Name <you@example.com>
Date:   Thu Jan 30 13:29:56 2025

    change to hello there

commit e1c439a92efef55036a54250a8fa58d8db2e7981 (HEAD)
Author: Your Name <you@example.com>
Date:   Thu Jan 30 13:28:32 2025

    add hi there
Enter fullscreen mode Exit fullscreen mode

Tip: if git log not showing all the results you needed, try to add --all!

Now you can find the latest commit and switch back to latest version:

git checkout 56908bb5
Enter fullscreen mode Exit fullscreen mode

Our small project so far explanation

Next, let's talk about a concept called "detached HEAD".

When you're using git checkout to change to a version, the HEAD is point to that version. This is called "detached HEAD". You can imagine it's like the Git let us "preview" what the project looks like in that version.

Generally, you don't want to have a "detached HEAD" unless you really understand what you're doing. For now, to escape the "detached HEAD" mode, use:

git checkout master
Enter fullscreen mode Exit fullscreen mode

master here is the current branch we're in. I'll explain more in part 2 when we learn about branch.

Rollback to a previous version

If you want to rollback to a specific version, you can use git reset --hard and then the version hash like so:

git reset --hard e1c439a9
Enter fullscreen mode Exit fullscreen mode

But be really careful because this command will also delete all versions after that! git log --all won't bring the newer versions back!

Git reset hard I lost the latest version for real

In fact, you should use git switch -c and then the new branch name like so:

git switch -c new-branch-name
Enter fullscreen mode Exit fullscreen mode

but again I'll explain in part 2 when we learn about branch.

Git switch c explain

.gitignore file

Next, let's talk about the famous git file: .gitignore.

Have you ever seen this file?

Git ignore file in the wild

What is the .gitignore file and what does it do?

There are files and folders that you never want to include in any version of your project.

For example think about the node_modules folder. As long as you have the package.json and package-lock.json file you can recreate the node_modules folder exactly as needed anytime you want. Furthermore, let's imagine you use a Window machine and share your project with another guy using a Mac. Because he has a different OS, to run the project he'd have to delete the node_modules and reinstall it again. But now if he git status he'll see a bunch of changes in the node_modules folder despite the fact that in reality he don't change a thing.

But I didnt change anything Git

You'd only want to include things that absolutely necessary in your version.

To avoid accidentally git add and git commit -m that node_modules folder, you can create a .gitignore file with the following content to ignore the node_modules folder:

/node_modules
Enter fullscreen mode Exit fullscreen mode

Git ignore file explain

Here are some of the usual .gitignore stuffs in the wild:

.DS_Store
*.local
*.log*

node_modules
dist/

.vscode/*
!.vscode/extensions.json
.idea
Enter fullscreen mode Exit fullscreen mode

Conclusion

Let's recap what we've learned so far:

  • git init: tell git to versioning a folder
  • git add: stage file
  • git commit -m: create new version
  • git status: show all staged files and untracked files
  • git log, git log --all: show all versions
  • git checkout [version hash]: see a previous version
  • git reset --hard [version hash]: roll back to previous version (careful when use this!)

That's the list of basic Git versioning commands that I use everyday.

In part 2 I'll talk about the next revolutionary feature of Git: branch, and in part 3 I'll talk about the full workflow.

Credits

If you like the cute fish that I'm using, check out: https://thenounproject.com/browse/collection-icon/stripe-emotions-106667/.

Top comments (0)