Skip to content

pull Git Command Guide

The git pull command incorporates changes from a remote repository into the current branch. It runs git fetch with the given parameters and then calls either git rebase or git merge to reconcile diverging branches based on configuration or command-line options.

Terminal window
git pull [<options>] [<repository> [<refspec>...]]
OptionDescription
--no-rebaseMerge after fetching (default)
--rebaseRebase after fetching
--ffAllow fast-forward merges
--no-ffCreate merge commit even for fast-forward
--ff-onlyOnly allow fast-forward merges
--squashSquash all commits into single commit
OptionDescription
--no-commitDon’t create merge commit
--commitCreate merge commit (default)
--editEdit merge message
--no-editUse auto-generated merge message
--cleanup=<mode>Clean up commit message
--no-verifySkip pre-commit hooks
OptionDescription
--recurse-submodulesUpdate submodules recursively
--no-recurse-submodulesDon’t update submodules
--recurse-submodules=<strategy>Submodule update strategy
--jobs=<n>Number of parallel jobs
--depth=<depth>Shallow clone depth
--shallow-since=<date>Shallow clone since date
OptionDescription
-q, --quietSuppress output
-v, --verboseVerbose output
--progressShow progress
--no-progressHide progress
--statShow diffstat
--no-statDon’t show diffstat
ParameterDescription
<repository>Remote repository name or URL
<refspec>Remote refs to fetch and merge
1. Fetch: Download objects and refs from remote
2. Analyze: Check if branches have diverged
3. Reconcile: Choose merge strategy (merge/rebase)
4. Apply: Integrate changes into current branch
5. Update: Move branch pointer to new commit
Merge Strategy (default):
A---B---C (local)
\
D---E (remote)
\
F (merge commit)
Rebase Strategy (--rebase):
A---B---C (remote)
\
D'---E' (local rebased)
Terminal window
# Pull from default remote (origin)
git pull
# Pull from specific remote
git pull origin
# Pull specific branch
git pull origin main
# Pull with rebase instead of merge
git pull --rebase
# Pull with custom merge message
git pull --no-edit -m "Merge latest changes"
Terminal window
# Allow fast-forward (default)
git pull
# Force merge commit
git pull --no-ff
# Only allow fast-forward
git pull --ff-only
# Squash all commits
git pull --squash
Terminal window
# Merge strategy (default)
git pull
# Rebase strategy
git pull --rebase
# Interactive rebase
git pull --rebase=interactive
# Preserve merge commits during rebase
git pull --rebase=preserve
Terminal window
# Update submodules recursively
git pull --recurse-submodules
# Update submodules with specific strategy
git pull --recurse-submodules=on-demand
# Don't update submodules
git pull --no-recurse-submodules
Terminal window
# Pull in shallow repository
git pull --depth=1
# Unshallow repository
git pull --unshallow
# Pull with shallow since date
git pull --shallow-since="2 weeks ago"
Terminal window
# Pull with automatic merge
git pull
# If conflicts occur, resolve manually:
# Edit conflicted files
# Stage resolved files
git add resolved-file.txt
# Complete merge
git commit
# Or abort pull
git merge --abort
Terminal window
# Use multiple jobs for fetching
git pull --jobs=4
# Configure default job count
git config fetch.parallel 4
git config submodule.fetchJobs 4
Terminal window
# Set default pull strategy
git config pull.rebase false # Merge (default)
git config pull.rebase true # Rebase
git config pull.rebase preserve # Preserve merges
# Configure per-branch
git config branch.main.rebase true
git config branch.feature.rebase interactive
Terminal window
# Set default remote for branch
git config branch.main.remote origin
git config branch.main.merge refs/heads/main
# Configure remote tracking
git branch --set-upstream-to=origin/main main
# Set default push remote
git config push.default upstream
Terminal window
# Configure credential helper
git config credential.helper store
# Use SSH instead of HTTPS
git remote set-url origin git@github.com:user/repo.git
# Configure GPG signing
git config commit.gpgsign true
git config user.signingkey "your-key-id"
#!/bin/bash
# CI/CD pull workflow
ci_pull_workflow() {
echo "=== CI Pull Workflow ==="
# Configure Git for CI
git config user.name "CI Bot"
git config user.email "ci@example.com"
# Pull with rebase for clean history
if git pull --rebase --quiet; then
echo "✓ Pull successful"
return 0
else
echo "✗ Pull failed - checking conflicts"
# Check for conflicts
if git diff --name-only --diff-filter=U | grep -q .; then
echo "Merge conflicts detected"
git status
# Auto-resolve strategy (customize as needed)
# For CI, we might want to abort
git merge --abort
echo "Pull aborted due to conflicts"
return 1
else
echo "No conflicts, pull completed"
return 0
fi
fi
}
ci_pull_workflow
Terminal window
# Collaborative pull workflow
team_pull_workflow() {
local branch="${1:-$(git branch --show-current)}"
echo "=== Team Pull Workflow: $branch ==="
# Ensure clean working directory
if ! git diff --quiet || ! git diff --cached --quiet; then
echo "Working directory not clean. Stash changes first."
return 1
fi
# Fetch latest changes
git fetch origin
# Check for remote changes
local ahead_behind
ahead_behind=$(git rev-list --left-right --count "HEAD...origin/$branch")
local ahead=$(echo "$ahead_behind" | awk '{print $1}')
local behind=$(echo "$ahead_behind" | awk '{print $2}')
if [ "$behind" -gt 0 ]; then
echo "Behind by $behind commits. Pulling..."
# Pull with appropriate strategy
if [ "$ahead" -gt 0 ]; then
echo "Branches diverged. Using rebase strategy."
git pull --rebase origin "$branch"
else
echo "Fast-forward possible."
git pull origin "$branch"
fi
echo "✓ Pull completed successfully"
else
echo "Already up to date"
fi
}
team_pull_workflow "main"
Terminal window
# Automated repository sync
auto_sync_repositories() {
local repos_dir="$1"
for repo in "$repos_dir"/*/.git; do
local repo_path=$(dirname "$repo")
echo "Syncing $(basename "$repo_path")"
cd "$repo_path" || continue
# Pull with error handling
if git pull --quiet --rebase 2>/dev/null; then
echo "✓ $(basename "$repo_path") synced"
else
echo "✗ $(basename "$repo_path") sync failed"
fi
cd - >/dev/null
done
}
auto_sync_repositories "/path/to/repos"
Terminal window
# Check divergence
git status
# Shows: Your branch and 'origin/main' have diverged
# See divergence details
git log --oneline --graph --decorate HEAD...origin/main
# Resolve with merge
git pull # Creates merge commit
# Or resolve with rebase
git pull --rebase # Replays local commits
Terminal window
# Pull fails with conflicts
git pull
# CONFLICT (content): Merge conflict in file.txt
# Check conflicted files
git status
# Resolve conflicts manually
# Edit conflicted files
# Remove conflict markers (<<<<<<< ======= >>>>>>>)
# Stage resolved files
git add file.txt
# Complete merge
git commit
# Or abort
git merge --abort
Terminal window
# Check remote URL
git remote -v
# Update credentials
git config credential.helper store
# Use SSH instead of HTTPS
git remote set-url origin git@github.com:user/repo.git
# Test authentication
ssh -T git@github.com
Terminal window
# Shallow pull for large repos
git pull --depth=1
# Increase timeout
git config http.lowSpeedLimit 0
git config http.lowSpeedTime 999999
# Use compression
git config core.compression 9
git config core.loosecompression 9
Terminal window
# Update submodules after pull
git submodule update --init --recursive
# Fix detached HEAD in submodules
cd submodule/
git checkout main
cd ..
# Sync submodule URLs
git submodule sync --recursive
#!/bin/bash
# Development environment synchronization
dev_environment_sync() {
echo "=== Development Environment Sync ==="
# Save current work
local has_changes=false
if ! git diff --quiet || ! git diff --cached --quiet; then
echo "Stashing local changes..."
git stash push -m "Auto-stash before pull"
has_changes=true
fi
# Pull latest changes
if git pull --rebase --stat; then
echo "✓ Successfully synced with remote"
# Show what changed
echo "Recent commits:"
git log --oneline -5
# Restore stashed changes
if [ "$has_changes" = true ]; then
echo "Restoring local changes..."
if git stash pop; then
echo "✓ Local changes restored"
else
echo "⚠ Conflicts with restored changes"
echo "Resolve conflicts manually"
fi
fi
else
echo "✗ Sync failed"
if [ "$has_changes" = true ]; then
echo "Local changes are stashed. Run 'git stash pop' to restore"
fi
return 1
fi
}
dev_environment_sync
Terminal window
# Release branch pull strategy
release_branch_pull() {
local release_branch="$1"
echo "=== Release Branch Pull: $release_branch ==="
# Switch to release branch
git checkout "$release_branch"
# Pull with strict fast-forward
if git pull --ff-only origin "$release_branch"; then
echo "✓ Release branch updated successfully"
# Verify no new commits (should be managed through PRs)
local new_commits=$(git rev-list --count "HEAD@{1}..HEAD")
if [ "$new_commits" -gt 0 ]; then
echo "$new_commits new commits added to release branch"
echo "Ensure all changes go through pull requests"
fi
else
echo "✗ Release branch pull failed"
echo "Release branches should only accept fast-forward merges"
echo "Use pull requests for all changes"
return 1
fi
}
release_branch_pull "release/v2.1"
Terminal window
# Manage multiple related repositories
multi_repo_pull() {
local repos_file="$1"
local strategy="${2:-rebase}"
echo "=== Multi-Repository Pull ==="
while IFS='|' read -r repo_path remote branch; do
echo "Processing: $repo_path"
if [ -d "$repo_path/.git" ]; then
cd "$repo_path"
# Pull with specified strategy
if [ "$strategy" = "rebase" ]; then
git pull --rebase "$remote" "$branch"
else
git pull "$remote" "$branch"
fi
cd - >/dev/null
else
echo "Repository not found: $repo_path"
fi
done < "$repos_file"
}
# Repository configuration file format:
# /path/to/repo1|origin|main
# /path/to/repo2|upstream|develop
multi_repo_pull "repositories.txt" "rebase"

What’s the difference between git pull and git fetch?

Section titled “What’s the difference between git pull and git fetch?”

git pull fetches and merges in one operation; git fetch only downloads changes without merging. Use pull for automatic integration, fetch for manual control.

How do I avoid merge commits when pulling?

Section titled “How do I avoid merge commits when pulling?”

Use git pull —rebase to replay local commits on top of fetched changes, maintaining linear history.

Only allows fast-forward merges. Fails if branches have diverged, preventing accidental merge commits.

Resolve conflicts by editing files, removing conflict markers, staging changes with git add, then git commit to complete the merge.

Yes, specify remote name: git pull upstream main. Configure multiple remotes and pull from different sources.

What’s the impact of pull —rebase on history?

Section titled “What’s the impact of pull —rebase on history?”

Rewrites local commit history by replaying commits on new base. Avoid on shared branches to prevent history divergence.

Set pull.rebase=true for rebase by default, or configure per-branch with branch.branchname.rebase.

What happens if pull fails with conflicts?

Section titled “What happens if pull fails with conflicts?”

Pull stops with conflicts marked in files. Resolve conflicts manually, then git commit to complete, or git merge —abort to cancel.

No, pull fetches and merges branch tips. Use git cherry-pick to apply specific commits.

Use —depth=1 for shallow pulls, increase git config http.postBuffer, or pull in smaller batches.

What’s the relationship between pull and submodules?

Section titled “What’s the relationship between pull and submodules?”

git pull —recurse-submodules updates submodules after main repository pull. Configure submodule update strategies separately.

  1. Repository Synchronization: Keep local branches updated with remote changes
  2. Team Collaboration: Integrate team members’ changes into local development
  3. CI/CD Integration: Automated fetching and merging in deployment pipelines
  4. Release Management: Update release branches with approved changes
  5. Development Workflow: Regular synchronization in development environments
  6. Multi-Repository Management: Coordinate updates across related repositories