git diff $(git merge-base master branch)..branch
Merge base is the point where branch diverged from master.
Git diff supports a special syntax for this:
git diff master...branch
Since Git 2.30.0, the special syntax even gets a special switch as a shorthand:
git diff --merge-base master branch
You must not swap the sides because then you would get the other branch. You want to know what changed in branch since it diverged from master, not the other way round.
You may want to replace branch in this syntax with HEAD or even delete it completely -- all the following display the content of the current branch since it diverged from master:
git diff master...HEAD
git diff master...
git diff --merge-base master
Loosely related:
- Finding a branch point with Git?
- How can I see what branch another branch was forked from?
Note that .. and ... syntax does not have the same semantics as in other Git tools. It differs from the meaning specified in man gitrevisions.
Quoting man git-diff:
Answer from Palec on Stack Overflow
git diff [--options] <commit> <commit> [--] [<path>…]This is to view the changes between two arbitrary
<commit>.
git diff [--options] <commit>..<commit> [--] [<path>…]This is synonymous to the previous form. If
<commit>on one side is omitted, it will have the same effect as usingHEADinstead.
git diff [--options] <commit>...<commit> [--] [<path>…]This form is to view the changes on the branch containing and up to the second
<commit>, starting at a common ancestor of both<commit>. "git diff A...B" is equivalent to "git diff $(git-merge-base A B) B". You can omit any one of<commit>, which has the same effect as usingHEADinstead.Just in case you are doing something exotic, it should be noted that all of the
<commit>in the above description, except in the last two forms that use ".." notations, can be any<tree>.For a more complete list of ways to spell
<commit>, see "SPECIFYING REVISIONS" section ingitrevisions[7]. However, "diff" is about comparing two endpoints, not ranges, and the range notations ("<commit>..<commit>" and "<commit>...<commit>") do not mean a range as defined in the "SPECIFYING RANGES" section ingitrevisions[7].
git diff $(git merge-base master branch)..branch
Merge base is the point where branch diverged from master.
Git diff supports a special syntax for this:
git diff master...branch
Since Git 2.30.0, the special syntax even gets a special switch as a shorthand:
git diff --merge-base master branch
You must not swap the sides because then you would get the other branch. You want to know what changed in branch since it diverged from master, not the other way round.
You may want to replace branch in this syntax with HEAD or even delete it completely -- all the following display the content of the current branch since it diverged from master:
git diff master...HEAD
git diff master...
git diff --merge-base master
Loosely related:
- Finding a branch point with Git?
- How can I see what branch another branch was forked from?
Note that .. and ... syntax does not have the same semantics as in other Git tools. It differs from the meaning specified in man gitrevisions.
Quoting man git-diff:
git diff [--options] <commit> <commit> [--] [<path>…]This is to view the changes between two arbitrary
<commit>.
git diff [--options] <commit>..<commit> [--] [<path>…]This is synonymous to the previous form. If
<commit>on one side is omitted, it will have the same effect as usingHEADinstead.
git diff [--options] <commit>...<commit> [--] [<path>…]This form is to view the changes on the branch containing and up to the second
<commit>, starting at a common ancestor of both<commit>. "git diff A...B" is equivalent to "git diff $(git-merge-base A B) B". You can omit any one of<commit>, which has the same effect as usingHEADinstead.Just in case you are doing something exotic, it should be noted that all of the
<commit>in the above description, except in the last two forms that use ".." notations, can be any<tree>.For a more complete list of ways to spell
<commit>, see "SPECIFYING REVISIONS" section ingitrevisions[7]. However, "diff" is about comparing two endpoints, not ranges, and the range notations ("<commit>..<commit>" and "<commit>...<commit>") do not mean a range as defined in the "SPECIFYING RANGES" section ingitrevisions[7].
Here's what worked for me:
git diff origin/master...
This shows only the changes between my currently selected local branch and the remote master branch, and ignores all changes in my local branch that came from merge commits.
[tip] use snacks.picker to see git diff with current branch and master
vim - Display git-diff between master and my last commit - Unix & Linux Stack Exchange
Understanding diff against current ?
'git diff' between current workspace and master - Stack Overflow
Videos
Just custom finder for snacks.picker to see difference between your current branch and master branch. Sure you can choose any branch instead of master. It's useful for me, because git_status shows only current changes and i can't see them after git commit.
Snacks.picker.git_diff {
finder = function(opts, ctx)
local file, line
local header, hunk = {}, {}
local header_len = 4
local finder = require('snacks.picker.source.proc').proc({
opts,
{
cmd = 'git',
args = {
'-c',
'core.quotepath=false',
'--no-pager',
'diff',
'origin/master...HEAD',
'--no-color',
'--no-ext-diff',
},
},
}, ctx)
return function(cb)
local function add()
if file and line and #hunk > 0 then
local diff = table.concat(header, '\n') .. '\n' .. table.concat(hunk, '\n')
cb {
text = file .. ':' .. line,
diff = diff,
file = file,
pos = { line, 0 },
preview = { text = diff, ft = 'diff', loc = false },
}
end
hunk = {}
end
finder(function(proc_item)
local text = proc_item.text
if text:find('diff', 1, true) == 1 then
add()
file = text:match '^diff .* a/(.*) b/.*$'
header = { text }
header_len = 4
elseif file and #header < header_len then
if text:find '^deleted file' then
header_len = 5
end
header[#header + 1] = text
elseif text:find('@', 1, true) == 1 then
add()
-- Hunk header
-- @example "@@ -157,20 +157,6 @@ some content"
line = tonumber(string.match(text, '@@ %-.*,.* %+(.*),.* @@'))
hunk = { text }
elseif #hunk > 0 then
hunk[#hunk + 1] = text
else
error('unexpected line: ' .. text)
end
end)
add()
end
end,
}
This is not a very 'git like' way to approach the problem. Normally you would just keep a branch which pointed to your last commit.
However to answer the question, try the following helper function. This is not going to be very efficient, I probably need to user some lower level commands.
my_last_commit(){
local ME="$(git config user.name)"
git log --format='%h%n' --author="$ME" -1
}
Then you can do git diff $(my_last_commit)..HEAD (omit HEAD if you like as it is the default) or git logadog $(my_last_commit)^..
Don't be such a trusting person. ;-)
Sorry, sorry. Speaking more seriously -- the moment just before you merge is the perfect time to inspect what's changed between your work and your peers'. If you run it before merging, this will show you what's about to change when you merge:
git fetch
git diff ...@{upstream}
In fact, in my own workflow, I've got a "whatsnew" alias for git log ..@{upstream}.
If you'd rather merge first and ask questions later, you could create a temporary branch as a placemarker:
git fetch
git branch -c my_last_commit # or use -C to overwrite if it already exists
git merge
git diff my_last_commit...
This is the real basics of Git. I strongly recommend going through a visual Git tutorial (just google that). Also, I recommend getting the open source GUI tool Git Extensions so you can visually see your commits/branches and learn different commands easier.
Some terminology and beginner's tips:
- You cloned a remote repository (usually called
originby default) into a local repository on your PC. - You do have a workspace locally, but it's a combination of several things:
- The local Git repository itself, where all the information about the commit history is stored, this allows you to recreate the working directory for any commit.
- The Working Directory - these are ongoing changes and differences that have not yet been committed into the repository
- The Index - this is where changes from the working directory have been staged and are ready to be committed.
- The Stash - this is a sort of temporary commit, where you can save the current changes from your Working directory and/or index temporarily while you go off and do something else in your repository.
- Cloning actually creates a duplicate of the remote repository on your PC, that you can commit changes to your new local repository separately from the remote repository (then sync up with it using pull and push). Not only can you commit changes locally, updating the repository, but before you can commit changes locally, you must stage them into your index. Only items in the index get committed, and then only commits get pushed to the remote repository.
- When you pull from the remote repository, it brings down any new commits from the current branch you have checked out (with
git fetch), and then willgit mergeyour localmasterbranch into the remotemasterbranch that you just pulled down. - Unless you have created a new branch and committed locally, you are likely in the
masterbranch. - Merging may cause a merge conflict that you would have to resolve before committing the merge locally, and then finally pushing your local commits to the remote.
How to see changes ready for committing:
- If you want to see the list of changes in your working directory (unstaged) and your index (staged and ready for a commit), type
git status. - If you also want see the actual changes in each file that is changed, then you can type
git diff HEAD.
Although it's really easy in Git Extensions to see the current changes - just hit the "Commit" button, and a window pops up with the working directory on top left, index on bottom left, and if you click on any file in them, you'll see all the changes for that file on the right side.
This is Not the Diff You're Looking For
(Sorry - couldn't resist the Star Wars quote)
Okay, I finally understand your core question - you are not making changes to the local repository, you just want to see the changes between the repository before the pull and after the pull - to see what changed since the last time you pulled.
This can be done by getting the hash of the last commit on master before the pull, and then using:
git diff <hash of prior commit> HEAD
HEAD refers to whichever commit is currently checked out, either the current commit of the branch you checked out, or a particular commit if you checked one out directly (this is a state called a "detached HEAD"). HEAD will point to master which will should point to the latest commit in the repository after a successful pull.
Instead of using HEAD, you could put the actual hash of the latest commit. Note that if you know how many commits were pulled down, you don't even need to know the commit hashes. For example, if the prior commit was two commits back, you can use:
git diff HEAD~2 HEAD
The HEAD~2 just looks two commits back in the log from HEAD, and uses that hash.
To do this with a GUI, in Git Extensions, you can just right-click on the prior commit and select "Compare → Compare to current branch" in order to pull up the diff window with the changes between that commit and the current location of your current branch.
The currently checked out branch/commit is shown in bold in Git Extensions, and should always be at the top of the list and have a >master tag next to it for your situation.
In general, you are always on a branch in Git (an exception might the detached head state). Unless you recall creating a branch, my guess is that you are on the master branch. To see changes you have made relative to where you began, you can use the following from the command line:
git diff HEAD
If you are using an IDE such as IntelliJ or Eclipse, with a Git plugin, then you can visually see many more types of diffs of the files in your workspace.
To compare the current branch against main branch:
$ git diff --name-status main
To compare any two branches:
$ git diff --name-status firstbranch..yourBranchName
There are more options to git diff in the official documentation (and specifically the --name-status option).
Try
$ git diff --stat --color master..branchName
This will give you more info about each change, while still using the same number of lines.
You can also flip the branches to get an even clearer picture of the difference if you were to merge the other way:
$ git diff --stat --color branchName..master
The following works for me:
git diff master:foo foo
In the past, it may have been:
git diff foo master:foo
You're trying to compare your working tree with a particular branch name, so you want this:
git diff master -- foo
Which is from this form of git-diff (see the git-diff manpage)
git diff [--options] <commit> [--] [<path>...]
This form is to view the changes you have in your working tree
relative to the named <commit>. You can use HEAD to compare it with
the latest commit, or a branch name to compare with the tip of a
different branch.
FYI, there is also a --cached (aka --staged) option for viewing the diff of what you've staged, rather than everything in your working tree:
git diff [--options] --cached [<commit>] [--] [<path>...]
This form is to view the changes you staged for the next commit
relative to the named <commit>.
...
--staged is a synonym of --cached.