
🔧 Mechanics wield spanners.
👨💻 We, as developers, harness Git.
Isn’t it intriguing how Git, such a vital tool for code collaboration and management, often goes unnoticed in tech stacks and resumes? The assumption prevalent today is that a working knowledge of Git is par for the course. But consider this: have you truly mastered it?
Git is a Version Control System (VCS)—a ubiquitous innovation that enables us to seamlessly store, change, and collaborate on code with our peers.
🚨 Important note: Git is an expansive topic. Comprehensive books and detailed blog posts exist solely dedicated to it. That’s not the journey we’re embarking on here. While I might not hold the badge of a Git expert, my purpose is to lay out the Git fundamentals post I longed for when starting out.
For developers, our world revolves around reading, writing, and reviewing code. Git might well be the developer’s Excalibur—undoubtedly one of the most critical tools at our disposal. Gaining mastery over Git’s features is akin to investing in your own growth as a developer.
Let’s forge ahead.
The Universe of Git
If there’s a command you’d like expanded upon, feel free to voice it in the comments. I’d be more than pleased to update this guide. 🙏
Solid Foundations
Does Git ever make you feel like Peter Griffin in a bewildering moment? If Git fundamentals elude you, you risk endless loops of confusion and the dread of yet another merge conflict tracking you from the terminal. Let’s set a robust foundation by defining core Git concepts.
Branches: The Stem of Evolution
In a Git repository, the main line of development, often termed “main” or the now-deprecated “master,” serves as the axis from which various branches sprout. Each branch represents an independent flow of work, empowering developers to explore multiple features or tweaks in parallel.
Commits: The Chronicle of Code
Git commits map out the evolution of your codebase, capturing snapshots of the code across time. They log alterations since the last record, cumulatively composing a narrative of the project’s developmental arc.
For reference, commits are generally tracked using their unique cryptographic hash.
Example:
git show abc123def456789
This command reveals intricate details about the commit specified by that hash.
Tags: Milestones in the Timeline
Git tags are akin to bookmarks in the Git timeline, usually highlighting notable achievements in a project’s history like releases
, versions
, or standout commits.
HEAD: The Compass of Commitment
At any given moment, HEAD
denotes the latest commit on the currently active branch, serving as the repository’s navigational pointer. Sometimes, HEAD
can diverge from the branch tip, staking its claim on a specific commit, entering what’s termed a detached HEAD
state.
What are Stages?
Grasping the essence of Git stages ensures smoother navigation through your workflow. These stages signify logical transitions your file alterations undergo before being committed.
Working Directory 👷
Here, in the working directory
, you engage with the heart of your project. It’s your canvas, reflecting the current state of your files.
Staging Area 🚉
Think of the staging area
as the green room—the prelude before the grand release. Here, you assemble changes awaiting their final curtain call.
To stage:
git add
. To unstage:git rm
Local Repository 🗄️
The sanctuary of your code—the local repository is where Git eternally nests committed changes, offering a time machine to explore your project’s saga.
Commit with:
git commit
Remote Repository 🛫
In cyberspace, the remote repository reigns supreme—a hub on servers like GitHub or Bitbucket, facilitating global collaboration on your code.
Sync with:
git push
andgit pull
Embarking on Git
Every journey begins somewhere; in Git, that starting point is your workspace
. You may either fork
or clone
an existing repository to clone its workspace or git init
for a nascent project.
Credential Configuration
Prevent the monotony of repeatedly entering credentials with:
git config --global credential.helper store
On initial remote repository interaction, Git requests your username and password. Post-initial entry, Git takes care of remembering it—note this is stored in plaintext within .git-credentials
.
Check credentials using:
git config --global credential.helper
Branching Out
Being intimately familiar with which local branch you’re operating on is crucial. Here are vital commands:
git branch # Displays changes
# Create a new branch
git branch feature-branch-name
To transition between branches:
git switch
For creating and switching in one sweep:
git checkout -b feature-branch-name
To visualize the current repository status:
git status
Mastering Commits
Utilize git commit -m
to cement changes, git amend
for refined alterations, and adhere strictly to commit message conventions.
git commit -m "meaningful message"
To adjust your last commit:
git add .
git commit --amend
# Modify the message if necessary.
git push origin your_branch --force
⚠️ Careful with
--force
; its impact can reshape the history of the target branch—not recommended on main/master.
Generally, frequent commits shield against lost progress or resets. Amend histories as needed by squashing or rebasing.
Invoke git log
for a chronicle of commit history, sorted by recency.
Rewriting the Past
With great power comes great responsibility. Commands like Rebase
and Squashing
let you alter history, while Cherry-picking
fine-tunes the adoption of commits.
Rebase vs. Merge
While both rebase and merge target integration, their methods diverge—rebasing modernizes, creating a lucid narrative, whereas merging preserves historical paths.
Here’s how you rebase:
Ensure you’re on your target branch and sync changes:
git checkout your_branch
git fetch
Select your rebase target branch:
git rebase upstream_branch
After rebasing:
git push origin your_branch --force
⚠️ Tread carefully with
--force
; it can reshape the destiny of branches.
Embrace the Power of Squash
Git squashing melds numerous commits into a cohesive entity.
Particularly useful during rebasing, this method effectively streamlines history. To assist with squashing, perform:
git reset --soft HEAD~X
git commit -m "Your squashed commit message"
git push origin your_branch --force
⚠️ Again, handle
--force
with care—it wields the power of change.
Precision with Cherry-Picking
Cherry-picking allows precise grabbing of important changes without extensive merging, ideal for selective incorporation.
First, identify the desired commit hash:
git checkout target_branch
git cherry-pick <commit-hash>
# Repeat for multiple desired commits
git push origin target_branch
Venturing Beyond: Advanced Git Commands
Harness advanced Git tools like signing commits to authenticate contributions securely.
Commit Signing
Verification of commit legitimacy protects against forgery. By conceding your GPG key to Git, you can cryptographically endorse your work:
# Generate a GPG key
gpg --gen-key
# Inform Git of your key
git config --global user.signingkey <your-gpg-key-id>
# Link your GPG key with GitHub
# Commencing signed commits:
git commit -S -m "Your commit message"
# View signed credentials:
git log --show-signature
Git Reflog: Time Traveler’s Guide
Git references—your gateway to repository history—benefit from commands like reflog, restoring lost commits and fixing mishaps.
Embracing Interactivity: Interactive Rebase
Interactive rebase redefines commit history dynamically, granting control over each edit.
Understand actions such as Pick, Reword, Edit, Squash, Drop.
Here’s a video on executing an interactive rebase, alongside a useful tool.
Collaborating with Git
Origin vs. Upstream
Origin: The default remote repository linked to your local Git clone. With forks, your fork becomes the “origin.”
Upstream: The parent repository from which yours forked. Synchronizing with upstream prevents divergence.
git remote -v # Check remotes
Navigating Conflicts
Don’t despair. Git’s conflicts manifest when diverging changes collide, enclosing conflicting sections with markers like <<<<<<<
, =======
, >>>>>>>
.
Navigate through, deciding what remains, what alters, and surface clarity by removing markers.
Encounter challenges? This video skillfully explains conflict resolution.
Appreciating Git Workflows
Various methodologies abound, each offering a unique refinement of flow.
Feature Branch Workflow 🌱
Separate branches capture individual features or bugs before merging back to the main branch, encouraging siloed progression.
- Strength: Minimizes conflict.
- Weakness: Complexity demands vigilance.
Gitflow Workflow 🌊
A structured branching model, including main, develop, feature, and more.
- Strength: Great for serialized releases and maintenance.
- Weakness: Complexity could overwhelm smaller setups.
Forking Workflow 🍴
Developers shape their forks, propose changes, and merge through pull requests without risking the main repository’s sanctity—ideal for open-source collaboration.
- Strength: Facilitates external collaboration.
- Weakness: Synchronization challenges may emerge.
Pull Request Workflow ⏩
Emphasizes collaboration through branch-specific pull requests for code review and shared insights.
- Strength: Collaborative spirit and knowledge sharing.
- Weakness: Relies on human review timing.
Trunk-Based Development 🪵
Emphasizes rapid shifts and continuous delivery through main branch work, focusing on frequent, small updates.
- Strength: Agile pace.
- Weakness: Requires solid testing and deployment structures.
Collaborative Forking
Forking facilitates open-source development by allowing private innovation before syncing with the collective progress, establishing a resilient network.
💡 While originating separately, forks connect to their origin, enabling synchronicity across updates.
Git Cheatsheet
Here’s a glance at commands:
# Clone a Repository
git clone <repository_url>
# Stage Changes for Commit
git add <file(s)>
# Commit Changes
git commit -m "Commit message"
# Push Changes to Remote
git push
# Force Push (caution)
git push --force
# Reset to Last Commit
git reset --hard
# Create a New Branch
git branch <branch_name>
# Switch Branches
git checkout <branch_name>
# Merge Branch Changes
git merge <branch_name>
# Rebase onto Another Branch (caution)
git rebase <base_branch>
# Status Overview
git status
# Commit History Overview
git log
# Undo Last Commit (caution)
git reset --soft HEAD^
# Discard Changes
git restore <file(s)>
# Retrieve Lost References
git reflog
# Interactive Rebase Coordination
git rebase --interactive HEAD~3
Enhance Your Git Experience
Explore tools for interactive rebasing, colorful diffs, or interactive branching examples: