Git and GitHub: From your first commit to how teams ship together
Niraj Pahadi·Software Engineer, Novelty Lab
Git is a version control system that tracks changes in your code over time. Think of it as an undo history for your project—you can save snapshots (commits), revert to earlier versions, and safely experiment without breaking your code. It also lets multiple developers work on the same codebase efficiently by managing changes from different people in an organized way.
GitHub is a cloud platform built on top of Git. It hosts your code online, making it easy to collaborate, review changes, and contribute to projects. Alongside managing code history, it enables collaboration through branching, pull requests, and code reviews.
Git works with platforms like GitHub and GitLab in modern development. Git manages code history locally; GitHub and GitLab store it online and enable collaboration. GitHub focuses on code hosting, pull requests, and open-source collaboration, whereas GitLab is an all-in-one DevOps platform with built-in CI/CD, project management, and deployment tools. Together, they form the core workflow for modern software development.
Creating a GitHub account
Navigate to github.com and sign up with a unique username, your email, and a strong password. After verifying the code sent to your email, your profile is ready. For setup, security (including two-factor authentication), and profile best practices, see GitHub's Beginner's guide to setting up and securing your profile.
Before you begin
Install Git from git-scm.com. On Windows, Git Bash is where you'll run Git commands. Open Git Bash and verify:
git --versionIf Git is installed correctly, you'll see something like:
git version 2.44.0.windows.1That's your green light—you're ready to go.
Sign every commit with your identity
Before Git tracks your work, it needs to know who you are. Every commit is stamped with a name and email—like signing your work. Run these in Git Bash:
git config --global user.name "Your Name"
git config --global user.email "you@example.com"Important: Use the same email as your GitHub account so commits link to your profile.
For example:
git config --global user.name "Alex Rivera"
git config --global user.email "alex.rivera@example.com"Double-check:
git config --global --listYou should see your name and email. If something is wrong, run the `git config` commands again—Git overwrites the old values. Set this once; every commit on this machine will carry your identity from then on.
Setting up a new project on GitHub
On github.com, go to Repositories and click New. Name the repo (e.g. *my-first-project*), add an optional description, and choose Public or Private. If you already have a local project, do not initialize with a README—that can cause conflicts when you connect your local repo. Click Create repository.
Create a project on your PC
Open Terminal, Command Prompt, or PowerShell and go where you want the project (e.g. Desktop with `cd Desktop`). Create a folder with `mkdir project-name`, enter it with `cd project-name`, add your files, then open the folder in your editor with `code .`. You now have a clean project folder before `git init` and connecting to GitHub.
Pushing your first project to GitHub
Open the project in VS Code with `code .`, initialize Git, stage, commit, rename the default branch to `main` (after the first commit), add the remote, and push:
# Open the current project folder in VS Code
code .
# Initialize a new Git repository (creates a .git folder)
git init
# Stage all files in the project for tracking
git add .
# Create the first commit (save snapshot of your project)
git commit -m "initial commit"
# Rename the default branch to 'main'
git branch -M main
# Connect your local project to a GitHub repository
git remote add origin git@github.com:your-username/your-repo.git
# Push your code to GitHub and set upstream for future pushes
git push -u origin mainDaily workflow: track, stage, and commit
Once the project is connected to Git, use a simple loop: `git status` to see changes, `git add` to stage, `git commit` to save:
# See what's changed
git status
# Stage everything
git add .
# Or stage a specific file
git add src/components/Header.jsx
# Commit with a meaningful message
git commit -m "feat: add responsive header with mobile nav"A clean way to manage your code
Use a feature-based branching strategy: every feature gets its own branch instead of coding directly on `main`. That keeps `main` stable while you experiment. Update `main`, create a branch (e.g. `feature/auth-system`), commit, push, then merge—usually via a pull request. This keeps the codebase organized and makes collaboration and reviews smoother.
# Make sure you're on main and it's updated
git checkout main
git pull origin main
# Create and switch to a new feature branch
git checkout -b feature/your-feature-name
# Work on your feature, then stage and commit changes
git add .
git commit -m "feat: implement your feature"
# Push the feature branch to GitHub
git push -u origin feature/your-feature-name
# After review, merge back into main
git checkout main
git pull origin main
git merge feature/your-feature-name
# Push updated main branch
git push origin mainHow teams collaborate on the same codebase
Here's how a five-person engineering team might work in practice:
| Person | Role | Task |
|---|---|---|
| Sarah | Team Lead | Manages the repo, reviews PRs, handles final merges |
| Alex | Developer | Building the user authentication system |
| Blake | Developer | Building the payment gateway integration |
| Charlie | Developer | Designing the product dashboard |
| Diana | Developer | Fixing a critical bug in the notification service |
Nobody writes on `main` directly—`main` is production-ready. Everyone clones locally, branches for their task, and integrates through GitHub.
Step 1: Setting the foundation
Sarah initializes the repository and pushes `main`. Alex, Blake, Charlie, and Diana clone once:
# Run by Alex, Blake, Charlie, and Diana on their respective machines
git clone git@github.com:novelty-lab/global-marketplace.git
cd global-marketplaceStep 2: Isolated feature development
Alex's workflow (user auth)
git checkout main
git pull origin main
git checkout -b feature/user-auth
# Alex writes authentication code...
git add src/auth/
git commit -m "feat: implement JWT-based user login and session handling"
git push -u origin feature/user-authBlake's workflow (payments)
Blake works on `feature/stripe-payments` in parallel—his files don't collide with Alex's auth work:
git checkout main
git pull origin main
git checkout -b feature/stripe-payments
git add src/payments/
git commit -m "feat: integrate Stripe API for checkout processing"
git push -u origin feature/stripe-paymentsStep 3: Peer review and continuous integration
Alex opens a pull request from `feature/user-auth` into `main`. Sarah and Charlie review the diff, leave comments, and after approval Sarah merges on GitHub. Alex's code is now on `main`.
Step 4: Staying in sync and resolving conflicts
After Alex merges, Blake's branch is behind. He updates `main` locally and merges it into his feature branch:
git checkout main
git pull origin main
git checkout feature/stripe-payments
git merge mainIf both edited the same line (e.g. in `package.json`), Git reports a conflict. Blake resolves markers in the editor, then:
git add package.json
git commit -m "chore: resolve merge conflict with main branch"
git push origin feature/stripe-paymentsStep 5: Final review and shipping
Blake opens his PR; Sarah merges after checks pass. Charlie and Diana follow the same loop for dashboard and notifications. Pull, branch, commit, push, review, sync—five people can ship large features without overwriting each other.
When and why teams use rebase
Merging `main` into a feature branch works, but many teams prefer rebase to keep history linear. Rebase replays your commits on top of the latest `main` instead of creating a merge commit.
Merge vs rebase
With merge, histories combine with an extra merge commit. With rebase, your commits are re-applied on top of updated `main`—cleaner `git log`, easier reviews.
Before opening a PR, Blake might run:
git checkout main
git pull origin main
git checkout feature/stripe-payments
git rebase main- The branch includes everything merged to `main` since branching.
- The PR is smaller and easier to review.
- History stays linear after merge.
Handling conflicts during rebase
# Fix the conflict in your editor
git add .
git rebase --continueWhen not to rebase: Never rebase shared branches like `main` or `staging`, or any branch others are actively pushing to. Rebase only on your own feature branch.
Taking clean history one step further: squash
Squash collapses many WIP commits into one meaningful commit before merge. Noisy history:
feat: add payment form
fix: typo in button label
fix: validation not triggering on submit
wip: still debugging stripe webhook
fix: finally got stripe working
chore: remove console logsAfter squash, `main` might get a single line: `feat: integrate Stripe payment gateway`.
How to squash commits
Interactive rebase — squash the last four commits:
git rebase -i HEAD~4Change `pick` to `squash` (or `s`) on all commits except the first, save, then edit the final message. Squash merge on GitHub — when merging a PR, choose Squash and merge so GitHub squashes automatically; many teams commit freely locally and squash at merge time.
Rebase + squash: the full picture
# Branch off main
git checkout -b feature/stripe-payments
# Work freely — commit often
git commit -m "wip: payment form"
git commit -m "fix: webhook validation"
git commit -m "fix: remove console logs"
# Rebase onto latest main before the PR
git rebase main
# resolve conflicts, then: git rebase --continue
# Squash messy commits into one
git rebase -i HEAD~3
# Push and open the PR
git push --force-with-lease origin feature/stripe-payments
# Lead merges — main stays clean and linearAfter squashing or rebasing, use git push --force-with-lease instead of git push --force. It refuses to overwrite if someone else pushed to the branch since your last fetch.
Merge vs rebase vs squash at a glance
| Merge | Rebase | Squash | |
|---|---|---|---|
| What it does | Combines two branch histories | Replays commits on top of another branch | Collapses multiple commits into one |
| Commit history | Branching, non-linear | Clean and linear | Clean and minimal |
| Extra commits | Creates a merge commit | No extra commits | One final commit |
| Safe on shared branches? | Yes | No | Yes (via GitHub squash merge) |
| Best for | Integrating stable, completed work | Keeping a feature branch current | Cleaning up history before merging |
Why high-performing teams use all three
- Merge when combining stable work where full history matters (e.g. a release branch into `main`).
- Rebase during development to stay current and keep history linear once merged.
- Squash to turn noisy commits into one clear entry in shared history.
Together they produce a history that's easy to debug, fast to scan with `git log`, and clear for the next engineer who joins the project.
Quick reference
| Command | What it does |
|---|---|
| git init | Initialize a new repository |
| git clone <url> | Copy a remote repository locally |
| git status | See what has changed |
| git add . | Stage all changes |
| git commit -m "message" | Save a snapshot of staged changes |
| git push | Upload commits to GitHub |
| git pull | Download and merge remote changes |
| git checkout -b <name> | Create and switch to a new branch |
| git merge <branch> | Merge another branch into the current one |
| git rebase <branch> | Replay your commits on top of another branch |
Feature branching, pull requests, and rebasing are how professional teams ship every day. Master these habits early—they scale with you at every stage of your career.
More from Novelty Lab
From Conversations to Operations: The Future of Business Software
Every customer message is a buying signal, a booking intent, or a support request. But most businesses have no operational system behind their conversations. Here is why that gap is closing — and how to build systems that act on intent in real time.
Kshitij DhamalaAI Review Response Automation: How Smart Operators Reclaim 10 Hours a Week and Grow Revenue
Businesses that respond to every review are 80% more likely to win new customers. Yet the average response rate is just 56%. Here's how AI automation closes the gap — without removing human judgment from the process.