Git Notes
Learn workflows for synchronizing local and remote Git repositories. Master fetch-merge-push cycles, handling diverged branches, and staying up to date.
One of the most frustrating experiences for Git beginners is running git push and getting rejected because "the remote contains work that you do not have locally." This happens because Git requires you to integrate remote changes before you can share your own. Understanding synchronization workflows is essential for smooth collaboration.
Synchronization is the process of keeping your local repository aligned with the remote. It involves fetching what others have done, integrating their changes with yours, and pushing your contributions back. Get this wrong and you face merge conflicts, lost work, or a tangled commit history. Get it right and collaboration feels effortless.
The Complete Sync Cycle
Starting Your Day: The Morning Sync
Before you write any code, get the latest state of the project:
# Switch to main and get latest
git checkout main
git pull origin main
# Update your feature branch with latest main
git checkout feature/dashboard
git rebase main
# or: git merge mainFirst, rewinding head to replay your work on top of it... Applying: feat: add dashboard layout Applying: feat: add chart components
This ensures you are building on the latest foundation, reducing the chance of conflicts when you eventually create a pull request.
Fetch First, Then Decide
The safest sync approach is to separate downloading from integrating:
# Step 1: Download without modifying anything
git fetch origin
# Step 2: See what changed
git log HEAD..origin/main --onelined4e5f6g fix: resolve authentication timeout c3d4e5f feat: add rate limiting b2c3d4e docs: update API reference
# Step 3: Now integrate (you know what you are getting)
git merge origin/main
# or: git rebase origin/mainThis two-step approach gives you full visibility before anything changes in your working directory. Particularly useful when the remote has significant changes.
Handling Diverged Branches
Divergence happens when both you and the remote have new commits since your last sync:
git statusOn branch main Your branch and 'origin/main' have diverged, and have 2 and 3 different commits each, respectively. (use "git pull" to merge the remote branch into yours)
You have two options for reconciliation:
Option 1: Merge (Preserves Exact History)
git pull origin main
# Creates a merge commit combining both historiesMerge made by the 'ort' strategy. src/api.js | 25 +++++++++++++++++ src/auth.js | 8 +++--- 2 files changed, 30 insertions(+), 3 deletions(-)
Result: Your history shows a merge commit with two parents. Some teams dislike this because it makes the log harder to read.
Option 2: Rebase (Clean Linear History)
git pull --rebase origin main
# Replays your commits on top of the remote changesSuccessfully rebased and updated refs/heads/main.
Result: A clean, linear history as if you made your commits after the remote changes. Preferred by most teams for feature branches.
Syncing a Forked Repository
Open source contributors frequently need to sync their fork with the upstream project:
# One-time setup: add upstream remote
git remote add upstream https://github.com/original-org/project.git
# Regular sync routine
git fetch upstream # Get upstream changes
git checkout main # Switch to main
git merge upstream/main # Merge upstream into local main
git push origin main # Push updated main to your forkNow your fork's main branch matches the original project, and you can create feature branches from the latest code.
Syncing Feature Branches with Main
While working on a long-running feature branch, main moves forward. Keep your branch updated:
# Method 1: Rebase onto latest main (preferred for PRs)
git checkout feature/user-profiles
git fetch origin
git rebase origin/main
# Method 2: Merge main into feature (simpler but noisier history)
git checkout feature/user-profiles
git merge mainRebasing produces cleaner pull requests because reviewers see only your changes, not merge commits mixing in unrelated work from main.
Checking Sync Status
Before pushing, always verify your position relative to the remote:
# How many commits ahead/behind
git status
# Detailed comparison
git fetch origin
git log HEAD..origin/main --oneline # Commits they have, you lack
git log origin/main..HEAD --oneline # Commits you have, they lack
# One-line summary
git rev-list --count HEAD..origin/main # Number behind
git rev-list --count origin/main..HEAD # Number aheadDealing with Push Rejection
When your push is rejected because the remote is ahead:
git push origin main! [rejected] main -> main (fetch first) error: failed to push some refs hint: Updates were rejected because the remote contains work that you do not have locally.
Solution:
# Option A: Pull with rebase then push
git pull --rebase origin main
git push origin main
# Option B: Fetch, inspect, merge, push
git fetch origin
git log HEAD..origin/main --oneline # See what is new
git merge origin/main # Integrate
git push origin main # Now push succeedsAutomating Sync with Git Configuration
Set defaults that make syncing smoother:
# Always rebase on pull (avoids unnecessary merge commits)
git config --global pull.rebase true
# Auto-prune stale remote branches on fetch
git config --global fetch.prune true
# Show divergence summary in status
git config --global status.aheadBehind trueCommon Mistakes
Mistake 1: Never pulling before starting work. You end up building on stale code, creating massive conflicts later.
Mistake 2: Force pushing to resolve rejection errors instead of pulling first. This overwrites remote history and can destroy teammates' work.
Mistake 3: Not syncing feature branches with main regularly. The longer a branch lives without syncing, the worse the eventual merge conflict resolution will be.
Mistake 4: Pulling with uncommitted changes in the working directory. This can create confusing merge situations. Always commit or stash before pulling.
Interview Questions
Q1: What is the recommended workflow for keeping a feature branch up to date?
Regularly fetch from the remote and rebase your feature branch onto the latest main. This keeps your branch current, ensures conflicts are caught early while they are small, and produces clean pull requests. Aim to sync at least daily on active projects.
Q2: What does it mean when local and remote have diverged?
Divergence means both your local branch and the remote branch have commits that the other does not have. This happens when you commit locally while someone else pushes to the same remote branch. You must merge or rebase to reconcile before pushing.
Q3: How do you sync a forked repository with the original?
Add the original repository as an upstream remote, fetch from it, merge upstream/main into your local main, then push to your origin. This keeps your fork's main branch current with the source project.
Q4: Should you use pull with merge or rebase?
Rebase produces cleaner linear history and is preferred for feature branches. Merge preserves the exact history of when integration happened, which some teams prefer for main. Many teams use pull.rebase = true globally.
Q5: How often should you sync with the remote?
At minimum, sync at the start and end of each work session. For teams with high commit velocity, sync multiple times per day. The principle is simple: frequent small syncs produce small manageable conflicts, while infrequent syncs produce large painful ones.
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for Sync Local and Remote - Keep Repositories in Harmony.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this Git & GitHub topic.
Search Terms
git-github, git & github, git, github, working, with, repositories, sync
Related Git & GitHub Topics