Richard
Richard

Reputation: 65510

git diff last commit plus all uncommitted changes?

I am working on a repo on a brach, and I have some uncommitted changes.

$ git status
<my local changes>

I also have a previous "work in progress" commit with a lot of diffs in, made by a colleague.

$ git log
commit 6b388883f3e3cf2a864aeb335ce36e10f0e7a60d
Date:   Thu Jan 15 12:39:26 2015 +0000

    Work in progress

commit 91c868cda56e309b9a417f21c929a1beb1cc74d4
Date:   Thu Jan 14 12:39:26 2015 +0000

    <Last "real" commit to master>

I'm now planning to create a new branch based off master (aka 91c868cda56e309b9a417f21c929a1beb1cc74d4), and make a brand new set of neat structured commits, to make a clean PR.

To do that, it would be very helpful to output a single diff, with all the changes made (both committed and uncommitted) since the last "real" commit, 91c868cda56e309b9a417f21c929a1beb1cc74d4.

This is a throwaway branch, so it doesn't matter what I do on this branch.

What's the best way to do this?

One idea I had is that I could commit all my local changes, and then diff between that commit and 91c868cda56e309b9a417f21c929a1beb1cc74d4: is it possible to see a single diff of all the changes between those two commits?

Upvotes: 1

Views: 2537

Answers (1)

torek
torek

Reputation: 487755

With git diff you have to select two sets-of-files to compare. You can do this by specifying two revisions explicitly, e.g., git diff HEAD~3 HEAD^, which diffs those two commits. Or, you can diff some commit with your work-tree, or with your index/staging-area; or compare your index/staging-area to your work-tree.

To diff one commit against your current work-tree, name one commit: git diff HEAD, git diff HEAD^, git diff HEAD~2, and so on. If you do not name a particular commit, however, git diff compares your index/staging area against your work-tree, rather than using the HEAD commit.

To diff one commit against your index/staging area, name one commit and also use --cached: git diff --cached HEAD~2, and so on. Name no commits and git defaults to using HEAD here.

If you name two commits, git diff compares those two commits. You can write both of them as separate commits, git diff HEAD~2 HEAD for instance, or you can use the .. format: git diff HEAD~2..HEAD. Here --cached makes no sense, since it means "use index instead of work-directory" and the diff is not using the work-dir.

In your particular case here, comparing HEAD^, which names commit 91c868cda56e309b9a417f21c929a1beb1cc74d4, to your work-tree is what you want now. If you do make a new commit now, though, comparing HEAD^^ (or explicit commit 91c868cda56e309b9a417f21c929a1beb1cc74d4) to your new commit will be what you want. Your new commit will be the new HEAD so you can diff HEAD^^ vs HEAD at that point.

See the gitrevisions documentation for many ways to spell particular revisions.


Note that additional arguments that are not diff flags (diff flags being things like -w to ignore white space) are taken as path-specifiers, to limit the set of files diffed. For instance, if you're just curious what happened to path/to/file.txt between two revisions:

git diff rev1 rev2 path/to/file.txt

If a file name "looks like" a diff flag (what if you want to see what happened to the file named --cached for instance?) you can use -- to separate "arguments meant to control the diff itself" from "path names meant to limit which paths are diffed".

Upvotes: 2

Related Questions