Your files on disk exist independently; Git only “knows” them once they’re tracked.
Your project's folder on your computer, where you:
- Create and edit files
- Delete or move folders 💡 It’s your live workspace, but Git doesn’t automatically track changes here.
Git manages changes in two key areas:
git add <filename>
git commit -m "message"
State | Description | Commands |
---|---|---|
🗂️ Working Directory | Your project’s current files on disk | ls , cat |
📝 Staging Area | Changes queued for the next commit | git add , git status |
🏛️ Repository | Versioned history of confirmed changes | git commit , git log |
Working Directory → Staging Area → Repository
(edit files) (git add) (git commit)
- Edit
README.md
→ Git is unaware of changes. - Run
git add README.md
→ Changes are staged. - Run
git commit -m "Update README"
→ Changes are saved in the repository.
In a Git repository, files can exist in two primary states: Untracked and Tracked.
- A file is untracked when it hasn't been added to the Git repository yet.
- Git does not recognize or monitor the file in this state.
- A tracked file is one that Git is managing.
- Tracked files can exist in one of the following substates:
- The file has not changed since the last commit.
- The file has been edited since the last commit.
- Changes have not yet been staged for the next commit.
- The modified file has been added to the staging area (also called the index).
- These changes are ready to be committed.
- The file’s current version has been saved in Git’s database.
- It represents the latest committed version of the file.
Before using Git, configure your identity. These settings are stored globally and used for all repositories on your machine.
git config --global user.email "[email protected]"
git config --global user.name "your_name"
This sets your Git author information globally, ensuring that all commits reflect your name and email.
To start tracking a project with Git, navigate to your project directory and initialize a new repository:
git init
This creates a .git
directory in your project, establishing it as a Git repository. By default, Git also creates a primary branch named main
.
Use the git status
command to inspect the current state of the working directory and staging area:
git status
Example output:
On branch main
nothing to commit, working tree clean
This indicates that you are on the main
branch and that there are no changes staged or unstaged.
To add files to the staging area (preparing them for a commit):
git add <filename> # Adds a specific file
git add . # Adds all changes in the current directory
Files must be staged before they can be committed.
Commit staged changes to the local repository:
git commit -m "Your commit message here"
You can also commit changes to already tracked files (i.e., previously committed files that have been modified) in one step:
git commit -am "Update tracked files with changes"
Important
git commit -am
only works for files that Git is already tracking. New files must be staged with git add
first.
Example:
echo "1. TODO_1" >> README.md
git add README.md
git commit -m "Add initial TODO entry"
Every time you make a commit, it's like taking a snapshot of your project's files exactly as they are at that moment in time. You're telling Git:
“This is a version I want to remember.”
Just like a time machine, Git lets you travel back to any previous commit. You can see what your project looked like, what changed, and why. This makes collaboration safe, debugging easier, and progress traceable.
To review the commit history of the current branch in a concise format:
git log --oneline
This displays a summarized list of commits, showing the short commit hash and message for each entry.
To inspect changes made to files since the last commit, use the git diff
command. This allows you to see line-by-line differences between your working directory and the staging area (or the last commit).
git diff
The .gitignore
file tells Git which files or directories to ignore (not track) in your project. This is useful for excluding:
- Build artifacts (e.g.,
dist/
,build/
,coverage/
) - Temporary or cache files (e.g.,
*.tmp
,*.log
,*.swp
) - Operating system files (e.g.,
.DS_Store
,Thumbs.db
)
# Ignore all log files
*.log
# Ignore node_modules directory
node_modules/
# Ignore system files
.DS_Store
# Ignore compiled Python files
__pycache__/
*.pyc
Place the .gitignore
file in the root of your repository. Git will respect the patterns and avoid tracking matching files.
By default, Git does not track empty directories. If a folder has no tracked files, it will be ignored entirely—even if it exists in your project structure.
You want to keep a folder (e.g., logs/
, uploads/
, data/
) in the repository even though it's currently empty or only used at runtime.
mkdir uploads/
touch uploads/.git-keep
git add uploads/.git-keep
git commit -m "Keep empty uploads directory"
This will ensure the uploads/
directory is committed and remains in the repository.
If you need to update the last commit then simply make your edits, stage them with git add
, and run one of the follwoing commands:
Command | Effect |
---|---|
git commit --amend |
Amend last commit and open message editor |
git commit --amend -m "..." |
Amend last commit with new message |
git commit --amend --no-edit |
Amend last commit without changing message |
Important
Always double-check with git log
after amending to confirm the result.
todo
git switch -c path_config
# Switched to a new branch 'path_config'
git branch --all
git branch -r
Undo chnages to tracked file:
git reset HEAD --hard
git checkout --orphan last
git add -A
git commit -am "fresh init"
git branch -D main
git branch -m main
git push -f origin main
git bisect start
git bisect bad
git bisect good
git clone --mirror [email protected]:lifeparticle/binarytree.git
bfg --strip-blobs-bigger-than 1M binarytree.git
cd binarytree.git
A---B---C---D---E (develop)
\
F---G (feature branch)
\
H (merge commit: 9343dSwd)
H has two parents:
Parent 1: commit E (mainline — usually develop)
Parent 2: commit G (feature branch)
git revert -m 1 H
Git will:
- Keep the content as it was in E
- Undo the changes from the feature branch (G)
- Create a new commit that undoes the merge.
In the following examples, we switch to a realistic feature development scenario involving a CRM tool, where the file customer.css
was mistakenly deleted in a branch called feature/customer-ui
.
Assume you're working on a feature branch called feature/customer-ui
. The Git history looks like this:
git log --oneline
c7fa91e (HEAD -> feature/customer-ui) Remove customer stylesheet
a1e02dc Add customer search filters
7f32ab1 Create customer.css with responsive layout
2bdce90 Initial project setup
Suppose commit c7fa91e
(Remove customer stylesheet
) was a mistake — for example, a teammate accidentally removed customer.css
, thinking it was obsolete. You haven’t pushed this branch yet and want to undo the commit completely, including any staged or working changes.
git reset --hard HEAD^
Result:
- The repository is reset to commit
a1e02dc
customer.css
is restored in your working directory- Commit
c7fa91e
is removed from the branch history - Working directory is clean and matches the state after
Add customer search filters
- History now ends at:
git log --oneline
a1e02dc (HEAD -> feature/customer-ui) Add customer search filters
7f32ab1 Create customer.css with responsive layout
2bdce90 Initial project setup
When to Use This:
- Use this if you want to completely undo the last commit — including all its changes.
- Rolls back the entire repository to the state of the previous commit.
- Deletes the most recent commit and restores the working directory to the previous state.
- However, untracked files (e.g., new files not added to Git) will not be deleted.
Caution
Destructive: You will lose all changes made in that commit and any uncommitted changes. Use with caution, especially on shared branches.
Suppose you're still on the feature/customer-ui
branch, and the latest commit mistakenly deleted customer.css
:
git log --oneline
c7fa91e (HEAD -> feature/customer-ui) Remove customer stylesheet
a1e02dc Add customer search filters
7f32ab1 Create customer.css with responsive layout
2bdce90 Initial project setup
You don’t want to undo the entire commit because it includes valid updates (e.g., layout tweaks or minor UI changes). You just want to bring back the deleted file.
To restore only customer.css
from the previous commit:
git restore --source=HEAD~1 src/styles/customer.css
git add src/styles/customer.css
git commit -m "Restore customer.css after mistaken removal"
Result:
customer.css
is restored in your working directory- Other changes from the last commit remain untouched
- A new commit is added to clearly document the file restoration
git log --oneline
d34c123 Restore customer.css after mistaken removal
c7fa91e Remove customer stylesheet
a1e02dc Add customer search filters
...
When to Use This:
-
You want to restore a specific file from a previous commit This restores the file from the last commit (i.e.,
HEAD
) as it existed before deletion. -
You don’t want to affect or undo other parts of the latest commit
-
You're fixing a mistake while keeping the history clean and meaningful
Let’s say you're working on feature/customer-ui
, and the commit c7fa91e
(Remove customer stylesheet
) was already pushed to a shared remote. Rewriting history is no longer safe — but you still need to undo the file deletion.
Instead of using reset
, you can safely reverse the commit by running:
git revert c7fa91e
Result:
- Git creates a new commit that undoes the changes made in
c7fa91e
customer.css
is restored in the working directory- Original commit history remains untouched
- Your team can clearly see what was undone and when
git log --oneline
f51b847 (HEAD -> feature/customer-ui) Revert "Remove customer stylesheet"
c7fa91e Remove customer stylesheet
a1e02dc Add customer search filters
...
When to Use This:
- The branch has already been pushed or merged
- You want to preserve history and maintain team visibility
- You want to reverse a specific commit without affecting others
Command | Description | Affects Working Directory? | Affects Commit History? | Risk Level |
---|---|---|---|---|
git reset --hard HEAD^ |
Resets the entire repository to the previous commit, discarding the latest commit and all local changes | Yes (resets all tracked files) | Yes (rewrites history) | Dangerous (irreversible) |
git restore --source=HEAD~1 src/styles/customer.css |
Restores a deleted file from a previous commit without altering other changes | Yes (restores only the file) | No (history is preserved) | Safe |
git revert <commit_hash> |
Reverts the effect of a previous commit by creating a new inverse commit | Yes (applies reversed changes) | No (history is preserved) | Safe (non-destructive) |
todo
Fork is a feature provided by hosting platforms like GitHub—not a Git command—that creates a copy of a repository under your own account on the server, allowing independent development. Clone is a Git command that downloads any repository (including forks) to your local machine so you can work on it offline.
Other Key features provided by GitHub include:
- Issues
- Discussions
- Pull requests
- Notifications
- Labels
- Actions
- Projects
Revert adds a new commit to undo; reset moves the pointer as if a commit never happened.