
Git is "essential" in modern software development—
mastering it unlocks efficient collaboration and code management!

# Introduction to `git` Command

## What is Git?

**Git** is a **distributed version control system** (VCS) 
Git distributed version control system 

that tracks changes to files over time. 
It enables collaboration, 
version history, and branching workflows. 
Created by Linus Torvalds in 2005 for Linux kernel development.

## Why Use Git?

- **Version History:** Track every change, see who changed what and when
- **Branching:** Work on features independently without affecting main code
- **Collaboration:** Multiple developers work on the same project simultaneously
- **Backup:** Distributed copies protect against data loss
- **Rollback:** Easily revert to previous states
- **Code Review:** Pull requests enable peer review before merging

## Core Concepts

| Term | Meaning |
|------|---------|
| **Repository** | A folder containing your project + `.git` directory with history |
| **Commit**     | A snapshot of your code at a point in time with a message |
| **Branch**     | A parallel line of development (default: `main` or `master`) |
| **Remote**     | A copy of repo on a server (e.g., GitHub, GitLab) |
| **Staging Area** | Files ready to be committed |
| **Working Directory** | Your local folder with actual files |

## Basic Workflow

```
1. git init              # Initialize repository
2. git add <file>       # Stage changes
3. git commit -m "msg"  # Save snapshot
4. git push             # Send to remote server
5. git pull             # Get updates from remote
```

## Essential Commands

| Command | Purpose |
|---------|---------|
| `git init`   | Create new repository |
| `git clone <url>` | Copy existing repository |
| `git add <file>`  | Stage files for commit |
| `git commit -m "msg"` | Save snapshot with message |
| `git push`   | Send commits to remote |
| `git pull`   | Fetch and merge from remote |
| `git branch` | List/create branches |
| `git checkout -b <branch>` | Create and switch to new branch |
| `git merge <branch>`       | Combine branches |
| `git log`    | View commit history |
| `git status` | Show current state |
| `git diff`   | Show changes |

## Three-State Architecture

```
Working Directory → Staging Area → Repository (.git)
    (Modify)          (git add)    (git commit)
```

## Configuration

```bash
# First time setup
git config --global user.name "Your Name"
git config --global user.email "your@email.com"

# View config
git config --list
```

## Common Workflow Example

```bash
git clone https://github.com/user/project.git  # Get repo
cd project
git checkout -b feature-x                        # Create branch
# ... edit files ...
git add .                                        # Stage changes
git commit -m "Add feature X"                    # Commit
git push origin feature-x                        # Push branch
# Create Pull Request on GitHub
```

## 

Choose which parts of a file to stage:
git add -p

Move file:
git mv <old> <new>

Delete file:
git rm <file>

Tell Git to forget about a file without deleting it:
git rm --cached <file>

Unstage one file:
git reset <file>

Unstage everything:
git reset

Check what you added:
git status

### Make Commits

Make a commit (and open text editor to write message):
git commit

Make a commit:
git commit -m 'message'

Commit all unstaged changes:
git commit -am 'message'

### Move Between Branches

Switch branches: # switch to

git switch <name>

OR

git checkout <name>


Create a branch:

git switch -c <name>
OR
git checkout -b <name>

List branches:
git branch

List branches by most recently committed to:
git branch --sort=-committerdate

Delete a branch:
git branch -d <name>

Force delete a branch:
git branch -D <name>

### Diff Staged/Unstaged Changes

Diff all staged and unstaged changes:
git diff HEAD

Diff just staged changes:
git diff --staged

Diff just unstaged changes:
git diff

Diff Commits
Show diff between a commit and its parent:
git show <commit>

Diff two commits:
git diff <commit> <commit>

Diff one file since a commit:
git diff <commit> <file>

Show a summary of a diff:
git diff <commit> --stat
git show <commit> --stat

### Ways to refer to a commit

Every time we say <commit>, you can use any of these:

a branch, main, a tag, v0.1
a commit ID, 3e887ab
a remote branch, origin/main
current commit, HEAD
3 commits ago, HEAD^^^ or HEAD~3

### Discard Your Changes

Delete unstaged changes to one file:
git restore <file>
OR
git checkout <file>

Delete all staged and unstaged changes to one file:

git restore --staged --worktree <file>
OR
git checkout HEAD <file>

Delete all staged and unstaged changes:
git reset --hard

Delete untracked files:
git clean

'Stash' all staged and unstaged changes:
git stash



### Edit History

"Undo" the most recent commit (keep your working directory the same):
git reset HEAD^

Squash the last 5 commits into one:
git rebase -i HEAD~6

Then change "pick" to "fixup" for any commit you want to combine with the previous one

Undo a failed rebase:
git reflog BRANCHNAME

Then manually find the right commit ID in the reflog, then run:

git reset --hard <commit>

Change a commit message (or add a file you forgot):
git commit --amend

### Code Archaeology

Look at a branch's history:
git log main
git log --graph main
git log --oneline

Show every commit that modified a file:
git log <file>

Show every commit that modified a file, including before it was renamed:
git log --follow <file>

Find every commit that added or removed some text:
git log -G banana
Show who last changed each line of a file:
git blame <file>


### Combine Diverged Branches

Combine with rebase:
git switch banana
git rebase main

Before:

 a b c 
     d e

After:

 a b c d'e'
     d e

Combine with merge:
git switch main
git merge banana

Before:

 a-b-c
     d-e

After:

 a-b-c--->
     d-e

Combine with squash merge:
git switch main
git merge --squash banana
git commit

Before:

 a-b-c
   d-e

After:

 a-b-c-de
   d-e

Bring a branch up to date with another branch (aka "fast-forward merge"):
git switch main
git merge banana

Before:

 a-b-c-d-e
     m   b

After:

 a-b-c-d-e m
         b

Copy one commit onto the current branch:
git cherry-pick <commit>

Before:

 a-b-c
   d-e

After:

 a-b-c-d
   d-e

### Restore an Old File

Get the version of a file from another commit:

git checkout <commit> <file>
OR
git restore <file> --source <commit>

Add a Remote
git remote add <name> <url>

### Push Your Changes

Push the main branch to the remote origin:
git push origin main

Push the current branch to its remote "tracking branch":
git push

Push a branch that you've never pushed before:
git push -u origin <name>

Force push:
git push --force-with-lease

Push tags:
git push --tags


### Pull Changes

Fetch changes (but don't change any of your local branches):
git fetch origin main

Fetch changes and then rebase your current branch:
git pull --rebase

Fetch changes and then merge them into your current branch:

git pull origin main
OR
git pull

### Configure Git

Set a config option:
git config user.name 'Your Name'

Set option globally:
git config --global ...

Add an alias:
git config alias.st status

See all possible config options:
man git-config

### Important Files

Local git config:
.git/config

Global git config:
~/.gitconfig




