353

Is there a way to see what files have changed in a branch?

nickf
  • 537,072
  • 198
  • 649
  • 721
Raif
  • 8,641
  • 13
  • 45
  • 56
  • 6
    possible duplicate of [How can I find out which files have been modified in a branch?](http://stackoverflow.com/questions/1749323/how-can-i-find-out-which-files-have-been-modified-in-a-branch) – Matt Ball May 17 '12 at 18:24
  • 2
    They are not my employees they are my colleagues and it's not them in particular so much as people in general. But yea, re-reading this post it does seem a bit agro. :) – Raif Jan 26 '15 at 14:49
  • 4
    Can you use github or bitbucket, gitlab? There are tools to manage exactly this situation. The developer makes a pull request. You get the request and you will have access to a very good interface that will show you a diff of all the changes made to each file. You can even comment, ask for changes etc. When the changes are good you can accept the request which will merge the changes into the requested branch (typically develop). That is the best practice way to handle this situation. – Scott Wright May 31 '16 at 16:11
  • Does this answer your question? [How can I find out which files have been modified in a branch?](https://stackoverflow.com/questions/1749323/how-can-i-find-out-which-files-have-been-modified-in-a-branch) – mahen3d Mar 09 '21 at 23:46

17 Answers17

252

An alternative to the answer by @Marco Ponti, and avoiding the checkout:

git diff --name-only <notMainDev> $(git merge-base <notMainDev> <mainDev>)

If your particular shell doesn't understand the $() construct, use back-ticks instead.

twalberg
  • 59,951
  • 11
  • 89
  • 84
  • 2
    ah! this is good fun, now how about if I want to have say be the current branch I'm on. that is not have to specify it? – Raif May 17 '12 at 19:07
  • 49
    `git diff --name-only ` will show you what files are different between your current branch and ``. So it's essentially the same command, but note that you can use this to find the files that are different between *any* two branches, even if they're not remotely related. Whether that comparison is useful or not depends on the topology of your branches... Also, note `` really could be any commit at all, or anything that resolves to one (tags, etc.). – twalberg May 17 '12 at 19:12
  • hmmm, well, I guess what I mean is that I would like to do git diff --name-only $(git merge-base ) where MY_CURRENT_CO_BRANCH would of course be my current checked out branch – Raif May 17 '12 at 19:22
  • You can do that, as well. That will find the point where `` and `` most recently had a common ancestor, and compare `` to that ancestor. You'll have to provide your current branch name, though, as `git merge-base` expects two arguments - there's not a shortcut, at least in the current version. – twalberg May 17 '12 at 19:30
  • 1
    ok! I got it. Courtesy of my colleague what's his name. git merge-base `git branch | grep '\*' | awk '{print $2}'` that will get the commit for the branch between and my current branch. I can then do git diff --name-only $(git merge-base `git branch | grep '\*' | awk '{print $2}'`) – Raif May 17 '12 at 19:54
  • and for the coop-d`etat [alias] diffbranch = "!sh -c 'git diff --name-only $1 `git merge-base $1 $(git name-rev HEAD 2> /dev/null | cut -f2)`' -" !!! – Raif May 17 '12 at 20:25
  • Nice answer! I'm using Windows was only able to get the `$()` syntax working by using a git bash session - any tips for how I might get it to work in a standard command window (so I can put it in a batch file)? – Steve Chambers Dec 14 '16 at 09:53
  • Have now worked out how to run a bash command from a batch file - too long to put in a comment so [added an answer below](http://stackoverflow.com/questions/10641361#41140067). – Steve Chambers Dec 14 '16 at 10:24
  • Slightly shorter syntax for the current branch: git diff --name-only $(git merge-base master HEAD)... – Alcamtar Mar 27 '18 at 23:44
  • This gives the wrong status type for changes. See my answer for an alternative. – Connor Clark Jul 10 '18 at 06:33
  • 1
    A tip for the uninitiated like me... `git diff --name-only origin/branchX $(git merge-base origin/branchX origin/master)` vs `git diff --name-only branchX $(git merge-base branchX master)` which gives `fatal: Not a valid object name branchX. fatal: ambiguous argument 'branchX': unknown revision or path not in the working tree.` – jxramos Feb 05 '19 at 00:53
  • for me this did not work. It showed way to many files.. Don't know what could be the problem. – L.Rex Jul 28 '20 at 10:39
  • 2
    With Git 2.30 and newer, the above code can be replaced by `git diff --merge-base --name-only `. – nachtjasmin Sep 28 '21 at 06:45
  • How to do this on bitbucket? – TomTerrific Dec 22 '21 at 20:57
223

All you have to do is the following:

git checkout <notMainDev>
git diff --name-only <mainDev>

This will show you only the filenames that are different between the two branches.

Marco Ponti
  • 2,469
  • 1
  • 13
  • 4
  • wow quick and too the point. thank you. btw I love git. it's always quick and to the point – Raif May 17 '12 at 18:30
  • 29
    I believe that will also show stuff that has changed on `` since the branches diverged, though. You might want to use `git diff --name-only ` instead, or see the alternate answer I posted that avoids the checkout. – twalberg May 17 '12 at 18:56
  • Yes, that is true @twalberg it would show those changes if the branches are diverged. I was assuming the `notMainDev` would be kept up to date with the mainDev commits...I usually find it useful to see those differences as well though. – Marco Ponti May 17 '12 at 19:20
  • 1
    can't you just specify --right-only to only show the files that were changed on the right side? – TheZenker Apr 13 '17 at 18:40
  • 2
    you get the `` with `git rev-parse ` – fc9.30 Feb 01 '19 at 15:09
117

amazed this has not been said so far!

git diff main...branch

So see the changes only on branch

To check the current branch use

git diff main...

Thanks to jqr

This is short hand for

git diff $(git merge-base main branch) branch

so the merge base (the most recent common commit between the branches) and the branch tip

Also using origin/main instead of just master will help in case your local main is dated

Norfeldt
  • 8,272
  • 23
  • 96
  • 152
exussum
  • 18,275
  • 8
  • 32
  • 65
  • 8
    While this shows what has changed, it shows the ALL changes, rather than a summary of the changed files... which is what lead me to this page in the first place :) – Chris Rutledge Dec 10 '18 at 16:31
  • 2
    then add the --name-only flag to this. or --short-stat – exussum Dec 10 '18 at 16:42
  • 9
    `git diff --name-only master..` if you just want the names of files that are different between the two branches. – Adam May 07 '19 at 14:50
  • 4
    This won't work properly if your master had commits after you created your side-branch. – simplylizz Oct 11 '19 at 10:19
  • 4
    @simplylizz yes it does. thats exactly what this is solving – exussum Oct 11 '19 at 10:55
  • 1
    @exussum oh, indeed. Confused three and two dots. – simplylizz Oct 11 '19 at 12:54
  • for me this did not work. It showed way to many files.. Don't know what could be the problem. – L.Rex Jul 28 '20 at 10:38
  • if the repo is public I am happy to take a look, did you use 3 dots ? – exussum Jul 28 '20 at 19:10
  • In case any one else pops in here to read comments. This worked perfect for me. I had a `master` branch and a `feature` branch. The `master` branch was way ahead by a bunch of commits. The `feature` branch was behind, but also had `master` merged into it a few times to pull updates. using `git diff --name-status master...feature` gave me exactly what Upsource was showing in the branch review. – Chad Baldwin Oct 15 '21 at 20:56
  • Combined with other answers: `git diff --name-only main...` or, if you have `diffstat`, you could also pipe the result through `diffstat`: `git diff main... | diffstat`. – Atafar Nov 17 '22 at 10:03
  • This precise syntax actually dumps you into interactive mode, while the OP asked how to get the files. – Kraken Jul 11 '23 at 13:15
  • I'm guessing what ever your pager is is doing that. This command will just spit out files – exussum Jul 11 '23 at 18:18
75

I can't believe there are so many ways to do this. I use whatchanged as someone posted before, just with the following arguments:

git whatchanged --name-only --pretty="" origin..HEAD

This just lists the filenames, and only the ones that changed on the current branch.

lukiller
  • 1,107
  • 9
  • 12
  • 3
    This appears to be the easiest answer here as it requires no additional information. The output looks correct and it's way easier to remember than the accepted answer! – RickMeasham Dec 08 '16 at 00:20
  • 1
    Thanks, this is interesting, more wordy. It provides output fro each commit, in reverse order. _git-whatchanged - Show logs with difference each commit introduces_ https://git-scm.com/docs/git-whatchanged – nealmcb Jul 27 '17 at 12:14
  • 2
    From the [git docs](https://git-scm.com/docs/git-whatchanged): `New users are encouraged to use git-log instead. The whatchanged command is essentially the same as git-log but defaults to show the raw format diff output and to skip merges.` – Derek Mar 06 '19 at 22:31
  • 3
    This seems to do what I'm looking for by only printing changes the branch makes alone. It does however print files twice, so I pipe it to `sort -u` – jxramos Aug 13 '20 at 23:23
  • 1
    Yeah, the problem with whatchanged is as @jxramos mentioned: it's actually git log, so it shows things commit by commit. If you've made multiple commits to the same file, you get multiple copies of those names (unlike with git diff). – Jaykul Nov 30 '21 at 15:01
  • This should have been the accepted answer – Shubham Jain Feb 16 '22 at 16:51
  • This is the best answer – Tony Ennis Jun 16 '22 at 17:04
33

Update Nov 2020:

To get the list of files modified (and committed!) in the current branch you can use the shortest console command using standard :

git diff --name-only master...


  • If your local "master" branch is outdated (behind the remote), add a remote name (assuming it is "origin"):

    git diff --name-only origin/master...

  • If you want to include uncommitted changes as well, remove the ...:

    git diff --name-only master

  • If you use different main branch name (eg: "main"), substitute it:

    git diff --name-only main...

  • If your want to output to stdout (so its copyable):

    git diff --name-only master... | cat

  • If your want filenames to be clickable in VSCode terminal no matter what folder you are running this command from, add --relative:

    git diff --name-only --relative master... | cat


per really nice detailed explanation of different options https://blog.jpalardy.com/posts/git-how-to-find-modified-files-on-a-branch/

c69
  • 19,951
  • 7
  • 52
  • 82
  • [`diff`](https://git-scm.com/docs/git-diff) has much more options and overall [tag:git-diff] is super awesome ;) – c69 Mar 26 '21 at 00:17
32

I really liked @twalberg's answer but I didn't want to have to type the current branch name all the time. So I'm using this:

git diff --name-only $(git merge-base master HEAD)
Yep_It's_Me
  • 4,494
  • 4
  • 43
  • 66
  • 2
    Your solution works for me and I get the list of files that I expect to see. I'm a Git novice and have used `git diff master... --name-only` when run on the target branch and get the same result. Could you be so kind as to provide any feedback to what's good vs bad between your answer and the command I've provided? – hungerstar Dec 12 '18 at 22:56
  • 1
    Your command will work exactly the same, if master does not have any new commits since your branch was created. I think my command will be equivalent to `git diff master.. --name-only` (note there is only 2 dots instead of 3). To understand what the dots mean, see [this answer](https://stackoverflow.com/a/24186641/1393498) – Yep_It's_Me Dec 13 '18 at 02:33
  • 1
    Awesome! Thanks for the quick reply and insight. Much appreciated. – hungerstar Dec 13 '18 at 16:19
20
git diff --name-only master...branch-name

to which we want to compare.

Rajesh Dusa
  • 201
  • 2
  • 3
  • Seems like a partial of an existing answer, https://stackoverflow.com/a/41486181/11912 – James Skemp Nov 08 '18 at 16:30
  • 1
    This variation compares the HEAD of master to a current branch. The accepted answer compares the state of master *at the point you forked*. Either may have the answer you are looking for, depending on what you want to know. – Mark Stosberg May 08 '19 at 15:44
15

git whatchanged seems to be a good alternative.

chalasr
  • 12,971
  • 4
  • 40
  • 82
  • 2
    What was exactly that I was looking for. – Sild Oct 17 '16 at 11:03
  • 1
    From the [git docs](https://git-scm.com/docs/git-whatchanged): `New users are encouraged to use git-log instead. The whatchanged command is essentially the same as git-log but defaults to show the raw format diff output and to skip merges.` – Derek Mar 06 '19 at 22:26
8

What if it could be as easy as this?

git changed

If you're willing to assume that the main branch is called "master", and that you create your other branches from master, then you can add this alias to your ~/.gitconfig file to make it that easy:

cbranch = !"git branch | grep '*' | cut -f2 -d' '"
changed = !"git diff --name-only $(git cbranch) $(git merge-base $(git cbranch) master)"

Those assumptions will work for most people in most situations, but you must be aware that you're making them.

Also, you must use a shell that supports $(). It's very likely that your shell supports this.

Community
  • 1
  • 1
iconoclast
  • 21,213
  • 15
  • 102
  • 138
4

For some reason no one mentioned git-tree. See https://stackoverflow.com/a/424142/1657819

git-tree is preferred because it's a plumbing command; meant to be programmatic (and, presumably, faster)

(assuming base branch is master)

git diff-tree --no-commit-id --name-only -r master..branch-name

However this will show you all files which were affected in the branch, if you want to see explicitly modified files only, you can use --diff-filter:

git diff-tree --no-commit-id --name-only -r master..branch-name --diff-filter=M

Also one can use --name-status instead of --name-only to see the status of the files (A/M/D and so on)

The Godfather
  • 4,235
  • 4
  • 39
  • 61
  • This was just what I needed for linting changed files while excluding those that were deleted. `rubocop --fail-level error $(git diff-tree --no-commit-id --name-only -r origin/master..HEAD --diff-filter=M)` – HarlemSquirrel Feb 04 '20 at 22:11
3
git show --stat origin/branch_name

This will give you a list of the files that have been added or modified under this branch.

James Roper
  • 12,695
  • 46
  • 45
Badari
  • 87
  • 1
  • 1
3

Considering you're on a feature branch and you want to check which files have changed compared to master... just this:

git diff --name-only master
Leniel Maccaferri
  • 100,159
  • 46
  • 371
  • 480
2

The accepted answer - git diff --name-only <notMainDev> $(git merge-base <notMainDev> <mainDev>) - is very close, but I noticed that it got the status wrong for deletions. I added a file in a branch, and yet this command (using --name-status) gave the file I deleted "A" status and the file I added "D" status.

I had to use this command instead:

git diff --name-only $(git merge-base <notMainDev> <mainDev>)
James Skemp
  • 8,018
  • 9
  • 64
  • 107
Connor Clark
  • 671
  • 7
  • 15
2

What about

git diff --name-only HEAD~1
1

I use grep so I only get the lines with diff --git which are the files path:

git diff branchA branchB | grep 'diff --git'
// OUTPUTS ALL FILES WITH CHANGES, SIMPLE HA :)
diff --git a/package-lock.json b/package-lock.json
T04435
  • 12,507
  • 5
  • 54
  • 54
0

Expanding off of what @twalberg and @iconoclast had, if you're using cmd for whatever reason, you can use:

FOR /F "usebackq" %x IN (`"git branch | grep '*' | cut -f2 -d' '"`) DO FOR /F "usebackq" %y IN (`"git merge-base %x master"`) DO git diff --name-only %x %y
Lunyx
  • 3,164
  • 6
  • 30
  • 46
0

The following batch file is based on twalberg's answer but will work in Windows:

@ECHO OFF
C:                               :: <== OR USE A DIFFERENT DRIVE
CD \path\to\where\git\files\are  :: <== CHANGE TO THE ACTUAL PATH
SET /p b="Enter full path of an ALREADY MERGED branch to compare with origin/master: "
bash --login -i -c "git diff --name-only %b% $(git merge-base %b1% origin/drop2/master)"
PAUSE

The above assumes that the main branch is origin/master and that git bash was included when Git was installed (and its location is in the path environment). I actually needed to show the actual differences using a configured diff tool (kdiff3) so substituted the following bash command above:

bash --login -i -c "git difftool --dir-diff %b% $(git merge-base %b1% origin/drop2/master)"
Steve Chambers
  • 37,270
  • 24
  • 156
  • 208