- Introduction
- What is Git?
- Understanding Version Control Systems
- Git vs GitHub
- Installing Git
- How Git Works
- Hands-on Git
- Git Scenario 1: Single User Setup
- Ignoring Files
- Tracking Empty Directories
- Branches
- Merge Conflict
- Stashing in Git
- Git Tags
- Git Rebase
- Using GitHub to Host Our Repositories
- GitHub Desktop: GUI for Git and GitHub
- Using Git in VS Code
- Git Scenario 2: Multi-User Setup
- Modern Workflow
- Conclusion
Learning Git doesn’t have to be hard. This handbook is a beginner-friendly, practical guide to help you understand Git and GitHub from scratch without the jargon.
If you’ve ever asked “What is Git?”, “What is a commit?”, or “How do developers work together on GitHub?”, you’re in the right place. You’ll find clear explanations, visual diagrams, real-world examples, and copy-paste-ready commands to make learning easy.
By the end of this handbook, you’ll know how to:
- Track and manage code with Git.
- Create and use branches.
- Merge changes and fix conflicts.
- Collaborate with others on GitHub.
- Use real-world Git workflows.
Whether you’re a student, self-taught developer, open-source contributor, or preparing for your first tech job, this handbook is for you.
You can use this handbook in two ways:
- Learn step by step by reading it from start to finish.
- Use it as a reference by jumping to any of the topics in the Table of Contents whenever you need a quick refresher.
⭐ Found this handbook helpful? Consider starring the repository to support the project, and feel free to open a pull request if you'd like to improve it for the community.
Git is a version control system that tracks changes to files over time. It helps you save progress, return to earlier versions, and work without losing important edits.
Think of Git as a timeline for your project. Each saved point is called a commit. You can review changes, compare versions, and undo mistakes when needed.
flowchart LR
A["🔴 A<br/>Commit 1"] --> B["🟠 B<br/>Commit 2"] --> C["🟢 C<br/>Commit 3"]
In the above diagram, each letter is one commit. New commits extend the line to the right.
Git is often used with GitHub, which gives you a place to store repositories online, share code, and collaborate with others.
|
A clear history of changes made to your project over time |
Safe backup points for your work that you can return to anytime. |
|
Easier teamwork when multiple people work on the same project. |
The ability to undo mistakes without losing important edits. |
| Step | Action | Git Command |
|---|---|---|
| ✏️ | Edit Files | Working Directory |
| ⬇️ | Stage Changes | git add |
| 💾 | Create Commit | git commit |
| ☁️ | Push to GitHub | git push |
| 🌍 | Repository Updated | GitHub |
flowchart LR
A["✏️ Edit Files<br/><sub>Working Directory</sub>"]
--> B["📋 Stage Changes<br/><code>git add</code>"]
--> C["💾 Commit Changes<br/><code>git commit</code>"]
--> D["☁️ Push to GitHub<br/><code>git push</code>"]
--> E["🌍 GitHub Repository"]
Click here 👉 Table of Contents to return back to the Table of Contents.
Version control systems (VCS) track file changes over time. They let you save snapshots, compare versions, and collaborate without overwriting each other's work.
With version control, you can:
- 📝 Save snapshots of your project.
- 🔍 Compare different versions.
- ⏪ Restore previous versions when needed.
- 🤝 Collaborate with others without overwriting each other's work.
In a centralized model, one server holds the official copy of the project. Developers check out files, make changes, and check them back in.
- SVN (Subversion)
- CVS (Concurrent Versions System)
- If the central server goes down, collaboration stops
In a distributed model, every developer has a full copy of the project history on their machine. You commit locally first, then sync with a remote when ready.
- Git
- Mercurial
- You can work offline and still have a full history.
| Feature | 🏛️ Centralized VCS | 🌐 Distributed VCS |
|---|---|---|
| 📜 Project History | Stored only on the server | Stored on every developer's machine |
| 💻 Offline Work | Limited | Full support |
| 💾 Backup | Only the server has the complete history | Every clone acts as a backup |
| Single point of failure | Multiple copies reduce risk | |
| ⚡ Performance | Slower (depends on server) | Faster local operations |
🏛️ Centralized Version Control
☁️ Central Server
┌─────────────────┐
│ Project History │
└────────┬────────┘
┌────────┼────────┐
▼ ▼ ▼
👨💻 Dev A 👩💻 Dev B 👨💻 Dev C
🌐 Distributed Version Control (Git)
👨💻 Dev A 👩💻 Dev B 👨💻 Dev C
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Full Repo│ │ Full Repo│ │ Full Repo│
│ + History│ │ + History│ │ + History│
└────┬─────┘ └────┬─────┘ └────┬─────┘
└─────────────┼─────────────┘
▼
☁️ Remote Repository
Git was created by Linus Torvalds in 2005 for large teams working on the Linux Kernel. A distributed model means:
- ⚡ Faster performance
- 💾 Reliable backups
- 🌿 Easy branching
- 🔀 Powerful merging
- 💻 Offline development
- 🤝 Efficient collaboration
- Centralized VCS relies on one server.
- Distributed VCS gives everyone a full copy.
- Git is distributed by design.
Click here 👉 Table of Contents to return back to the Table of Contents.
Git is the version control tool that runs on your computer. It tracks changes, creates commits, and manages branches.
GitHub is a website that hosts Git repositories online. It adds collaboration features like pull requests, issues, and code review.
They are not the same thing — Git is the engine, GitHub is one of several places you can park it.
A repository (repo) is a project folder tracked by Git. It contains your files plus the hidden .git folder with all history.
- Local repo: on your machine, where you commit daily work.
- Remote repo: on GitHub (or similar), where you push and pull to share code.
- 📁 A Git Repository is a project folder managed by Git.
- 📂 The hidden
.gitfolder stores your project's complete history. - 🖥️ A Local Repository is where you develop and commit your work.
- ☁️ A Remote Repository is where you share, back up, and collaborate on your project.
- 🔄 Use
git pushto upload your commits andgit pullto download the latest changes.
| Git | GitHub | |
|---|---|---|
| What it is | Tool | Hosting service |
| Runs on | Your computer | The cloud |
| Needs internet | No (for local work) | Yes (to sync) |
| Stores history | Yes | Yes (as a remote copy) |
Click here 👉 Table of Contents to return back to the Table of Contents.
Before you can start tracking your projects with Git, you need to install it on your operating system. Git is available for Windows, macOS, and Linux, and the installation process only takes a few minutes.
💡 Recommendation: Always install Git from the official Git website to ensure you get the latest stable version.
- Visit https://git-scm.com/downloads
- Download the latest version for Windows.
- Run the installer.
- Leave all settings as Default unless you have specific preferences.
- Click Next until the installation is complete.
- Click Finish.
✅ Git is now installed on your computer.
If you have Windows Package Manager (Winget) installed, open Command Prompt or PowerShell and run:
winget install --id Git.Git -e --source wingetWait for the installation to complete.
There are two common ways to install Git on macOS.
Open Terminal and run:
xcode-select --installFollow the on-screen instructions.
Git will be installed automatically along with Apple's Command Line Tools.
If you already have Homebrew installed, simply run:
brew install gitGit is available through your Linux distribution's package manager.
Update your package list:
sudo apt updateInstall Git:
sudo apt install gitsudo dnf install gitsudo pacman -S gitAfter installing Git, open your terminal (or Command Prompt) and run:
git --versionIf Git is installed correctly, you'll see output similar to:
git version 2.x.x
🎉 Congratulations! Git has been successfully installed.
Once Git is installed, you can use it in different ways depending on your preference.
| Workflow | Best For | Description |
|---|---|---|
| 💻 Command Line | ⭐ Recommended | The most powerful and flexible way to use Git. Works on every platform and supports every Git feature. |
| 📝 Visual Studio Code | Daily Development | Use VS Code's built-in Source Control panel to manage commits, branches, and repositories without leaving your editor. |
| 🖥️ GitHub Desktop | Beginners | A simple graphical interface that lets you use Git without memorizing commands. |
💡 Good to Know: Regardless of whether you use the Command Line, VS Code, or GitHub Desktop, they all execute the same Git commands behind the scenes.
| Platform | Installation Method | Command / Website |
|---|---|---|
| 🪟 Windows | Official Installer | https://git-scm.com/downloads |
| 🪟 Windows | Winget | winget install --id Git.Git -e --source winget |
| 🍎 macOS | Xcode Command Line Tools | xcode-select --install |
| 🍎 macOS | Homebrew | brew install git |
| 🐧 Debian / Ubuntu | APT | sudo apt update && sudo apt install git |
| 🐧 Fedora | DNF | sudo dnf install git |
| 🐧 Arch Linux | Pacman | sudo pacman -S git |
Click here 👉 Table of Contents to return back to the Table of Contents.
Git moves your changes through four areas before they reach GitHub:
| 📁 | 📋 | 💾 | ☁️ |
|---|---|---|---|
| WORKING DIR | STAGING AREA | LOCAL REPO | REMOTE REPO |
| Your files on disk | Changes queued for commit | Commits saved locally | GitHub / cloud host |
| 01) Working Directory Your project files on disk. Edit freely here. Git sees changes but does not save them until you stage and commit. |
02) Staging Area A holding zone for changes you want in the next commit. Use git add to move files here. |
|---|---|
| 03) Local Repository Where commits are stored permanently on your machine. Use git commit to save a snapshot. |
04) Remote Repository The copy on GitHub (or another host). Use git push to upload and git pull to download. |
A full cycle from editing to pushing looks like this:
# 1. Edit files in your working directory
# 2. Stage changes
git add .
# 3. Commit to local repository
git commit -m "describe your change"
# 4. Push to remote repository
git push origin mainEach commit is a snapshot of your entire project at one moment. Git stores these efficiently so that you can jump back to any point in history.
# See all snapshots
git log --onelineClick here 👉 Table of Contents to return back to the Table of Contents.
Git provides a simple set of commands for tracking changes, saving versions of your work, and reviewing your project history.
Before working with Git, you can verify that Git is installed and check the current state of your repository.
# check installed Git version
git --version
# initialize Git in the current folder
git init
# check the current repository state
git statusBefore making your first commit, configure your name and email address. You usually need to do this only once per machine.
git config --global user.name "Your_Name"
git config --global user.email "Your_Email"You can verify your configuration with:
git config --global user.name
git config --global user.emailThese four commands cover most of your everyday Git workflow:
git statusgit addgit commitgit log
Shows the current state of your repository.
It tells you which files are:
- Modified
- Staged
- Untracked
- Ready to commit
git statusFor a shorter and more compact output:
git status -sExample:
M README.md
?? notes.txt
Here:
Mmeans the file has been modified.??means Git is not yet tracking the file.
Stages changes so they can be included in your next commit.
git add README.mdgit add README.md main.pygit add .git add *.pyNote:
git adddoes not permanently save your changes. It only moves them into the staging area, ready for the next commit.
Creates a saved snapshot of your staged changes.
git commit -m "add README file"A good commit message should briefly explain what changed.
Example:
git commit -m "fix login validation"You can also stage and commit already tracked files in one command:
git commit -am "fix typo in main script"Important:
git commit -amonly works with files that Git is already tracking.
New or untracked files must first be staged usinggit add.
Example:
git add new_file.py
git commit -m "add new Python file"Shows the commit history of your repository.
git loggit log --onelineExample:
a1b2c3d add README file
e4f5g6h fix login validation
7h8i9j0 initial commit
git log --oneline -5git log --oneline --graph --allThis is especially useful when working with multiple branches.
A normal Git workflow usually follows this cycle:
# 1. check what changed
git status
# 2. stage your changes
git add .
# 3. save the staged changes
git commit -m "describe your changes"
# 4. review commit history
git log --onelineThink of it as:
Check → Stage → Save → Review
Removes a file from the staging area without deleting your changes.
git restore --staged <filename>Example:
git restore --staged README.mdgit add .git log --onelinegit log --oneline --graph --all| Command | What It Does |
|---|---|
git init |
Initializes a new Git repository in the current folder. |
git status |
Shows staged, modified, and untracked files in the working directory. |
git status -s |
Displays a compact summary of the repository state. |
git add <filename> |
Stages a specific file for the next commit. |
git add . |
Stages all current changes for the next commit. |
git add *.py |
Stages all matching .py files. |
git commit -m "message" |
Creates a new snapshot with a descriptive message. |
git commit -am "message" |
Stages tracked modified files and commits them in one step. |
git log |
Displays the complete commit history. |
git log --oneline |
Displays each commit in a compact one-line format. |
git log --oneline -5 |
Displays the five most recent commits. |
git log --oneline --graph --all |
Visualizes branch and merge history as a graph. |
git restore --staged <filename> |
Removes a file from staging while keeping its changes. |
Click here 👉 Table of Contents to return back to the Table of Contents.
Let me walk you through a complete project from scratch.
1. Create a Simple Project
mkdir hello-git
cd hello-git
git init
echo "# Hello Git" > README.md2. Make Changes
echo "print('hello')" > main.py
git status3. Stage Files
git add README.md
git add main.py
# or stage everything at once
git add .4. Create a Commit
git commit -m "initial commit with readme and main script"git log --oneline- Commit when a logical piece of work is done.
- One idea per commit.
- Use present tense messages:
add login formnotadded login form.
# good commit flow
git status
git add .
git commit -m "add user input validation"
git log --oneline -3Every project follows the same repeating loop: edit → stage → commit → review. Repeat this cycle for every logical change.
EDIT
Make your changes to files in the working directory. Git notices but does not save them yet.
STAGE
Use git add to move changes into the staging area, ready to be committed.
COMMIT
Use git commit -m to save a permanent snapshot with a clear message.
REVIEW
Use git log --oneline to inspect your commit history and confirm everything looks right.
Click here 👉 Table of Contents to return back to the Table of Contents.
Not every file belongs in Git. Some files should stay local and should never be committed to your repository.
Common examples include:
- Passwords and API keys such as
.env - Dependency folders such as
node_modules/ - Build output such as
dist/andbuild/ - Python-generated files such as
__pycache__/ - Operating system files such as
.DS_StoreandThumbs.db - Large or temporary data files
Create a .gitignore file in the root of your repository. Git will ignore files and folders that match the patterns listed inside it.
touch .gitignoreExample .gitignore file:
# environment variables
.env
# Python
__pycache__/
*.pyc
venv/
# OS files
.DS_Store
Thumbs.db
# build output
dist/
build/Ignore a specific file:
secret.txtIgnore a folder and everything inside it:
node_modules/Ignore all files of a specific type:
*.logIgnore all .log files but keep one specific file:
*.log
!important.logThe ! symbol means do not ignore this matching file.
So:
!important.logmeans that important.log should remain trackable even if *.log is ignored above it.
| Pattern | What It Ignores |
|---|---|
secret.txt |
A file named secret.txt wherever the pattern matches in the repository. |
node_modules/ |
The node_modules folder and everything inside it. |
*.log |
All files with the .log extension. |
!important.log |
Keeps important.log from being ignored when a previous rule ignores it. |
.env |
The environment file that often contains secrets and API keys. |
__pycache__/ |
Python cache directories. |
*.pyc |
Compiled Python files. |
dist/ |
Distribution or build output folder. |
build/ |
Build output folder. |
Git does not track empty folders by itself.
If you want an empty folder to appear in your repository, add a placeholder file such as .gitkeep.
mkdir logs
touch logs/.gitkeep
git add logs/.gitkeep.gitkeep is not a special Git feature. It is simply a common convention used to keep otherwise-empty folders in a repository.
Adding a file to .gitignore does not automatically stop Git from tracking it if it was already committed or staged before.
Remove it from Git's tracking while keeping the local file:
git rm --cached filenameThen commit the change:
git commit -m "stop tracking filename"For example:
git rm --cached .env
git commit -m "stop tracking .env"The file will remain on your computer, but Git will stop tracking it.
Click here 👉 Table of Contents to return back to the Table of Contents.
Git only tracks files, never empty folders. To keep an empty folder (like logs/) in your repo:
mkdir logs
touch logs/.gitkeep
git add logs/.gitkeepClick here 👉 Table of Contents to return back to the Table of Contents.
Branches let you work on new features, bug fixes, or experiments without touching your stable code.
A branch is an independent line of development.
In most repositories, main is the default branch.
Branching at commit B lets you build a feature without changing main:
A─B─C main
\
D─E feature/search
Each letter represents a commit.
The lines show how commits are connected, and time flows from left to right.
Branches are useful because:
- They let you build features in isolation.
- They help fix bugs without breaking stable or production code.
- They let you experiment safely.
- They allow multiple lines of development to exist at the same time.
Create a new branch with:
git branch feature/search # git branch <branchname>This creates the branch, but it does not switch you to it.
Using the traditional command:
git checkout feature/searchModern alternative:
git switch feature/searchBoth commands move you onto the selected branch.
You can create a branch and switch to it in one command.
Traditional method:
git checkout -b feature/searchModern alternative:
git switch -c feature/searchThe -c option tells Git to create the branch before switching to it.
Show all local branches:
git branchExample:
* feature/search
main
The * symbol shows your current branch.
Show local and remote branches:
git branch -aShow only the name of your current branch:
git branch --show-currentExample:
feature/search
You can visualize how branches split and merge with:
git log --oneline --graph --allA typical branch history may look like:
D─E
/ \
A─B─C─────M
Here:
A,B, andCare commits on the original line of development.DandErepresent work done on another branch.Mis a merge commit where the two lines of development come back together.
This graph helps you understand how branches have changed and merged over time.
Click here 👉 Table of Contents to return back to the Table of Contents.
Merge conflicts happen when Git cannot automatically combine changes made to the same lines of a file.
Common causes include:
- Two people edit the same line of a file.
- You edit a file locally while someone else pushes changes to the same part.
- You merge branches that contain overlapping edits.
- You rebase a branch that has conflicting changes.
For example, both branches may change the same line after splitting from the same commit:
C feature/search changed line 10
/
A─B─E main also changed line 10
Both branches changed the same part of the file after commit B.
Git cannot decide automatically which version should be kept, so it reports a merge conflict.
Try to merge the branch:
git merge feature/searchIf Git finds conflicting changes, you may see output similar to:
CONFLICT (content): Merge conflict in filename.py
Open the conflicted file and Git will show special conflict markers.
A conflicted file may look like this:
<<<<<<< HEAD
your version
=======
their version
>>>>>>> feature/search
The markers mean:
<<<<<<< HEADshows the version from your current branch.=======separates the two conflicting versions.>>>>>>> feature/searchshows the version from the branch being merged.
Edit the file manually and keep the correct code.
Then remove all conflict markers:
<<<<<<< HEAD
=======
>>>>>>> feature/search
After resolving the file, stage it:
git add filename.pyThen create a commit:
git commit -m "resolve merge conflict in filename.py"git diff helps you inspect changes before committing them.
It can compare different areas of your Git workflow.
Working Directory → Staging Area → Repository
Compare your working directory with the staging area:
git diffThis shows changes you have made but have not staged yet.
Compare the staging area with the last commit (HEAD):
git diff --stagedThis shows changes that have already been staged with git add.
git diff filename.pyDuring a merge conflict, this can help you inspect conflicting changes in a specific file.
| Command | What It Compares |
|---|---|
git diff |
Working directory vs staging area |
git diff --staged |
Staging area vs last commit (HEAD) |
git diff filename.py |
Changes in a specific file |
Pull the latest changes before starting work:
git pull origin mainBefore pushing your work, make sure your local branch is updated:
git pull origin main
git push origin mainOther good practices include:
- Keep feature branches short-lived.
- Commit and synchronize changes regularly.
- Communicate with teammates when working on the same files.
- Avoid making large unrelated changes in the same commit.
If you are in the middle of a merge conflict and want to cancel the merge:
git merge --abortgit merge --abort stops the in-progress merge and attempts to return your files to the state they were in before you ran:
git mergeClick here 👉 Table of Contents to return back to the Table of Contents.
Git stash saves uncommitted work temporarily so you can switch tasks without creating a half-finished commit.
Suppose you are working on a feature, but suddenly need to fix an urgent bug on main.
Instead of committing unfinished work, you can temporarily store your changes using Git stash.
Working on feature
↓
git stash
↓
Switch branch / fix bug
↓
Return to feature
↓
git stash pop
Save your current uncommitted changes:
git stashYou can also add a message so you remember what the stash contains:
git stash push -m "wip on search feature"This temporarily stores your work and gives you a cleaner working directory.
To see all saved stashes:
git stash listExample:
stash@{0}: On feature/search: wip on search feature
stash@{1}: On feature/login: half-done login form
Each stash receives an identifier such as:
stash@{0}
stash@{1}
Apply the most recent stash:
git stash applyThis restores the changes but keeps the stash in the stash list.
To apply a specific stash:
git stash apply stash@{1}git stash apply restores the saved changes but keeps the stash:
git stash applygit stash pop restores the saved changes and removes the stash from the list:
git stash popIn simple terms:
git stash apply → restore + keep
git stash pop → restore + remove
Suppose you are working on a login feature but need to fix an urgent issue on main.
First, save your unfinished work:
git stash push -m "half-done login form"Switch to main:
git switch mainCreate a branch for the urgent fix:
git switch -c hotfix/typoFix the issue, commit it, and complete your work.
Then return to your feature branch:
git switch feature/loginRestore your saved work:
git stash popYou can now continue working from where you stopped.
If you no longer need a specific stash:
git stash drop stash@{0}This permanently removes that stash from the list.
To remove every saved stash:
git stash clearBe careful with this command because it removes all stashes.
| Command | What It Does |
|---|---|
git stash |
Temporarily saves current uncommitted changes. |
git stash push -m "message" |
Saves changes with a descriptive label. |
git stash list |
Shows all saved stashes. |
git stash apply |
Restores the latest stash and keeps it in the list. |
git stash apply stash@{1} |
Restores a specific stash. |
git stash pop |
Restores the latest stash and removes it from the list. |
git stash drop stash@{0} |
Deletes a specific stash. |
git stash clear |
Deletes all saved stashes. |
Click here 👉 Table of Contents to return back to the Table of Contents.
Git tags mark important points in your repository history, usually releases.
Git tags are useful for:
- Marking version releases such as
v1.0.0 - Bookmarking stable checkpoints
- Referencing a specific commit permanently
Unlike branches, tags do not move when new commits are added.
Example:
A─B─C─D
↑ ↑
v1.0.0 main
After adding more commits:
A─B─C─D─E─F
↑ ↑
v1.0.0 main
v1.0.0 stays on commit C, while main continues moving forward.
A lightweight tag is a simple pointer to a commit.
It does not store extra metadata such as an author, date, or message.
git tag v1.0.0Annotated tags are recommended for releases.
They store additional information such as:
- Author
- Date
- Tag message
Create an annotated tag:
git tag -a v1.0.0 -m "first stable release"Tag the current commit:
git tag v1.0.0Tag a specific commit:
git tag v0.9.0 a1b2c3dCreate an annotated tag with a message:
git tag -a v1.0.0 -m "release version 1.0.0"List all tags:
git tagList tags matching a specific pattern:
git tag -l "v1.*"View details about a tag:
git show v1.0.0Tags are not automatically pushed with normal commits.
Push one specific tag:
git push origin v1.0.0Push all local tags:
git push origin --tagsDelete a tag locally:
git tag -d v1.0.0Delete the same tag from GitHub:
git push origin --delete v1.0.0| Type | Use Case |
|---|---|
| Lightweight | Simple pointer to a commit with no extra metadata |
| Annotated | Stores author, date, and message; recommended for releases |
Click here 👉 Table of Contents to return back to the Table of Contents.
Git rebase moves your branch commits on top of another branch to create a cleaner and more linear history.
Instead of creating a merge commit, git rebase replays your commits on top of the latest commits from another branch.
Suppose your feature branch diverged from main at commit B.
Your feature branch has commits C and D, while main has moved forward to commit E:
C─D feature/search
/
A─B─E main
After running:
git switch feature/search
git rebase mainGit replays your feature commits on top of E:
A─B─E─C'─D'
↑ ↑
main feature/search
C' and D' are new commits containing the same changes as C and D, but they are now based on the latest main.
A merge keeps the original branch structure and creates a merge commit.
C─D
/ \
A─B─E─────M
Here, M is the merge commit.
A rebase instead replays your work on top of the updated branch:
A─B─E─C'─D'
This creates a straight, linear history without an extra merge commit.
| Merge | Rebase | |
|---|---|---|
| History | Preserves branch structure | Linear and cleaner |
| Merge commit | Yes | No |
| Safe on shared branches | Yes | No |
Rebase is useful:
- Before opening a pull request to keep your branch history clean
- To sync a feature branch with the latest changes from
main - On branches that only you are working on
Example:
# update your feature branch with the latest main
git switch feature/search
git fetch origin
git rebase origin/mainThis fetches the latest remote changes and replays your feature commits on top of the latest origin/main.
Before pushing your feature branch for a pull request:
git switch feature/search
git rebase main
git push --force-with-lease origin feature/searchBecause rebase rewrites commit history, a normal push may be rejected.
--force-with-lease safely updates the remote branch while checking that no unexpected remote changes have been added.
- Rebase branches that only you are working on.
- Rebase your feature branch before opening a pull request if you want a cleaner history.
- Never rebase commits that have already been pushed to a shared branch.
- Remember that rebase creates new versions of your commits.
If the rebase becomes difficult or you want to cancel it:
git rebase --abortThis stops the current rebase and returns your branch to the state it was in before the rebase started.
⚠️ Never rebase commits that have already been pushed to a shared branch.
Rebase rewrites commit history, so changing commits that other developers are already using can cause synchronization problems.
Click here 👉 Table of Contents to return back to the Table of Contents.
GitHub allows you to host your Git repositories online so you can store your code, maintain its history, share projects, and collaborate with others.
To use GitHub, first create a personal GitHub account.
Step 1: Go to github.com/signup.
Step 2: Enter your email address or continue using a supported social sign-in option.
Step 3: Follow GitHub's prompts to create your account, including choosing your account details such as a username.
Step 4: Verify your email address using the verification message sent by GitHub.
Step 5: Sign in to your GitHub account.
After completing these steps, your GitHub account is ready to use.
A repository is where GitHub stores your project's files, code, commits, and version history.
To create one:
Step 1: Sign in to GitHub.
Step 2: Click the + button in the upper-right corner.
Step 3: Select New repository.
Step 4: Choose the repository owner.
Step 5: Enter a repository name.
Example:
hello-git
Step 6: Optionally add a short description of the project.
Step 7: Select the repository visibility:
- Public → anyone can view the repository.
- Private → only you and people you authorize can access it.
Step 8: Optionally select Add a README file.
Step 9: Click Create repository.
Your repository is now hosted on GitHub.
README.md is a Markdown file commonly used to document your project in a structured and readable format.
It can explain things such as:
- What the project does
- How to install or run it
- How to use the project
- Project requirements
- Important instructions or documentation
Example:
# Hello Git
This is my first Git project.
## Installation
Clone the repository and run the project.GitHub automatically displays the repository's README on the main repository page when one is available.
git clone downloads a complete copy of a GitHub repository to your local computer.
For a public repository:
git clone <URL>Example:
git clone https://github.com/OWNER/REPOSITORY.gitPublic repositories can normally be cloned without authentication.
Step 1: Open the repository on GitHub.
Step 2: Click the Code button above the repository files.
Step 3: Select HTTPS.
Step 4: Copy the repository URL.
It will look similar to:
https://github.com/OWNER/REPOSITORY.git
Step 5: Open Git Bash on your computer.
Step 6: Move to the directory where you want to download the project.
Example:
cd DesktopStep 7: Run:
git clone https://github.com/OWNER/REPOSITORY.gitStep 8: Git will create a new folder and download the repository files and Git history.
Move inside the cloned repository:
cd REPOSITORYWhen a repository is cloned, Git also automatically creates a remote named origin that points back to the repository you cloned.
Private repositories require authentication.
One secure method is to connect GitHub with an SSH key.
SSH allows your computer to authenticate with GitHub using a public/private key pair.
Open Git Bash and run:
ls -al ~/.sshLook for files such as:
id_ed25519
id_ed25519.pub
or:
id_rsa
id_rsa.pub
Files ending in .pub are public SSH keys.
If you already have a suitable SSH key, you can use it. Otherwise, generate a new one.
Run:
ssh-keygen -t ed25519 -C "your_email@example.com"Replace:
your_email@example.com
with the email address associated with your GitHub account.
When Git Bash asks where to save the key:
Enter file in which to save the key:
Press Enter to accept the default location.
You may also be asked to enter a passphrase.
After generation, you normally have:
~/.ssh/id_ed25519
~/.ssh/id_ed25519.pub
The file:
id_ed25519
is your private key and should never be shared.
The file:
id_ed25519.pub
is your public key and can be added to GitHub.
Start the SSH agent:
eval "$(ssh-agent -s)"Then add your private SSH key:
ssh-add ~/.ssh/id_ed25519Display the public key:
cat ~/.ssh/id_ed25519.pubCopy the complete output.
It normally starts with:
ssh-ed25519
On GitHub:
- Click your profile picture.
- Open Settings.
- Under Access, select SSH and GPG keys.
- Click New SSH key.
- Enter a descriptive title, such as:
Personal Laptop
- Select Authentication Key as the key type.
- Paste your copied public SSH key into the Key field.
- Click Add SSH key.
- Confirm your GitHub account if GitHub asks you to authenticate.
Your computer can now use the SSH key to authenticate with GitHub.
Run:
ssh -T git@github.comThe first time you connect, GitHub may ask you to confirm the host.
After verifying GitHub's fingerprint, type:
yes
A successful authentication should identify your GitHub username and confirm that authentication succeeded.
Open your private repository on GitHub.
Then:
- Click Code.
- Select SSH.
- Copy the SSH URL.
It will look similar to:
git@github.com:OWNER/REPOSITORY.git
Open Git Bash and run:
git clone git@github.com:OWNER/REPOSITORY.gitGit will authenticate using your SSH key and clone the private repository.
If you already created a project locally using Git, connect it to a GitHub repository with:
git remote add origin <URL>Example:
git remote add origin https://github.com/OWNER/REPOSITORY.gitThis connects your local repository to the GitHub repository and gives that remote the name origin.
Use:
git remote -vExample output:
origin https://github.com/OWNER/REPOSITORY.git (fetch)
origin https://github.com/OWNER/REPOSITORY.git (push)
This shows the remote URLs Git uses for fetching and pushing.
origin is the conventional default nickname Git uses for the remote repository you cloned from.
For example:
git remote add origin https://github.com/OWNER/REPOSITORY.gitHere:
origin
is the nickname, while:
https://github.com/OWNER/REPOSITORY.git
is the actual remote repository URL.
When you clone a repository with git clone, Git normally creates origin automatically.
main is commonly used as the primary branch name for GitHub repositories.
For example:
git push origin mainmeans:
origin → remote GitHub repository
main → branch being pushed
To rename your current branch:
git branch -M <new_branch_name>For example, rename the current branch to main:
git branch -M mainThis is commonly used when changing a branch such as master to main.
To tell Git to initialize future local repositories with main as the initial branch:
git config --global init.defaultBranch mainAfter this configuration, running:
git initwill use main as the initial branch name for new repositories.
To upload the commits from your local main branch to GitHub:
git push origin mainHere:
git push → upload local commits
origin → remote repository
main → branch being pushed
The workflow looks like:
Local Repository
|
| git push origin main
↓
GitHub Repository
Use:
git pullgit pull retrieves changes from the remote repository and integrates them into your current local branch.
A typical pull operation can be understood as:
git pull
↓
git fetch
+
integrate remote changes
↓
Updated Local Branch
For example:
git pull origin mainThis retrieves the latest changes from origin/main and integrates them into your current branch.
Use:
git fetchgit fetch downloads information about new commits, branches, and other updates from the remote repository without automatically merging those changes into your current local branch.
For example:
git fetch originThink of the difference as:
git fetch
Remote → Download updates → Local remote-tracking branches
No automatic merge
while:
git pull
Remote → Download updates → Integrate into current branch
| Command | What It Does |
|---|---|
git pull |
Downloads remote changes and integrates them into your current branch. |
git fetch |
Downloads remote updates without automatically integrating them into your current branch. |
For an existing local Git repository:
# connect local repository to GitHub
git remote add origin <URL>
# verify the remote
git remote -v
# rename current branch to main
git branch -M main
# push local commits to GitHub
git push origin main
# retrieve and integrate remote changes
git pull origin main
# retrieve remote updates without integrating them
git fetch originThe basic relationship is:
Local Git Repository
↕
push / pull
↕
GitHub Remote Repository
| Command | Purpose |
|---|---|
git clone <URL> |
Downloads a complete copy of a repository. |
git remote add origin <URL> |
Connects a local repository to a remote GitHub repository. |
git remote -v |
Shows configured remote repository URLs. |
git branch -M main |
Renames the current branch to main. |
git config --global init.defaultBranch main |
Makes main the initial branch name for future local repositories. |
git push origin main |
Pushes commits from the local main branch to GitHub. |
git pull |
Retrieves remote changes and integrates them into the current branch. |
git fetch |
Retrieves remote changes without automatically integrating them. |
ssh -T git@github.com |
Tests SSH authentication with GitHub. |
Click here 👉 Table of Contents to return back to the Table of Contents.
GitHub Desktop is a free, open-source graphical user interface (GUI) that lets you work with Git and GitHub without typing Git commands manually.
Using GitHub Desktop, you can:
- Create and clone repositories
- Make commits
- Create and switch branches
- Push changes to GitHub
- Pull changes from GitHub
- Create pull requests
- Work with forks
- Review your Git history visually
Step 1: Go to desktop.github.com.
Step 2: Download GitHub Desktop for your operating system.
For Windows:
- Click Download for Windows.
- Open the downloaded setup file.
- Wait for the installation to complete.
- GitHub Desktop will launch automatically.
For macOS:
- Download GitHub Desktop for macOS.
- Open the downloaded file.
- Extract and open the GitHub Desktop application.
- Launch GitHub Desktop.
After installing GitHub Desktop, connect it to your GitHub account.
On Windows:
- Open GitHub Desktop.
- Go to File → Options.
- Open the Accounts section.
- Click Sign Into GitHub.com.
- Click Continue With Browser.
- Sign in to your GitHub account in the browser.
- Complete two-factor authentication if enabled.
- Allow the browser to return you to GitHub Desktop.
Once authenticated, GitHub Desktop can communicate with repositories on your GitHub account.
You can create a Git repository directly from GitHub Desktop.
Step 1: Open GitHub Desktop.
Step 2: Select:
File → New Repository
If you have no repositories added yet, you may instead see:
Create a New Repository on your Hard Drive
Step 3: Enter the repository information.
Name
Enter the repository name.
Example:
hello-github-desktop
Description
Optionally describe what the project does.
Example:
A practice repository for learning GitHub Desktop
Local Path
Choose where the repository should be stored on your computer.
Example:
Documents/GitHub/
GitHub Desktop will create the repository folder inside that location.
Initialize this repository with a README
Enable this option if you want GitHub Desktop to automatically create a README.md file.
Git Ignore
Optionally select a .gitignore template depending on the technology you are using.
Examples:
Python
Node
VisualStudio
Unity
License
Optionally select a software license.
Step 4: Click:
Create Repository
The repository now exists locally on your computer.
Creating a repository in GitHub Desktop does not automatically make it available on GitHub.
You need to publish it.
Step 1: Open the repository in GitHub Desktop.
Step 2: Click:
Publish repository
Step 3: Review the repository name.
Example:
hello-github-desktop
Step 4: Add or update the description if required.
Step 5: Choose the repository visibility.
GitHub Desktop provides the option:
Keep this code private
If selected:
Private Repository
If unselected:
Public Repository
Step 6: If you belong to a GitHub organization, optionally choose the organization where you want to publish the repository.
Otherwise, publish it under your personal GitHub account.
Step 7: Click:
Publish Repository
Your local repository is now connected to a remote repository on GitHub.
A public repository can be viewed by anyone on the internet.
You can test this by copying the repository URL and opening it in an incognito or private browser window.
Public Repository
↓
Anyone can view it
A private repository can only be viewed by you and people who have been given access.
Private Repository
↓
Authorized users only
If someone without permission tries to access a private repository, GitHub generally treats the resource as unavailable and may display:
404
This is not the web page you are looking for.
This prevents unauthorized users from confirming the contents of the private repository.
Open the project files in your preferred editor and make your changes.
GitHub Desktop automatically detects modified files.
The Changes tab will show the files that changed.
Enter a commit message:
add project documentation
Then click:
Commit to main
After committing, upload the commit to GitHub by clicking:
Push origin
The basic workflow becomes:
Edit Files
↓
GitHub Desktop Detects Changes
↓
Write Commit Message
↓
Commit to Branch
↓
Push origin
↓
GitHub
Branches allow you to work on a feature or fix without directly changing the stable main branch.
Step 1: Open your repository in GitHub Desktop.
Step 2: At the top of GitHub Desktop, click:
Current Branch
Step 3: Select the branch that should be the starting point.
Usually:
main
Step 4: Click:
New Branch
Step 5: Enter a branch name.
Example:
feature/login
or:
feature/search
Step 6: Confirm that the branch is based on the correct branch.
For example:
Create branch based on: main
Step 7: Click:
Create Branch
GitHub Desktop automatically switches to the newly created branch.
The structure may now look like:
main
\
feature/login
A new branch created in GitHub Desktop initially exists only on your computer.
To make it available on GitHub:
Step 1: Make sure your new branch is selected.
Example:
feature/login
Step 2: Click:
Publish branch
The branch is now available on GitHub.
A Pull Request (PR) is a proposal to merge changes from one branch or fork into another branch.
For example:
feature/login
↓
Pull Request
↓
Review
↓
main
A pull request lets the repository maintainer review:
- What files changed
- What code was added or removed
- Commit history
- Discussions and comments
- Automated checks
- Possible merge conflicts
A change itself is not automatically a pull request.
A pull request is created when someone proposes that their branch or fork should be merged into another branch, usually main.
Suppose you created:
feature/login
and now want to merge it into:
main
Step 1: Make your changes on feature/login.
Step 2: Review the files in the Changes tab.
Step 3: Enter a meaningful commit message.
Example:
add login form validation
Step 4: Click:
Commit to feature/login
Step 5: Upload your branch using:
Push origin
or, if it has never been uploaded before:
Publish branch
Step 6: GitHub Desktop will provide the option:
Preview Pull Request
Click it.
Step 7: Confirm the base branch.
For example:
base: main
Your current branch will contain the proposed changes:
feature/login → main
Step 8: Review the differences shown in GitHub Desktop.
Step 9: Click:
Create Pull Request
GitHub Desktop will open GitHub in your web browser.
Step 10: Enter a meaningful pull request title.
Example:
Add login form validation
Step 11: Add a description explaining the changes.
Example:
This pull request adds validation for empty username and password fields.
Step 12: Click:
Create pull request
Your pull request is now ready for review.
Before merging a pull request, review the proposed changes.
Step 1: Open the repository on GitHub.
Step 2: Click:
Pull requests
Step 3: Open the pull request you want to review.
Step 4: Review:
Conversation
Commits
Checks
Files changed
Pay particular attention to:
Files changed
to understand exactly what code will be added or removed.
Step 5: Make sure the pull request has no unresolved problems or merge conflicts.
If the repository uses required reviews or automated checks, those requirements must be satisfied before merging.
Step 6: When the changes are ready, click:
Merge pull request
Depending on the repository configuration, GitHub may also provide:
Squash and merge
Rebase and merge
Step 7: Confirm the merge by clicking:
Confirm merge
The changes are now part of the base branch, such as:
main
Step 8: Optionally click:
Delete branch
if the feature branch is no longer needed.
The complete workflow is:
Create Branch
↓
Make Changes
↓
Commit
↓
Push / Publish Branch
↓
Create Pull Request
↓
Review Changes
↓
Merge Pull Request
↓
main Updated
A fork creates your own copy of another repository under your GitHub account.
The fork remains connected to the original repository, which GitHub commonly refers to as the upstream repository.
Example:
Original Repository
github.com/original-owner/project
↓
Fork
↓
Your Repository
github.com/your-username/project
A fork allows you to:
- Experiment with someone else's project without changing the original repository
- Maintain your own version of the project
- Create branches and commits independently
- Contribute changes back to the original repository using a pull request
Step 1: Open the repository you want to fork.
Step 2: Click:
Fork
in the upper-right area of the repository page.
Step 3: Select the owner for the fork.
Usually this will be your personal GitHub account.
Step 4: Keep or change the repository name.
GitHub normally uses the same repository name as the original.
Step 5: Optionally add a description.
Step 6: Optionally enable:
Copy the DEFAULT branch only
For many contribution workflows, copying only the default branch is enough.
Step 7: Click:
Create fork
GitHub creates the fork under your account.
After creating the fork, download it to your computer using GitHub Desktop.
Step 1: Open your fork on GitHub.
The URL should now contain your username.
Example:
github.com/YOUR-USERNAME/PROJECT
Step 2: Click:
Code
Step 3: Select:
Open with GitHub Desktop
GitHub Desktop will open automatically.
Step 4: Choose the local path where you want to store the repository.
Example:
Documents/GitHub/
Step 5: Click:
Clone
Your fork now exists:
Original Repository
↓
Fork
↓
Your GitHub Account
↓
Clone
↓
Your Computer
You can now create branches and make changes using GitHub Desktop.
When contributing to a repository where you do not have direct write access, a common workflow is:
Fork Original Repository
↓
Clone Your Fork
↓
Create Feature Branch
↓
Make Meaningful Changes
↓
Commit Changes
↓
Push Branch
↓
Open Pull Request
↓
Original Repository Maintainer Reviews It
↓
Merge if Approved
Your pull request can propose that changes from your fork be merged into the original repository.
Do not create pull requests simply to increase activity on your GitHub profile.
Before contributing:
- Understand the repository and its purpose.
- Read
README.md. - Check
CONTRIBUTING.mdif available. - Read existing issues and pull requests.
- Make sure your change is useful.
- Follow the project's contribution guidelines.
- Test your changes before submitting them.
- Write a clear pull request title and description.
Always open a pull request after making meaningful and relevant changes.
Unnecessary pull requests can create extra work for repository maintainers.
A GitHub Star works similarly to bookmarking or showing appreciation for a repository.
If you find a repository useful or interesting:
Step 1: Open the repository on GitHub.
Step 2: Click:
Star
Starring a repository makes it easier to find later and also shows appreciation for the project.
You can think of it simply as:
Star ≈ Bookmark + Appreciation
A useful way to understand Git and GitHub Desktop is to practice the complete collaboration workflow with a friend.
Create a simple test repository and practice:
Create Repository
↓
Publish Repository
↓
Clone Repository
↓
Create Branches
↓
Make Changes
↓
Commit Changes
↓
Push Changes
↓
Pull Changes
↓
Create Pull Requests
↓
Review Each Other's Code
↓
Merge Pull Requests
You can also fork each other's sample repositories and practice contributing through forks.
This creates a realistic workflow for understanding GitHub collaboration and helps you become more comfortable working with repositories, branches, commits, reviews, and pull requests.
Repository
↓
Create / Clone
↓
Create Branch
↓
Edit Files
↓
Review Changes
↓
Commit
↓
Push / Publish
↓
Pull Request
↓
Review
↓
Merge into main
| Action | GitHub Desktop / GitHub |
|---|---|
| Create repository | File → New Repository |
| Publish local repository | Publish repository |
| View changed files | Changes |
| Save changes | Commit to <branch> |
| Upload commits | Push origin |
| Download remote updates | Fetch origin / Pull origin |
| Create branch | Current Branch → New Branch |
| Switch branch | Current Branch → Select Branch |
| Upload new branch | Publish branch |
| Create pull request | Preview Pull Request → Create Pull Request |
| Merge pull request | GitHub → Merge pull request |
| Fork repository | GitHub → Fork |
| Clone to Desktop | GitHub → Code → Open with GitHub Desktop |
| Star repository | GitHub → Star |
Click here 👉 Table of Contents to return back to the Table of Contents.
VS Code has built-in Git support in the Source Control panel, showing changed files, the staging area, and a commit box, all without leaving the editor.
Open the Source Control panel using:
Windows / Linux
Ctrl + Shift + G
macOS
Cmd + Shift + G
The Source Control panel shows:
- Changed files
- Staged changes
- Unstaged changes
- Commit message box
- Repository actions
Files you modify appear under the Changes section.
1. Stage one file
Click the + icon next to a changed file.
Terminal equivalent:
git add filename.py2. Stage all changes
Click the + icon next to Changes.
Terminal equivalent:
git add .3. Unstage a file
Under Staged Changes, click the - icon next to the file.
Every action in the Source Control interface maps to Git commands underneath.
After staging your changes:
Step 1: Type a commit message in the message box at the top of the Source Control panel.
Example:
add user authentication
Step 2: Click the Commit checkmark button.
Terminal equivalent:
git commit -m "add user authentication"VS Code can synchronize your local and remote repository using the Sync Changes button or circular arrows icon.
Click:
Sync Changes
This synchronizes remote and local changes by pulling incoming changes and pushing your outgoing commits.
Terminal equivalent:
git pull origin main
git push origin mainClick any modified file inside the Source Control panel.
VS Code opens a diff editor that lets you compare the previous version with your current changes.
Terminal equivalents:
# view unstaged changes
git diff
# view staged changes
git diff --stagedThis makes it easier to review exactly what was added, removed, or modified before committing.
VS Code provides a Timeline view for examining the history of a file.
To view it:
- Open the file in VS Code.
- Open the Explorer panel.
- Find the Timeline section for the file.
- Review its previous commits and changes.
You can also right-click a file and use the available timeline/history options.
Terminal equivalent:
git log --oneline -- filename.pyThis displays commits that affected that specific file.
Your current Git branch appears in the bottom-left area of the VS Code status bar.
Click the branch name to create or switch branches.
Click the current branch name and select:
Create new branch...
Enter a branch name such as:
feature/new-branch
Terminal equivalent:
git switch -c feature/new-branchClick the branch name and select the branch you want.
For example:
main
Terminal equivalent:
git switch mainWhen Git detects a merge conflict, VS Code highlights the conflicting sections directly inside the editor.
A conflict may look like:
<<<<<<< HEAD
your current code
=======
incoming code
>>>>>>> feature/search
VS Code provides actions for resolving the conflict.
Accept Current / Keep Mine
Keeps the version from your current branch.
Current Version
Accept Incoming / Keep Theirs
Keeps the incoming version from the branch being merged.
Incoming Version
Accept Both / Keep Both
Keeps both versions in the file.
Current Version
Incoming Version
After resolving the conflict, stage the file and commit the resolution.
git add filename.py
git commit -m "resolve merge conflict"If you have created a local Git repository that is not yet hosted on GitHub, VS Code can publish it directly.
Step 1: Open the project in VS Code.
Step 2: Open Source Control.
Ctrl + Shift + G
or on macOS:
Cmd + Shift + G
Step 3: If required, initialize the repository by clicking:
Initialize Repository
Step 4: Create and commit your project files.
Step 5: Click:
Publish to GitHub
Step 6: Sign in to GitHub if VS Code asks you to authenticate.
Step 7: Choose whether the repository should be:
Public
or:
Private
Step 8: Select the files you want to include.
VS Code then creates the GitHub repository and publishes your local commits.
The equivalent Git workflow includes commands such as:
git remote add origin https://github.com/username/repo.git
git push -u origin mainFor a visual representation of branches, commits, and merges, you can install the Git Graph extension by mhutchie.
Open Extensions:
Ctrl + Shift + X
Then search for:
Git Graph
Click:
Install
After installation, open the Command Palette:
Ctrl + Shift + P
Search for:
Git Graph: View Git Graph
Select it to open the visual Git history.
A Git graph helps you visualize:
C─D
/ \
A─B─E─────M
This makes branch creation, commits, merges, and repository history easier to understand.
Edit Files
↓
Source Control
↓
Review Changes
↓
Stage (+)
↓
Write Commit Message
↓
Commit (✓)
↓
Sync / Push
↓
GitHub
Click here 👉 Table of Contents to return back to the Table of Contents.
When multiple people work on the same repository, GitHub helps manage contributors, tasks, and discussions.
To invite someone to your GitHub repository:
- Open your repository on GitHub.
- Go to Settings.
- Click Collaborators.
- Click Add people.
- Search for the person's GitHub username or email.
- Select the user and send the invitation.
- The user must accept the invitation before they can contribute.
GitHub Issues are used to track bugs, features, tasks, or improvements.
To create an issue:
- Open your repository.
- Click the Issues tab.
- Click New issue.
- Fill in the issue details.
- Click Submit new issue.
| Field | Purpose |
|---|---|
| Title | Short name of the issue or task. |
| Description | Explains the problem, feature, or task in detail. |
| Assignees | Shows who is responsible for the issue. |
| Labels | Categorizes the issue, such as bug, enhancement, or documentation. |
| Project | Adds the issue to a GitHub Project for better task management. |
| Milestone | Groups related issues under a larger goal or release. |
| Relationships | Connects related or dependent issues. |
| Development | Links branches and pull requests to the issue. |
| Close issue | Marks the issue as completed or no longer needed. |
GitHub Issues also work like a discussion thread.
You can:
- Comment on an issue
- Reply to other contributors
- Mention users with
@username - Add emoji reactions such as 👍 ❤️ 🎉
- Discuss the task with your team
- Close the issue when the work is finished
A simple workflow is:
Create Issue
↓
Assign Contributor
↓
Discuss the Task
↓
Work on the Issue
↓
Close the Issue
Click here 👉 Table of Contents to return back to the Table of Contents.
AI tools can generate and modify code very quickly. Git helps you keep those changes safe by letting you review, commit, and roll back AI-generated work.
Before letting AI make major changes, save your current working state:
git add .
git commit -m "working state before AI refactor"After AI makes changes, review them before committing:
git diff
git add .
git commit -m "AI-generated dashboard layout"If the AI changes are not useful, you can roll them back:
git restore .Or roll back the last commit:
git reset --hard HEAD~1Never commit AI-generated code blindly.
Check every changed line:
git diffSee a quick summary of changed files:
git diff --statSome AI tools can suggest commit messages for you.
Always review and improve them so they clearly describe the change.
Bad:
git commit -m "update files"Good:
git commit -m "add input validation to signup form"Start your work by getting the latest changes and creating a new branch:
git pull origin main
git switch -c feature/todays-workCommit each logical change during your session:
git add .
git commit -m "describe each logical step"At the end of your session, publish the branch:
git push -u origin feature/todays-workThen open a pull request on GitHub.
| Command | When to Use It |
|---|---|
git diff |
Review every changed line before staging. |
git diff --stat |
See a file-by-file summary of changes. |
git restore . |
Discard uncommitted changes after a bad AI edit. |
git reset --hard HEAD~1 |
Remove the latest commit and its changes. |
git switch -c name |
Create and switch to a new branch. |
git push -u origin name |
Publish the branch to GitHub. |
Click here 👉 Table of Contents to return back to the Table of Contents.
Good Git habits make your project history easier to understand, review, and roll back.
- Commit frequently — small commits are easier to review and undo.
- Keep commits small — one logical change per commit.
- Use clear present-tense messages — describe exactly what changed.
git commit -m "add email field to form"
git commit -m "fix null check in user parser"
git commit -m "add dark mode toggle to settings"Keep each feature isolated in its own branch.
git switch -c feature/dark-modeWork only on that feature inside the branch, then merge it when it is ready.
Sync with the remote repository before pushing your changes.
git pull origin main
git push origin mainThis helps reduce unnecessary conflicts.
Never commit:
- API keys
- Passwords
.envfiles- Other private credentials
If .env is already tracked:
git rm --cached .env
echo ".env" >> .gitignore
git commit -m "remove env file from tracking"If a secret was ever committed, rotate or replace it immediately. Removing it from Git does not undo the exposure.
Create .gitignore early so unwanted files are never tracked.
echo ".env" >> .gitignore
echo "__pycache__/" >> .gitignore
echo ".DS_Store" >> .gitignore
git add .gitignore
git commit -m "add gitignore"Always review your changes before saving them to Git history.
# check what changed
git status
# review unstaged changes
git diff
# review staged changes
git diff --staged
# commit with a clear message
git commit -m "your message"| Command | What It Does |
|---|---|
git status |
Shows what has changed before staging or committing. |
git diff |
Reviews unstaged changes. |
git diff --staged |
Reviews exactly what the next commit will contain. |
git rm --cached file |
Stops tracking a file without deleting it locally. |
git switch -c name |
Creates and switches to a new feature branch. |
Quick reference for common Git commands you will use again and again.
| Command | What It Does |
|---|---|
git init |
Starts a new Git repository. |
git clone <url> |
Copies a remote repository to your computer. |
git status |
Shows the current repository state. |
git status -s |
Shows a short, compact status. |
| Command | What It Does |
|---|---|
git add <file> |
Stages one file. |
git add . |
Stages all changes. |
git add -p |
Stages changes interactively, hunk by hunk. |
git commit -m "msg" |
Saves staged changes as a commit. |
git commit -am "msg" |
Stages tracked files and commits them in one step. |
| Command | What It Does |
|---|---|
git branch |
Lists local branches. |
git branch -a |
Lists local and remote branches. |
git switch <branch> |
Switches to an existing branch. |
git switch -c <branch> |
Creates and switches to a new branch. |
git merge <branch> |
Merges a branch into the current branch. |
git branch -d <branch> |
Deletes a local branch. |
| Command | What It Does |
|---|---|
git remote -v |
Shows connected remote repositories. |
git remote add origin <url> |
Connects your local repo to GitHub. |
git push -u origin main |
First push and sets the upstream branch. |
git push |
Pushes commits to the tracked remote branch. |
git pull origin main |
Downloads and merges remote changes. |
git fetch origin |
Downloads remote changes without merging them. |
| Command | What It Does |
|---|---|
git log |
Shows full commit history. |
git log --oneline |
Shows compact commit history. |
git log --oneline --graph --all |
Shows a visual graph of all branches. |
git show <commit> |
Shows details of a specific commit. |
git diff |
Shows unstaged changes. |
git diff --staged |
Shows staged changes. |
Use
git fetchwhen you want to review remote changes before merging.git pulldownloads and integrates them in one step.
| Command | What It Does |
|---|---|
git restore <file> |
Discards unstaged changes in a file. |
git restore --staged <file> |
Unstages a file but keeps its changes. |
git reset --soft HEAD~1 |
Undoes the last commit but keeps changes staged. |
git reset --hard HEAD~1 |
Undoes the last commit and discards its changes. |
git revert <commit> |
Safely creates a new commit that undoes an earlier commit. |
git stash |
Temporarily saves uncommitted work. |
git stash pop |
Restores the latest stashed work. |
Prefer
git revertinstead ofgit reset --hardwhen a commit has already been pushed and shared with others.
# get the latest changes
git pull origin main
# create a feature branch
git switch -c feature/my-feature
# edit files
# stage changes
git add .
# commit changes
git commit -m "add my feature"
# publish the branch
git push -u origin feature/my-feature
# open a pull request on GitHub
Click here 👉 Table of Contents to return back to the Table of Contents.
You started with the basics: what version control is, how commits and branches work, and the core commands that drive every workflow. From there, you learned to collaborate with others, resolve conflicts, undo mistakes, and use GitHub to share and review code.
The real skill comes from practice. Use Git on every project, even small ones. Commit often, write clear messages, and pull before you push. When something goes wrong, you have the tools to fix it.
Click the box below to visit the author's GitHub profile and explore more projects, open-source work, and contributions.
Muhammad Zeeshan Islam 💻 📖 |