Git vs GitHub: Key Differences
You clone a repository, edit two files, commit, run git push — and the terminal answers ! [rejected] main -> main (fetch first). Nothing is broken: while you were working, a teammate pushed their own commits and your history drifted apart from the remote one. The fix is a single command, git pull --rebase, followed by git push again. Messages like this stop being scary the moment you understand where Git ends and GitHub begins, and what each command actually does.
Git is a distributed version control system that you install on your machine and that keeps the full history of a project locally. GitHub is a cloud service that hosts Git repositories and adds collaboration tools on top of them. In one sentence: Git is the tool, GitHub is the place where the results of that tool are stored, reviewed and discussed.
Git vs GitHub — what is the difference
Git was created by Linus Torvalds in 2005 for Linux kernel development. It tracks changes in code, handles branches, merges work from different developers, rolls the project back to any earlier state, and does all of that offline — the complete history lives on your own disk.
GitHub launched in 2008 and has been owned by Microsoft since 2018. It wraps Git in a web interface and adds pull requests, code review, an issue tracker, CI/CD (GitHub Actions), static site hosting (GitHub Pages) and team permissions. GitHub’s motto is Social Coding: it is not just storage for code, but a platform for both open-source and private projects.
| Aspect | Git | GitHub |
|---|---|---|
| What it is | A program — a distributed version control system | A web service that hosts Git repositories |
| Where it runs | Locally on your machine, no internet required | In the cloud, accessed through a browser or API |
| Created | 2005, by Linus Torvalds | 2008, owned by Microsoft since 2018 |
| Core features | Commits, branches, merges, history, rollbacks | Pull requests, issues, code review, Actions, Pages |
| Dependency | Works perfectly fine without GitHub | Makes no sense without Git — it stores Git repositories |
| Alternatives | Mercurial, Subversion (SVN), Perforce | GitLab, Bitbucket, Gitea, Azure Repos |
| Cost | Free and open source | Free tier plus paid plans for teams |
The short answer: Git is the technology, GitHub is a service built around that technology. You can use Git without GitHub, but GitHub cannot exist without Git.
File states in the Git working directory
Git splits every file in your project folder into two groups: tracked and untracked.
- Tracked files — files that were part of the last snapshot of the project or have already been added to the index. They can be unmodified, modified, or staged for the next commit.
- Untracked files — everything else: files that were not in the last commit and that you have not added with
git addyet.
A file travels through three areas: working directory → index (staging area) → repository.
| State | Where the file lives | What git status prints | How to move it forward |
|---|---|---|---|
| Untracked | Working directory | Untracked files | git add file |
| Modified | Working directory | Changes not staged for commit | git add file |
| Staged | Index | Changes to be committed | git commit -m "..." |
| Committed | Local repository | nothing to commit, working tree clean | git push |
One command shows the current state of every file:
git status
git status -s # short format: ?? untracked, M modified, A added to the index Essential Git commands
The list below is the minimum set that covers day-to-day work.
| Command | What it does | When you need it |
|---|---|---|
git init | Creates a new local repository in the current folder | Starting a project from scratch |
git clone | Downloads a remote repository together with its whole history | Joining someone else’s or your team’s project |
git add | Stages changes in the index (staging area) | Before every commit |
git commit | Records a snapshot of the staged changes in history | When a finished piece of work is ready |
git fetch | Downloads new data from the server without merging anything | To inspect other people’s changes without touching yours |
git pull | fetch plus merge (or rebase) into the current branch | Before starting work and before pushing |
git push | Uploads your local commits to the remote repository | When you need to share the result |
git log | Shows the commit history | Finding out who changed what and when |
git diff | Shows exactly what changed | A last check before committing |
A typical work cycle
git status # see what changed
git add . # stage all changes
git commit -m "Add user validation"
git pull --rebase # take teammates' commits and replay yours on top
git push # send everything to the server git add . vs git add -A vs git commit -am
These three shortcuts look interchangeable and are not:
git add .stages everything under the current directory, including new files.git add -A(also writtengit add --all) stages everything in the whole repository, no matter which folder you are standing in.git add -ustages only files that Git already tracks — new files are ignored.git commit -a -m "message"(short formgit commit -am) stages and commits tracked files in one step, but it will silently skip a brand-new file you have never added.
Since Git 2.0 git add . and git add -A behave identically when you run them from the repository root; the difference only shows up in a subdirectory.
What commit, fetch, pull and push really do
git commit stores the state of the project: Git records how each file looks at that moment and saves a reference to the snapshot. If a file did not change, Git does not duplicate it — it links to the identical version it already stores, which is why history stays compact.
git fetch contacts the remote repository and downloads data you do not have yet. Afterwards you get references to every remote branch (origin/main and the rest) that you can inspect or merge. Fetch does not change your working copy — merging stays your decision. Use git fetch --all to refresh every configured remote at once.
git pull is fetch plus an automatic merge of the remote branch into the current one. When you clone a repository, Git sets your local branch to track the remote’s default branch (usually main), which is why git pull without arguments knows where to pull from.
git push uploads your commits to the remote repository. It succeeds only if you have write access and nobody has pushed new commits since your last fetch. If a teammate got there first, your push is rejected with a non-fast-forward error: you have to bring their work down and combine it with yours before trying again.
Worth knowing
The --rebase flag on git pull replays your commits on top of the downloaded ones instead of creating an extra merge commit, so the history stays linear. Set it once and forget it: git config --global pull.rebase true.
Working with GitHub from the command line
There is no separate set of “GitHub commands” in the terminal. You talk to GitHub with the same Git commands — you simply point the remote at an address on github.com.
Clone an existing project
git clone https://github.com/user/project.git
cd project Push a local project to GitHub
Create an empty repository on GitHub (without a README), then run:
git init
git add .
git commit -m "Initial commit"
git branch -M main
git remote add origin https://github.com/user/project.git
git push -u origin main The -u flag links your local branch to the remote one, so from then on plain git push and git pull are enough.
Check and change the repository address
git remote -v # which remotes are configured
git remote add upstream https://github.com/original/project.git
git remote set-url origin [email protected]:user/project.git # switch to SSH Outdated sign-in advice
Since 13 August 2021 GitHub no longer accepts your account password for Git operations over HTTPS. Use a Personal Access Token (Settings → Developer settings → Tokens) in place of the password, or set up an SSH key. Any tutorial that tells you to “type your username and password” is out of date.
Branching, merging and conflicts
Branching lets you keep independent lines of development: a new feature, an experiment or a bug fix never disturbs the main code. Git stores the project as a series of snapshots, and a branch is just a lightweight pointer to one commit — which is why creating a branch takes milliseconds.
git branch # list branches
git switch -c feature/login # create a branch and move onto it
git switch main # go back to the main branch
git merge feature/login # merge the branch into the current one
git branch -d feature/login # delete a branch that has been merged git switch (change branches) and git restore (discard changes in files) arrived in Git 2.23 and split the responsibilities of the overloaded git checkout, which used to do both. The older form git checkout -b feature/login still works.
A merge conflict happens when the same line was edited in two branches. Git marks the disputed area in the file with <<<<<<<, ======= and >>>>>>>. You keep the correct version by hand, delete the markers, and finish the merge:
git add ConflictedFile.java
git commit main or master?
Since October 2020 new repositories on GitHub are created with main as the default branch instead of master. Technically it is an ordinary branch name: older projects still live on master, and the two behave exactly the same. Check which one you are on with git branch --show-current.
Tags and releases
A tag is a fixed bookmark on a particular commit. Unlike a branch, a tag never moves forward, which makes it the natural way to mark released versions such as v1.0 or v2.0.1.
git tag v1.0 # lightweight tag
git tag -a v1.0 -m "First release" # annotated tag with author and date
git push origin v1.0 # tags are not sent by a plain git push On GitHub a tag becomes the basis of a Release — a page with release notes and attached build artifacts, for example a JAR file.
Fork and pull request
A remote repository is a version of your project hosted on a server, for example on GitHub. You can have several remotes, each with its own permissions: read-only, or read and write.
If you want to contribute to a project where you have no write access, use fork — the button that creates a copy of the repository under your own account. The workflow then looks like this:
- Press Fork on the project page — the copy appears in your account.
- Clone your copy with
git clone. - Create a branch, make the changes, commit and
git push. - Open a pull request against the original repository.
- The maintainer reviews the code and either merges or rejects it.
Forking is the standard way to take part in open source. GitHub keeps the link between your copy and the original, so you can bring in upstream changes with the Sync fork button or from the terminal:
git remote add upstream https://github.com/original/project.git
git fetch upstream
git merge upstream/main Where beginners get tripped up
- Committing without staging.
git commitrecords only what you staged withgit add. A modified but unstaged file simply will not be part of the commit. - Running git add . in the project root. That is how
target/,.idea/,*.classfiles and — far worse — passwords from config files end up in the repository. Write a.gitignorebefore the first commit. - Pushing without pulling. The
! [rejected] ... (non-fast-forward)error means the server has commits you do not. The answer isgit pull --rebase, notgit push --force: a force push overwrites someone else’s work. - Pulling with uncommitted changes. Git refuses to merge over them. Either commit first, or park the changes with
git stashand bring them back withgit stash pop. - Detached HEAD. You land there after
git checkout <commit hash>. Commits made in that state belong to no branch and are easy to lose — go back withgit switch -, or save the work in a new branch first. - Mixing up the terms. A pull request is a GitHub feature, not the
git pullcommand. They share a word and nothing else.
Frequently asked questions
Can you use Git without GitHub?
Yes. Git is fully local: git init, commits, branches and history all work without an internet connection and without any account. You need GitHub when the repository has to be reachable by other people, when you want an off-site backup, or when the team reviews code together. GitLab, Bitbucket or your own server can replace GitHub for the same purpose.
What is the difference between a pull request and git pull?
They are unrelated. git pull is a Git command that downloads changes from the server into your local branch. A pull request is a GitHub feature: a proposal to merge your branch into the main one, with discussion, line-by-line comments and CI checks. GitLab calls the same thing a merge request.
How do I undo the last commit?
If the commit has not been pushed yet, use git reset: git reset --soft HEAD~1 puts the changes back into the index, while git reset --hard HEAD~1 throws them away completely. If the commit is already in a shared repository, prefer git revert HEAD - it creates a new commit that cancels the previous one and does not rewrite history your teammates have already downloaded.
Why does GitHub reject my password when I push?
Password authentication for Git operations was switched off on 13 August 2021. Create a Personal Access Token under Settings, Developer settings, Personal access tokens and enter it instead of the password, or set up an SSH key and change the repository address with git remote set-url origin.
How is GitHub different from GitLab and Bitbucket?
All three host ordinary Git repositories, so the Git commands are identical and a project can be moved between them without losing anything. The difference is the ecosystem: GitHub has the largest open-source community and GitHub Actions, GitLab focuses on a built-in DevOps pipeline and easy self-hosting, and Bitbucket integrates tightly with Jira and the rest of Atlassian.
Comments