A World Without git
![]()
If we lived in a world without git, software development and internet services would be far more primitive than they are today. When Linus Torvalds and the Linux team were developing Linux, they were using BitKeeper, which ended its free service. This led them to develop git, which has become an indispensable tool for the internet world—something even they probably didn’t foresee.
Before git, the ‘centralized system’ where code on a single server was modified has evolved into a ‘decentralized system’ where code is modified and merged on individual computers. This makes it easier to identify the root cause of problems and revert to previous states during software development, improving code stability and quality. In server operations and deployment, git enables infrastructure configuration management as code, change history tracking, and deployment automation.
So, what exactly is github?
Are git and github Different?

git is a distributed version control system. It tracks and manages source code change history, allowing you to revert to previous versions of code or check changes at specific points in time.
github is a web-based service that hosts git repositories. It’s a platform where you can store and share projects managed with git online. As long as you have internet access, it helps you share project code and collaborate with others.
To explain it in a table:
| git | github |
|---|---|
| Software | Service |
| CLI | GUI |
| Runs on local system | Web-based, runs online |
| Linux | Microsoft |
| Distributed version control | git repo hosting |
In short, you do the actual work with git, and github allows you to visually check your git work and perform git operations through the web.
Without git, there would be no github.
How to Use
While you can work directly through github, switching between the web and your editor is inefficient, so it’s more efficient to open a terminal in your editor and work there. Let’s now explore frequently used git commands.
Initial Setup and Workflow
The initial setup to connect git and github locally is as follows. Note that I’ll also explain how to set up both github and gitlab if you use both.
// Install git sudo pacman -S git // Arch Linux sudo apt install git // Ubuntu sudo dnf install git // Fedora winget install git.git // Windows choco install git // Chocolatey brew install git // Mac // Set global user information git config --global user.name "Your Name" git config --global user.email "your@email.com" // Verify user information git config --global user.name git config --global user.email
// Install git sudo pacman -S git // Arch Linux sudo apt install git // Ubuntu sudo dnf install git // Fedora winget install git.git // Windows choco install git // Chocolatey brew install git // Mac // Set global user information git config --global user.name "Your Name" git config --global user.email "your@email.com" // Verify user information git config --global user.name git config --global user.email
// Generate SSH keys ssh-keygen -t ed25519 -C "yourgithub@email.com" ssh-keygen -t ed25519 -C "yourgitlab@email.com" -f ~/.ssh/id_ed25519_gitlab // Create SSH config file and set permissions touch ~/.ssh/config chmod 600 ~/.ssh/config // Create and edit SSH config file Host github.com // github configuration (existing) HostName github.com User git IdentityFile ~/.ssh/id_ed25519 // Existing github key IdentitiesOnly yes Host gitlab.com // gitlab configuration (newly added) HostName gitlab.com User git IdentityFile ~/.ssh/id_ed25519_gitlab // New gitlab key IdentitiesOnly yes // Add keys to SSH agent eval "$(ssh-agent -s)" // Add both keys ssh-add ~/.ssh/id_ed25519 // github key ssh-add ~/.ssh/id_ed25519_gitlab // gitlab key // Verify added keys ssh-add -l // View key contents cat ~/.ssh/id_ed25519.pub cat ~/.ssh/id_ed25519_gitlab.pub
// Generate SSH keys ssh-keygen -t ed25519 -C "yourgithub@email.com" ssh-keygen -t ed25519 -C "yourgitlab@email.com" -f ~/.ssh/id_ed25519_gitlab // Create SSH config file and set permissions touch ~/.ssh/config chmod 600 ~/.ssh/config // Create and edit SSH config file Host github.com // github configuration (existing) HostName github.com User git IdentityFile ~/.ssh/id_ed25519 // Existing github key IdentitiesOnly yes Host gitlab.com // gitlab configuration (newly added) HostName gitlab.com User git IdentityFile ~/.ssh/id_ed25519_gitlab // New gitlab key IdentitiesOnly yes // Add keys to SSH agent eval "$(ssh-agent -s)" // Add both keys ssh-add ~/.ssh/id_ed25519 // github key ssh-add ~/.ssh/id_ed25519_gitlab // gitlab key // Verify added keys ssh-add -l // View key contents cat ~/.ssh/id_ed25519.pub cat ~/.ssh/id_ed25519_gitlab.pub
After this, register your SSH key with github/gitlab. You can register by accessing the respective site, then test if the SSH connection works properly.
// Verify connection ssh -T git@github.com ssh -T git@gitlab.com // result "Hi <your-github-username>! You've successfully authenticated..." // github "Welcome to gitlab, @<your-gitlab-username>!" // gitlab
// Verify connection ssh -T git@github.com ssh -T git@gitlab.com // result "Hi <your-github-username>! You've successfully authenticated..." // github "Welcome to gitlab, @<your-gitlab-username>!" // gitlab
Now github (gitlab) is connected to your computer. Let’s see how to connect your project to github.
// If you want to create a github repo through CLI, install sudo pacman -S github-cli // Arch Linux winget install github.cli // Windows choco install github-cli // Chocolatey brew install gh // Mac
// If you want to create a github repo through CLI, install sudo pacman -S github-cli // Arch Linux winget install github.cli // Windows choco install github-cli // Chocolatey brew install gh // Mac
// Ubuntu, Debian (type -p wget >/dev/null || (sudo apt update && sudo apt install wget -y)) \ && sudo mkdir -p -m 755 /etc/apt/keyrings \ && out=$(mktemp) && wget -nv -O$out https://cli.github.com/packages/githubcli-archive-keyring.gpg \ && cat $out | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null \ && sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \ && sudo mkdir -p -m 755 /etc/apt/sources.list.d \ && echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \ && sudo apt update \ && sudo apt install gh -y // Fedora, CentOS, Red Hat (DNF4) sudo dnf install 'dnf-command(config-manager)' sudo dnf config-manager --add-repo https://cli.github.com/packages/rpm/gh-cli.repo sudo dnf install gh --repo gh-cli
// Ubuntu, Debian (type -p wget >/dev/null || (sudo apt update && sudo apt install wget -y)) \ && sudo mkdir -p -m 755 /etc/apt/keyrings \ && out=$(mktemp) && wget -nv -O$out https://cli.github.com/packages/githubcli-archive-keyring.gpg \ && cat $out | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null \ && sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \ && sudo mkdir -p -m 755 /etc/apt/sources.list.d \ && echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \ && sudo apt update \ && sudo apt install gh -y // Fedora, CentOS, Red Hat (DNF4) sudo dnf install 'dnf-command(config-manager)' sudo dnf config-manager --add-repo https://cli.github.com/packages/rpm/gh-cli.repo sudo dnf install gh --repo gh-cli
Now you’ve completed all the computer setup for git and github. Next, let’s check the flow of creating a repo using git and gh commands and uploading to the remote repository.
// Initialize project git init // Add current files to staging area git add . // Add description for added files and update HEAD pointer in local repository git commit -m "init" // Check status git status // If branch name is master but you want to change it to main git branch -m master main // Check again git status // Create github repo (requires github CLI / private, use current directory source, set remote repository) gh repo create repo-name --private --source=. --remote=origin // Push to remote repository git push -u origin main // From now on, it's simple git add . git commit -m "fixed: type error" git push
// Initialize project git init // Add current files to staging area git add . // Add description for added files and update HEAD pointer in local repository git commit -m "init" // Check status git status // If branch name is master but you want to change it to main git branch -m master main // Check again git status // Create github repo (requires github CLI / private, use current directory source, set remote repository) gh repo create repo-name --private --source=. --remote=origin // Push to remote repository git push -u origin main // From now on, it's simple git add . git commit -m "fixed: type error" git push
reset and revert
If the uploaded code might be misleading to other team members or if the code modifications are insufficient, you need to go back. Even in such cases, you can work with the following commands.
First, there’s the method of completely resetting without any history.
// To go back to the previous state git reset --hard HEAD~1 // How to push modified code afterwards git push --force origin <branch-name> // Or if collaborators haven't updated yet (recommended) git push --force-with-lease origin <branch-name>
// To go back to the previous state git reset --hard HEAD~1 // How to push modified code afterwards git push --force origin <branch-name> // Or if collaborators haven't updated yet (recommended) git push --force-with-lease origin <branch-name>
Additionally, we used --hard, but there are three modes, so let’s check them out
// Move only HEAD pointer (keep staging area as is) git reset --soft <commit-hash> // Move HEAD pointer and staging area (default) git reset --mixed <commit-hash> // Move HEAD pointer, staging area, and working directory git reset --hard <commit-hash>
// Move only HEAD pointer (keep staging area as is) git reset --soft <commit-hash> // Move HEAD pointer and staging area (default) git reset --mixed <commit-hash> // Move HEAD pointer, staging area, and working directory git reset --hard <commit-hash>
Second, there’s the method of preserving history but creating a new commit that undoes the changes. Note that it creates a commit rather than reverting.
Most people think of revert as just a ‘reverting command’, but in reality, it reverts by creating a new commit, modifying it, and committing again.
// Cancel most recent commit changes and create a new commit git revert HEAD // Cancel specific commit changes and create a new commit git revert <commit-hash>
// Cancel most recent commit changes and create a new commit git revert HEAD // Cancel specific commit changes and create a new commit git revert <commit-hash>
Therefore, use reset when you want to “make it as if it never happened locally”, and use revert when you want to “cancel already shared changes and record them as new work”.
Note that git reset --hard cannot be recovered, so use it carefully.
checkout and branch
Many people confuse checkout and branch commands. Simply put, checkout is used to switch the current working environment, while branch is a command that manages the branch itself, such as creating, listing, and deleting.
// Check local branches git branch // result * main dev fix-login-function // Check all branches git branch -a // result * main dev fix-login-function remotes/origin/fix-login-function remotes/origin/fix-mobile-layout remotes/origin/user-profile // Create new branch git branch admin-dashboard // Delete branch git branch -d new-login
// Check local branches git branch // result * main dev fix-login-function // Check all branches git branch -a // result * main dev fix-login-function remotes/origin/fix-login-function remotes/origin/fix-mobile-layout remotes/origin/user-profile // Create new branch git branch admin-dashboard // Delete branch git branch -d new-login
// Switch workspace to dev git checkout dev // Create and move to a branch at the same time git checkout -b payment
// Switch workspace to dev git checkout dev // Create and move to a branch at the same time git checkout -b payment
tag
If you want to manage your project by version, create tags.
// Commit and push changes git add . git commit -m "release v0.1.0" git push // Tag current commit and create git tag v0.1.0 // Push tag to github git push origin v0.1.0
// Commit and push changes git add . git commit -m "release v0.1.0" git push // Tag current commit and create git tag v0.1.0 // Push tag to github git push origin v0.1.0
Later, if you need to deploy again after adding or modifying features, create a new tag and push again.
// 0.1.0 -> 0.1.1 // Commit changes git add . git commit -m "release v0.1.1" // Create new tag git tag v0.1.1 // push git push origin v0.1.1 git push origin main
// 0.1.0 -> 0.1.1 // Commit changes git add . git commit -m "release v0.1.1" // Create new tag git tag v0.1.1 // push git push origin v0.1.1 git push origin main
Tag management is also useful to know, so keep it in mind.
// Check list git tag // Checkout to specific tag git checkout v0.1.0 // Delete tag (local) git tag -d v0.1.0 // Delete tag (github) git push origin --delete v0.1.0 // Add message to tag (optional) git tag -a v0.1.0 -m "Release v0.1.0: Initial release" git push origin v0.1.0
// Check list git tag // Checkout to specific tag git checkout v0.1.0 // Delete tag (local) git tag -d v0.1.0 // Delete tag (github) git push origin --delete v0.1.0 // Add message to tag (optional) git tag -a v0.1.0 -m "Release v0.1.0: Initial release" git push origin v0.1.0
remote
You might also be confused about remote, but this command is a copy of a git repository that exists on a network, separate from your local computer’s git repository.
In short, when sharing company git code and working together, it acts as an intermediate hub between the company git repository and your computer’s git repository.
Because of this, even if something goes wrong with your computer, the remote repository can prevent data loss, and as long as you have an internet connection, you can access and modify the project code.
You might think it’s unfamiliar, but these are commands everyone uses, so let’s check them out.
// When connecting a remote repository to a local repository git remote add origin <repo> // When copying the entire remote repository locally git clone <repo> // When uploading commits from local repository to remote repository git push origin main // When fetching commits from remote repository to local repository git pull origin main // When fetching changes from remote repository locally but not merging with current working branch git fetch origin
// When connecting a remote repository to a local repository git remote add origin <repo> // When copying the entire remote repository locally git clone <repo> // When uploading commits from local repository to remote repository git push origin main // When fetching commits from remote repository to local repository git pull origin main // When fetching changes from remote repository locally but not merging with current working branch git fetch origin
Conclusion
Linus Benedict Torvalds, who developed Linux and git
This became too long, so although there are many gh commands, I only wrote about basic repo creation, and diff and merge also exist but were excluded from this post.
Honestly, you don’t need to memorize all the commands explained. As you use them, you’ll naturally learn them, and if you can’t remember a feature you want, you can just search for it then without much problem. However, finding clear explanations for confusing parts like managing two SSH keys takes time, so I hope this post helps developers using git.
Finally, for those reading this, please don’t buy books or courses about git and github on the market and just search for information yourself.
Comments