Using Git how do I find changes between local and remote

GitMercurial

Git Problem Overview


Here are two different questions but I think they are related.

  1. When using Git, how do I find which changes I have committed locally, but haven't yet pushed to a remote branch? I'm looking for something similar to the Mercurial command hg outgoing.

  2. When using Git, how do I find what changes a remote branch has prior to doing a pull? I'm looking for something similar to the Mercurial command hg incoming.

For the second: is there a way to see what is available and then cherry-pick the changes I want to pull?

Git Solutions


Solution 1 - Git

Starting with Git 1.7.0, there is a special syntax that allows you to generically refer to the upstream branch: @{u} or @{upstream}.

To mimic hg incoming:

git log ..@{u}

To mimic hg outgoing:

git log @{u}..

I use the following incoming and outgoing aliases to make the above easier to use:

git config --global alias.incoming '!git remote update -p; git log ..@{u}'
git config --global alias.outgoing 'log @{u}..'

Solution 2 - Git

Git can't send that kind of information over the network, like Hg can. But you can run git fetch (which is more like hg pull than hg fetch) to fetch new commits from your remote servers.

So, if you have a branch called master and a remote called origin, after running git fetch, you should also have a branch called origin/master. You can then get the git log of all commits that master needs to be a superset of origin/master by doing git log master..origin/master. Invert those two to get the opposite.

A friend of mine, David Dollar, has created a couple of git shell scripts to simulate hg incoming/outgoing. You can find them at http://github.com/ddollar/git-utils.

Solution 3 - Git

Not a full answer but git fetch will pull the remote repo and not do a merge. You can then do a

git diff master origin/master

Solution 4 - Git

  1. Use "git log origin..HEAD"

  2. Use "git fetch" followed by "git log HEAD..origin". You can cherry-pick individual commits using the listed commit ids.

The above assumes, of course, that "origin" is the name of your remote tracking branch (which it is if you've used clone with default options).

Solution 5 - Git

There's also this, for comparing all branches:

git log --branches --not --remotes=origin

This is what the git log man page says about this:

> Shows all commits that are in any of > local branches but not in any of > remote tracking branches for origin > (what you have that origin doesn’t).

The above is for outgoing. For incoming, just swap:

git log --remotes=origin --not --branches

Solution 6 - Git

I would do

$ git fetch --dry-run

for hg incoming and

$ git push --dry-run

for hg outgoing.

Solution 7 - Git

git-out is a script that emulates hg outgoing quite accurately. It parses on "push -n" output, so it produces accurate output if you need to specify additional arguments to push.

Solution 8 - Git

git incoming

$ git fetch && git log ..origin/master --stat
OR
$ git fetch && git log ..origin/master --patch

git outgoing

$ git fetch && git log origin/master.. --stat
OR
$ git fetch && git log origin/master.. --patch

Solution 9 - Git

When the "git log" and @{u} answers initially gave me "unknown revision" errors, I tried out Chris/romkyns suggestion of git push --dry-run.

You will get an output such as "5905..4878 master->master". 5905 is the latest commit that the remote has and commits through (and including) 4878 will be applied to the remote.

You can then use 5905..4878 as arguments to several other git commands to get more details:

git diff 5905..4878 # Gives full code changes in diff style

git log --online 5905..4878 # Displays each commit's comment

Solution 10 - Git

Incoming commits across all branches can be shown with the following approach.

The command git fetch-diff becomes available by adding an executable called git-fetch-diff to your PATH, containing:

#!/bin/bash

set -e

# get hashes before fetch
old_hashes=$(git log --all --no-color --pretty=format:"%H")

# perform the fetch
git fetch

# get hashes after fetch
new_hashes=$(git log --all --no-color --pretty=format:"%H")

# get the difference
added_hashes=$(comm -1 -3 <(echo "$old_hashes") <(echo "$new_hashes"))

# print added hashes
[ ! -z "$added_hashes" ] && echo "$added_hashes" | git log --stdin --no-walk --oneline

Commit hashes are compared before and after the fetch. The difference is piped back to git log for pretty printing. The appearance of the printed log can be further tuned to your liking with arguments such as --pretty=<format> and --graph.

Note: You might want to cap how far git log will go back in time depending on how much a bash variable can hold on your system, or for performance reasons. This can be done by adding the argument --max-count=<count>.

Solution 11 - Git

When you do git fetch, all the contents including branches,tags ( refs) are stored temporarily in .git/FETCH_HEAD whose content can be viewed with command: git log FETCH_HEAD If you don't use suffix -a with git fetch then by default, FETCH_HEAD's content's will be overwritten by new contents. From these contents, you can view and decide to which branch you want to merge them if you do or you can simple cherry-pick if you want only a few commits from what has been brought by fetch.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionejunkerView Question on Stackoverflow
Solution 1 - GitRichard HansenView Answer on Stackoverflow
Solution 2 - GitJordi BunsterView Answer on Stackoverflow
Solution 3 - GitMartin RedmondView Answer on Stackoverflow
Solution 4 - GitGreg HewgillView Answer on Stackoverflow
Solution 5 - GitrobinstView Answer on Stackoverflow
Solution 6 - GitchrisView Answer on Stackoverflow
Solution 7 - GitstepanchegView Answer on Stackoverflow
Solution 8 - GitprayagupaView Answer on Stackoverflow
Solution 9 - Gitpierce.jasonView Answer on Stackoverflow
Solution 10 - GitgospesView Answer on Stackoverflow
Solution 11 - GitAMIT PRAKASH PANDEYView Answer on Stackoverflow