Git - Pushing & Pulling
Intermediate
Pushing and pulling are the fundamental operations for synchronizing your local repository with remote repositories. Understanding these commands is essential for effective collaboration.
Understanding Push and Pull
Local Repository ββ Remote Repository
git pull βββββββββββ Your changes
βββββββββββ git push
- Push: Upload your local commits to remote repository
- Pull: Download and merge remote changes to local repository
- Fetch: Download changes without merging (safer)
Git Push Operations
Basic Push Commands
# Push current branch to its upstream
git push
# Push specific branch to remote
git push origin main
# Push new branch and set upstream
git push -u origin feature-branch
git push --set-upstream origin feature-branch
Successful push output:
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 8 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 312 bytes | 312.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
To github.com:user/repository.git
a1b2c3d..b2c3d4e main -> main
Push All Branches
# Push all branches with tracking
git push --all origin
# Push all tags
git push --tags origin
# Push everything (branches and tags)
git push --all origin && git push --tags origin
Force Push (Use with Caution)
# Force push (destructive)
git push --force origin main
# Safer force push (won't overwrite others' work)
git push --force-with-lease origin main
β οΈ Force Push Warning: Force pushing can destroy other people's work. Only use on branches you own, and prefer
--force-with-lease
for safety.
Git Pull Operations
Basic Pull Commands
# Pull from tracked remote branch
git pull
# Pull from specific remote and branch
git pull origin main
# Pull with rebase instead of merge
git pull --rebase origin main
Successful pull output:
remote: Enumerating objects: 8, done.
remote: Counting objects: 100% (8/8), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 6 (delta 2), reused 4 (delta 2), pack-reused 0
Unpacking objects: 100% (6/6), 1.45 KiB | 744.00 KiB/s, done.
From github.com:user/repository
b2c3d4e..c3d4e5f main -> origin/main
Updating b2c3d4e..c3d4e5f
Fast-forward
README.md | 5 +++++
src/app.js | 12 ++++++++++++
2 files changed, 17 insertions(+)
What Pull Actually Does
git pull
is equivalent to:
# These two commands together
git fetch origin
git merge origin/main
# Or with --rebase
git fetch origin
git rebase origin/main
Fetch vs Pull
When to Use Fetch
Safe workflow with fetch:
# 1. Download latest changes
git fetch origin
# 2. Review what changed
git log HEAD..origin/main --oneline
# 3. See the differences
git diff HEAD origin/main
# 4. Merge when ready
git merge origin/main
Fetch Advantages
- β Safeβnever modifies your working directory
- β Allows review before merging
- β Enables complex merge strategies
- β Prevents surprise conflicts
Handling Push Conflicts
Non-Fast-Forward Error
Push rejection error:
To github.com:user/repository.git
! [rejected] main -> main (non-fast-forward)
error: failed to push some refs to 'github.com:user/repository.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
Resolving Push Conflicts
Method 1: Pull and merge
# Pull remote changes
git pull origin main
# Resolve any merge conflicts if they occur
# Then push
git push origin main
Method 2: Pull with rebase (cleaner history)
# Pull with rebase
git pull --rebase origin main
# Resolve any conflicts during rebase
# Then push
git push origin main
Pull Conflicts and Resolution
Merge Conflicts During Pull
Pull conflict output:
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 285 bytes | 285.00 KiB/s, done.
From github.com:user/repository
c3d4e5f..d4e5f6g main -> origin/main
Auto-merging config.js
CONFLICT (content): Merge conflict in config.js
Automatic merge failed; fix conflicts and then commit the result.
Resolving Pull Conflicts
Conflict resolution workflow:
# 1. Check status
git status
# 2. Edit conflicted files (remove conflict markers)
nano config.js
# 3. Stage resolved files
git add config.js
# 4. Complete the merge
git commit # Uses default merge message
# 5. Push the resolution
git push origin main
Rebase vs Merge on Pull
Pull with Merge (Default)
Creates merge commits:
Before pull:
Local: A---B---C
Remote: A---B---D---E
After git pull:
Result: A---B---C-------F β F is merge commit
\ /
D---E---/
Pull with Rebase
Linear history:
Before pull:
Local: A---B---C
Remote: A---B---D---E
After git pull --rebase:
Result: A---B---D---E---C' β C' is rebased commit
Setting Default Pull Behavior
# Always rebase on pull
git config --global pull.rebase true
# Always merge on pull
git config --global pull.rebase false
# Fast-forward only (fail if merge needed)
git config --global pull.ff only
Advanced Push and Pull Operations
Pushing Tags
# Push single tag
git push origin v1.0.0
# Push all tags
git push --tags origin
# Push tag with branch
git push origin main --tags
Deleting Remote Branches and Tags
# Delete remote branch
git push origin --delete feature-branch
# Delete remote tag
git push origin --delete v1.0.0
# Alternative syntax for branch deletion
git push origin :feature-branch
Pushing to Multiple Remotes
# Push to specific remote
git push origin main
git push backup main
# Configure multiple push URLs
git remote set-url --add --push origin [email protected]:user/repo.git
git remote set-url --add --push origin [email protected]:user/repo.git
# Now git push pushes to both
Collaboration Workflows
Daily Team Workflow
Start of day routine:
# 1. Switch to main branch
git switch main
# 2. Pull latest changes
git pull origin main
# 3. Create feature branch
git switch -c feature/new-functionality
# 4. Do your work...
# 5. Push feature branch
git push -u origin feature/new-functionality
Before Going Home
# Push your work to backup
git add .
git commit -m "Work in progress: implementing feature X"
git push origin feature/new-functionality
Feature Completion
# 1. Update main branch
git switch main
git pull origin main
# 2. Rebase feature branch
git switch feature/new-functionality
git rebase main
# 3. Push rebased branch
git push --force-with-lease origin feature/new-functionality
# 4. Create pull request (on GitHub/GitLab)
# 5. After merge, clean up
git switch main
git pull origin main
git branch -d feature/new-functionality
Troubleshooting Push/Pull Issues
Authentication Problems
SSH authentication error:
[email protected]: Permission denied (publickey).
fatal: Could not read from remote repository.
Solutions:
# Test SSH connection
ssh -T [email protected]
# Add SSH key to agent
ssh-add ~/.ssh/id_ed25519
# Check SSH agent
ssh-add -l
Large Push Issues
# Push with progress info
git push --progress origin main
# Increase Git buffer size
git config --global http.postBuffer 524288000
# Push specific commits only
git push origin a1b2c3d:main
Corrupted Reference Errors
# Repair local repository
git fsck --full
# Reset remote tracking branch
git update-ref refs/remotes/origin/main origin/main
# Re-fetch everything
git fetch --all --prune
Best Practices
Safe Push Practices
- β Always pull before pushing
- β
Use
--force-with-lease
instead of--force
- β Push feature branches early for backup
- β Test code before pushing to main
- β Never force push to shared branches
Efficient Pull Practices
- β Fetch regularly to stay updated
- β Use rebase for cleaner history
- β Pull main branch before creating features
- β Resolve conflicts promptly
Automation and Hooks
Automatic Push After Commit
# .git/hooks/post-commit
#!/bin/sh
branch=$(git rev-parse --abbrev-ref HEAD)
if [ "$branch" = "main" ]; then
git push origin main
fi
Pre-push Hook Example
# .git/hooks/pre-push
#!/bin/sh
# Run tests before push
npm test
if [ $? -ne 0 ]; then
echo "Tests failed. Push aborted."
exit 1
fi
Performance Optimization
Faster Push/Pull
# Use SSH for better performance
git remote set-url origin [email protected]:user/repo.git
# Parallel processing
git config --global push.parallel 0
# Compress network traffic
git config --global core.compression 9
Partial Operations
# Push specific files only (rare use case)
git add specific-file.txt
git commit -m "Update specific file"
git push origin main
# Pull specific files (using sparse checkout)
git config core.sparseCheckout true
echo "docs/*" > .git/info/sparse-checkout
git pull origin main
Summary
You now understand Git push and pull:
- β
git push
uploads local commits to remote - β
git pull
downloads and merges remote changes - β
git fetch
downloads without merging (safer) - β Conflicts can occur during both push and pull
- β Rebase vs merge affects history structure
- β Force push is dangerous and should be used carefully
- β Regular synchronization prevents complex conflicts
Next Steps
Now that you understand push and pull, let's explore collaboration workflows and team practices:
β Git - Collaboration Workflows
Practice Tip: Create two clones of the same repository and practice pushing/pulling between them to simulate team collaboration scenarios.