SE Notes
Fundamental Git concepts and commands for version control in software development projects.
Git is a distributed version control system created by Linus Torvalds in 2005 to manage Linux kernel development. It has since become the de facto standard for source code management across the entire software industry. Understanding Git is not optional for modern software engineers — it is as fundamental as knowing a programming language. Git tracks every change to every file, enables multiple developers to work simultaneously without conflicts, and provides a complete audit trail of project evolution.
How Git Works
Unlike centralized systems (SVN, CVS) where a single server holds the complete history, Git gives every developer a full copy of the repository including its entire history. This distributed model means developers can work offline, commits are instantaneous (no network round-trip), and there is no single point of failure.
Git stores data as snapshots rather than differences. Each commit captures the complete state of all tracked files at that moment. Unchanged files are stored as references to their previous version (efficiently, not duplicated), while changed files are stored as new compressed objects. This snapshot model makes operations like branching and comparing versions extremely fast.
Core Concepts
Repository: A directory containing your project files plus a hidden .git folder that stores all version history, branches, and configuration. Repositories exist locally on your machine and optionally on remote servers (GitHub, GitLab, Bitbucket).
Working Directory: The actual files you see and edit. This represents a single checkout of one version of the project.
Staging Area (Index): An intermediate area where you compose your next commit. You selectively stage changes, choosing exactly what goes into each commit rather than committing all modifications at once.
Commit: A permanent snapshot of the staged changes with a message describing what changed and why. Each commit has a unique SHA-1 hash, a pointer to its parent commit(s), and metadata (author, timestamp).
Essential Git Commands
Repository Setup
git init # Create new repository in current directory
git clone <url> # Copy existing remote repository locallyDaily Workflow
git status # See what has changed since last commit
git add <file> # Stage specific file for next commit
git add . # Stage all changed files
git commit -m "message" # Create commit with staged changes
git push origin main # Upload commits to remote repository
git pull origin main # Download and integrate remote changesBranching and Merging
git branch feature-login # Create new branch
git checkout feature-login # Switch to branch
git checkout -b feature-x # Create and switch in one command
git merge feature-login # Merge branch into current branch
git branch -d feature-login # Delete branch after mergingInspecting History
git log # View commit history
git log --oneline --graph # Compact visual history
git diff # See unstaged changes
git diff --staged # See staged changes
git blame <file> # See who changed each line and whenThe Three-Tree Architecture
Git maintains three "trees" that developers must understand:
- HEAD (last commit): The snapshot of your last commit on the current branch
- Index (staging area): Your proposed next commit
- Working Directory: Your sandbox where you make changes
The workflow is: modify files in working directory → stage selected changes to index → commit index to repository. This three-step process gives you precise control over what goes into each commit.
Branching Model
Branches in Git are incredibly lightweight — creating a branch is simply creating a 41-byte file containing a commit hash. This makes branching a everyday operation rather than the heavyweight process it was in older version control systems.
When you create a branch, you create a new pointer to the current commit. As you make commits on the branch, the pointer moves forward. The main branch continues pointing to its own latest commit. When you merge, Git finds the common ancestor and combines the changes.
Merge Conflicts
When two branches modify the same lines in the same file, Git cannot automatically determine which version to keep. It marks the conflict in the file:
<<<<<<< HEAD
function calculateTotal(price, tax) {
=======
function calculateTotal(price, taxRate) {
>>>>>>> feature-branchYou resolve by editing the file to the desired final state, removing the conflict markers, staging the file, and completing the merge commit. Prevention is better than resolution — communicate with teammates about what files you are modifying, keep branches short-lived, and merge main into your branch frequently.
Best Practices for Git Usage
Write meaningful commit messages. "Fixed bug" tells future developers nothing. "Fix off-by-one error in pagination causing empty last page when total items are divisible by page size" tells them exactly what was wrong and what was fixed.
Make atomic commits. Each commit should represent one logical change. If you fixed a bug and added a feature, make two commits. This makes history readable and enables precise reverts.
Never commit secrets. API keys, passwords, database credentials, and private keys should never enter Git history. Use .gitignore for local configuration files and environment variables for sensitive values. Once committed, secrets persist in history even if deleted in later commits.
Pull before push. Always pull the latest remote changes before pushing your own. This reduces merge conflicts and ensures you are building on the current state of the project.
Real-World Git Workflow
A developer starting their day:
git pull origin main— get latest changes from teamgit checkout -b feature/JIRA-234-password-reset— create branch for today's task- Write code, run tests, verify changes work
git add src/auth/password-reset.js src/auth/password-reset.test.js— stage relevant filesgit commit -m "Implement password reset token generation and email delivery"— commit with clear messagegit push origin feature/JIRA-234-password-reset— push to remote- Open pull request for code review
- After approval, merge to main and delete branch
Interview Q&A
Q: What is the difference between git merge and git rebase? A: Merge creates a new commit combining two branch histories, preserving the complete history with a merge commit. Rebase replays your branch's commits on top of the target branch, creating a linear history. Merge is safer (never rewrites history), while rebase produces cleaner history but should never be used on shared branches.
Q: What is git stash and when would you use it? A: Git stash temporarily saves uncommitted changes without creating a commit, returning your working directory to a clean state. Use it when you need to quickly switch branches (to fix a production bug) without committing incomplete work. Apply the stash later with git stash pop to restore your changes.
Q: How do you undo the last commit without losing changes? A: git reset --soft HEAD~1 moves the HEAD pointer back one commit while keeping all changes staged. git reset --mixed HEAD~1 (default) unstages the changes but keeps them in your working directory. git reset --hard HEAD~1 discards all changes permanently — use with extreme caution.
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for Git Basics.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this Software Engineering topic.
Search Terms
software-engineering, software engineering, software, engineering, configuration, management, git, basics
Related Software Engineering Topics