Version Control System:
A Version Control System is a tool that stores different versions of files, helps developers undo
mistakes, and allows teams to work on the same project without conflicts and prevents data loss.
Version Control = History + Backup + Teamwork + Safe Editing
GIT:
Git is a distributed version control system.
save and manage different versions of your files and code.
work with others, keep track of changes, and undo mistakes.
Git works on your computer, but you also use it with online services like GitHub, GitLab,
or Bitbucket to share your work with others. These are called remote repositories.
Git Workflow
The Git workflow describes how your code moves from your computer to GitHub (or any remote
repo).
It has three main areas:
1. Working Directory
This is your normal project folder on your laptop. Here you: Write code, Edit files, Delete files.
These changes are not yet tracked by Git.
2. Staging Area (Index)
This is like a waiting room.
You add the files you want Git to remember and by initializing GIT you are making a repository.
Git add filename OR git add and git status to know tracked/untracked.
3. Local Repository
This is where Git stores the versions (commits) permanently on your computer.
Git commit -m “message”
Saves a snapshot of your project with a message.
git log to view the history of commits for a repository, commit
09f4acd3f8836b7f6fc44ad9e012f82faf861803 (HEAD -> master).
Head is usually points to the latest commit in the branch you are working on.
4. Remote Repository (GitHub / GitLab)
This is a copy of your project stored on the internet.
Git push
Share your changes with others or store them safely online.
Initialising a GIT, git init
--making it a Repository ,
--Git now creates a hidden folder to keep track of changes in that folder that stores Repository
configuration, Commit history, Branches, Staging area (index),Logs ,Objects
-- master or main branch is created.
When a file is changed, added or deleted, it is considered modified
You select the modified files you want to Stage
The Staged files are Committed, which prompts Git to store a permanent snapshot of the files.
Git allows you to see the full history of every commit. --> git log
git checkout <commit-id> - You can revert back to any previous commit.
Git uses a technique called delta storage :Git does not store a separate copy of every file in every
commit, but keeps track of changes made in each commit!
git restore --staged <file> OR git reset HEAD <file> - Unstage a file
Commit All Changes Without Staging (-a)
You can skip the staging step for already tracked files with git commit -a -m "message"
Skipping the staging step can make you include unwanted changes.
git commit -a does not work for new/untracked files. You must use git add <file> first for new files.
Write Multi-line Commit Messages - git commit (no -m), your default editor will open so you can
write a detailed, multi-line message.
Git Branch
In Git, a branch is like a separate workspace where you can make changes and try new ideas
without affecting the main project. Think of it as a "parallel universe" for your code.
Developing a new feature
Fixing a bug
Experimenting with ideas
Branches allow you to work on different parts of a project without impacting the main branch.
When the work is complete, a branch can be merged with the main project.
You can even switch between branches and work on different projects without them interfering
with each other.
Branching in Git is very lightweight and fast!
Creating a New Branch: git branch branchname
Listing All Branches: git branch
but the * beside master specifies that we are currently on that branch.
Switching Between Branches: checkout is the command used to check out a branch.
Note: Using the -b option on checkout will create a new branch, and move to it, if it does not exist
Switch branches :git checkout branch-name
Git now moves HEAD to that branch.
Deleting a Branch : git branch -d branchname
Rename a branch: git branch -m old-name new-name
What is a remote branch?
A remote branch is a branch that lives on a remote repository (GitHub, GitLab, Bitbucket, etc.). It’s
not a working branch you edit locally — it’s the remote copy other people (and your CI) can see.
Remote repos are referenced by names like origin (the default name for the repo you
cloned from)
What happens when you push a branch to a remote?
Suppose you created a local branch feature/login and committed on it. If that branch does not yet
exist on the remote, git push origin feature/login will:
1. Send your local commits to the remote repository.
2. Create a new branch on the remote named feature/login pointing to those commits.
3. Update the remote-tracking branch origin/feature/login in your local repo to reflect the
remote’s state (after a fetch/push).
What does -u (or --set-upstream) do?
git push -u origin branch-name is shorthand that does two things in one command:
1. Pushes your local branch-name to the origin remote (creating origin/branch-name if
needed).
2. Sets the upstream (tracking) branch for your local branch to origin/branch-name.
Setting an upstream means your local branch “knows” which remote branch it corresponds to. That
gives you useful defaults:
After -u, you can simply run git push (no args) and Git will push the current branch to its
upstream.
Similarly, git pull will fetch from the upstream and merge (or rebase) it into your local
branch without specifying remote/branch names.
git status will show helpful info like Your branch is ahead of 'origin/branch-name' by 2
commits or behind by X commits.
Example:
git checkout -b feature/login
# make commits...
git push -u origin feature/login
# later:
git push # pushes to origin/feature/login automatically
git pull # pulls from origin/feature/login automatically
Behind the scenes — tracking vs remote-tracking
remote-tracking branch (origin/feature/login) is updated when you git fetch or git push. It
reflects the remote repo state.
upstream (tracking) setting is a config on the local branch that says “my upstream is
origin/feature/login.” You can see it with:
git branch -vv
That shows each local branch, its upstream, and whether it’s ahead/behind.
Other useful commands / variations
Manually set or change upstream:
git branch --set-upstream-to=origin/feature/login
# or the longer form
git branch -u origin/feature/login
Push current branch to origin and set upstream in one idiom:
git push -u origin HEAD
# or
git push --set-upstream origin HEAD
Delete a remote branch:
git push origin --delete feature/login
# or the older syntax:
git push origin :feature/login
View which remote a branch tracks:
git for-each-ref --format='%(refname:short) %(upstream:short)' refs/heads/
(Or simply git branch -vv for human-friendly output.)
Behaviour with git pull
When an upstream is set, git pull will, by default, fetch from origin and merge the upstream branch
into your current branch. If you prefer rebase:
git config --global [Link] true # or set per-repo
When you don’t need -u
If you regularly push different branches and prefer to specify the remote each time, you can omit -
u. But the first push of a new branch commonly uses -u so that future git pull/git push are simpler.
Short practical checklist (what to do when creating a new branch)
1. Create & switch:
2. git checkout -b feature/x
3. Work, git add and git commit.
4. Push and set upstream:
5. git push -u origin feature/x
6. Later you can git push / git pull without extra args.
Why Should You Pull Before You Push?
When you're working in a team (or even alone across multiple devices), the remote repository
(GitHub/GitLab) may receive new changes at any time.
Your local branch may become out of date compared to the remote branch.
So Git recommends:
✅ Always run git pull before git push.
⭐ What Does git pull Do?
git pull = git fetch + git merge (or rebase)
This means:
1. fetch → downloads the latest changes from the remote repository
2. merge / update → integrates those changes into your local branch
So after pulling, your local branch becomes up to date with the remote branch.
⭐ What Happens If You Push Without Pulling?
Imagine this situation:
You are working on main
Your friend also works on main
Your friend pushes changes first
Your local copy doesn't have those new changes
Now you try to git push
Git will block your push because:
❌ Your local branch is behind the remote branch
(Meaning: you are missing some commits)
Git shows this error:
! [rejected] main -> main (fetch first)
error: failed to push some refs to 'origin/main'
hint: Updates were rejected because the remote contains work that you do
not have locally.
Git does this to prevent overwriting someone else's work.
⭐ Why Pulling First Helps
When you run:
git pull
Git brings the new changes from the server to your local system.
Now you can:
Resolve conflicts (if any)
Merge the remote changes with your local changes
Make sure the history is consistent
After that, your next push will succeed:
git push
Because now:
✔ Your local branch is in sync with the remote branch
✔ Git allows you to push safely
⭐ Simple Real-Life Example
👩💻 You:
Modify [Link]
Commit your change
You are ready to push
👨💻 Your teammate:
Changed the same file earlier
Pushed before you did
You push without pulling:
Git says NO ❌ because your changes do not include your teammate’s update.
You pull first:
Git brings teammate’s changes to you
You see a merge or conflict
You fix the conflict
Commit
Now push works perfectly ✔
⭐ Final Summary (Short Notes)
Pull Before You Push → ALWAYS
Ensures your branch is up-to-date
Prevents push rejections
Avoids overwriting others' work
Lets you fix conflicts locally instead of creating issues on the remote
Keeps your commit history clean and correct