How to list unpushed Git commits (local but not on origin)
How can I view local commits that haven’t been pushed to the remote repository in Git? Occasionally, git status shows that my branch is X commits ahead of origin/master, but this doesn’t always happen. Is this a Git installation issue, or am I misunderstanding something about Git’s status reporting?
To list unpushed Git commits, use git log origin/master..HEAD to see commits in your local branch that aren’t on the remote, or git log --oneline origin/master..HEAD for a condensed view. The “X commits ahead” message in git status appears when your branch has diverged from its remote counterpart, which is normal Git behavior indicating local commits that haven’t been pushed yet.
Contents
- Understanding Git Status
- Basic Methods to List Unpushed Commits
- Advanced Git Commands for Unpushed Commits
- Understanding Remote Tracking Branches
- Common Issues and Troubleshooting
- Best Practices for Managing Commits
- Automating Commit Checking
Understanding Git Status
Git status provides valuable information about your repository’s state, including whether you have unpushed commits. When you see “Your branch is ahead of ‘origin/master’ by X commits, 1 branch(es) can be fast-forwarded,” this is not a Git installation issue—it’s normal behavior indicating your local branch has commits that haven’t been pushed to the remote repository.
The status message appears because Git tracks the relationship between your local branch and its corresponding remote tracking branch (typically origin/master or origin/main). When you make commits locally but haven’t pushed them, Git recognizes this divergence and reports it accordingly.
Important: The status message only appears when there’s a direct relationship between your local branch and a remote tracking branch. This is established when you run
git push -u origin <branch-name>orgit pullwithout the--no-trackoption.
Basic Methods to List Unpushed Commits
Using Git Log with Range Specifications
The most straightforward way to list unpushed commits is using git log with a range specification:
# Show all unpushed commits in detail
git log origin/master..HEAD
# Show unpushed commits in condensed format
git log --oneline origin/master..HEAD
# Show unpushed commits with patch
git log -p origin/master..HEAD
The syntax origin/master..HEAD means “show commits reachable from HEAD but not from origin/master.” This effectively shows all local commits that haven’t been pushed to the remote.
Alternative Log Commands
Git offers several alternative ways to view unpushed commits:
# Show commits that exist locally but not remotely
git log --not --remotes=origin
# Show commits that will be pushed with next push
git log --branches --not --remotes=origin
# Show unpushed commits with author and date
git log --pretty=format:"%h %an %ad" --date=short origin/master..HEAD
Using Git Log with Graph View
For better visualization of the commit history:
# Show unpushed commits with graph
git log --graph --oneline origin/master..HEAD
# Show unpushed commits with detailed graph
git log --graph --decorate --oneline origin/master..HEAD
Advanced Git Commands for Unpushed Commits
Using Git Cherry-Pick to Identify Unpushed Commits
# List unpushed commits with their commit hashes
git log origin/master..HEAD --pretty=format:"%H"
# Count unpushed commits
git rev-list --count origin/master..HEAD
# Show unpushed commits in reverse chronological order
git log --reverse origin/master..HEAD
Using Git Diff to Compare Branches
While not exactly listing commits, git diff can show you what changes exist locally but not remotely:
# Show diff between remote and local branch
git diff origin/master..HEAD
# Show summary of unpushed changes
git diff --stat origin/master..HEAD
Using Git Range-Select
Git’s range-select syntax provides more flexible options:
# Show commits from remote to local (excluding remote commits)
git log HEAD ^origin/master
# Show commits that will be pushed
git log --branches --not --remotes=origin
Understanding Remote Tracking Branches
Remote tracking branches are Git’s mechanism for keeping track of the state of remote branches. When you run git clone, Git automatically creates remote tracking branches like origin/master that mirror the state of the remote repository.
Checking Remote Tracking Status
# Show all remote tracking branches
git branch -r
# Show all branches (local and remote)
git branch -a
# Show the branch you're currently on and its upstream
git branch -vv
The -vv (very verbose) option shows you the relationship between your local branches and their remote tracking branches, including how many commits are ahead or behind.
Setting Upstream Tracking
If you don’t see “ahead of” messages, your branch might not be properly set up to track a remote:
# Set upstream tracking for existing branch
git branch --set-upstream-to=origin/master master
# Or when pushing for the first time
git push -u origin master
Common Issues and Troubleshooting
Why Git Status Doesn’t Show Ahead Count
If git status doesn’t show how many commits you’re ahead, the most common reasons are:
- No upstream tracking: Your local branch doesn’t have a remote tracking branch set up.
- Different branch names: Your local branch might not correspond to a remote branch.
- Detached HEAD state: You’re not on a branch.
- Different remote names: You might be using a different remote name than “origin”.
Checking and Fixing Remote Tracking
# Check if your branch has an upstream
git status
# Set upstream if missing
git push --set-upstream origin <branch-name>
# Or for existing branches
git branch --set-upstream-to=origin/<branch-name> <branch-name>
Dealing with Multiple Remotes
If you work with multiple remotes:
# Show commits not on any remote
git log --not --remotes
# Show commits not on specific remote
git log --not --remotes=origin
# Show commits not on any remote except origin
git log --not --remotes=upstream
Best Practices for Managing Commits
Regular Pushing Habits
- Push frequently: Make it a habit to push commits regularly to avoid large unpushed changesets.
- Review before pushing: Use
git log origin/master..HEADto review what you’re about to push. - Use meaningful commit messages: This makes it easier to identify specific commits when reviewing.
Branch Management
# Create and switch to new branch with tracking
git checkout -b feature-branch origin/master
# Or create and set tracking in one command
git switch -c feature-branch --track origin/master
Using Git Status Effectively
Get in the habit of checking git status regularly and understanding what it tells you:
# Check status with more details
git status -v
# Check status briefly
git status --short
Automating Commit Checking
Creating Aliases for Common Commands
Add these to your ~/.gitconfig for easier access:
[alias]
unpushed = log --oneline origin/master..HEAD
unpushed-count = rev-list --count origin/master..HEAD
unpushed-graph = log --graph --oneline origin/master..HEAD
ahead-status = branch -vv
Then use them like:
git unpushed git unpushed-count git ahead-status
Pre-commit Hook for Checking Unpushed Commits
You can create a pre-commit hook that reminds you to push existing commits before making new ones:
#!/bin/bash
# .git/hooks/pre-commit
UNPUSHED=$(git rev-list --count origin/master..HEAD)
if [ "$UNPUSHED" -gt 0 ]; then
echo "Warning: You have $UNPUSHED unpushed commits"
echo "Consider running: git push"
fi
Make it executable with chmod +x .git/hooks/pre-commit.
Conclusion
- Use
git log origin/master..HEADorgit log --oneline origin/master..HEADto list unpushed commits in your local repository - The “X commits ahead” message in
git statusis normal Git behavior indicating local commits that haven’t been pushed - Ensure your branches are properly set up with remote tracking using
git branch -vvto check relationships - Create aliases in your Git configuration for easier access to common unpushed commit commands
- Make regular pushing a habit to avoid accumulating many unpushed commits
- If
git statusdoesn’t show ahead counts, check if your branch has proper upstream tracking set up
Understanding how to track and manage unpushed commits is essential for effective collaboration and maintaining a clean Git workflow. By mastering these commands and understanding the relationship between local and remote branches, you can better manage your development process and avoid common pitfalls.