Get all files that have been modified in git branch
Asked Answered
I

17

369

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

Improvisator answered 17/5, 2012 at 18:22 Comment(4)
possible duplicate of How can I find out which files have been modified in a branch?Aida
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. :)Improvisator
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.Jeep
Does this answer your question? How can I find out which files have been modified in a branch?Eclampsia
H
264

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.

Hanky answered 17/5, 2012 at 18:53 Comment(15)
ah! this is good fun, now how about if I want to have say <notMainDev> be the current branch I'm on. that is not have to specify it?Improvisator
git diff --name-only <some-other-branch> will show you what files are different between your current branch and <some-other-branch>. 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 <some-other-branch> really could be any commit at all, or anything that resolves to one (tags, etc.).Hanky
hmmm, well, I guess what I mean is that I would like to do git diff --name-only <notMainDev> $(git merge-base <notMainDev> <MY_CURRENT_CO_BRANCH>) where MY_CURRENT_CO_BRANCH would of course be my current checked out branchImprovisator
You can do that, as well. That will find the point where <notMainDev> and <MY_CURRENT_CO_BRANCH> most recently had a common ancestor, and compare <notMainDev> 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.Hanky
ok! I got it. Courtesy of my colleague what's his name. git merge-base <notMainDev> git branch | grep '\*' | awk '{print $2}' that will get the commit for the branch between <notMainDev> and my current branch. I can then do git diff --name-only <notMainDev> $(git merge-base <notMainDev> git branch | grep '\*' | awk '{print $2}')Improvisator
and for the coop-detat [alias] diffbranch = "!sh -c 'git diff --name-only $1 git merge-base $1 $(git name-rev HEAD 2> /dev/null | cut -f2)`' -" !!!Improvisator
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)?Armoured
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.Armoured
Slightly shorter syntax for the current branch: git diff --name-only $(git merge-base master HEAD)...Apterous
This gives the wrong status type for changes. See my answer for an alternative.Noaccount
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.Smash
for me this did not work. It showed way to many files.. Don't know what could be the problem.Spake
With Git 2.30 and newer, the above code can be replaced by git diff --merge-base <notMainDev> --name-only <mainDev>.Obstinate
How to do this on bitbucket?Salas
Beware git merge-base doesn't give the original forking point of the branch, but the closest common ancestor with the other (presumed main) branch. In many cases, both would be identical, but this solution won't work if the branch contains a commit merging main branch into it, in which case it will only list files that have been modified after the last merge, but any files modified in the branch before that merge commit (although not merged into main branch yet) won't be listed.Attribute
C
236

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.

Contagion answered 17/5, 2012 at 18:26 Comment(6)
wow quick and too the point. thank you. btw I love git. it's always quick and to the pointImprovisator
I believe that will also show stuff that has changed on <mainDev> since the branches diverged, though. You might want to use git diff --name-only <sha-of-branch-point> instead, or see the alternate answer I posted that avoids the checkout.Hanky
Yes, that is true @Hanky 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.Contagion
can't you just specify --right-only to only show the files that were changed on the right side?Hirohito
you get the <sha-of-branch-point> with git rev-parse <branch-name>Illuminative
I love this one. Thank you.Hieronymus
L
124

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

Lapierre answered 5/1, 2017 at 13:19 Comment(12)
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 :)Umber
then add the --name-only flag to this. or --short-statLapierre
git diff --name-only master.. if you just want the names of files that are different between the two branches.Goosander
This won't work properly if your master had commits after you created your side-branch.Whereto
@Whereto yes it does. thats exactly what this is solvingLapierre
@Lapierre oh, indeed. Confused three and two dots.Whereto
for me this did not work. It showed way to many files.. Don't know what could be the problem.Spake
if the repo is public I am happy to take a look, did you use 3 dots ?Lapierre
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.Fremantle
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.Grenade
This precise syntax actually dumps you into interactive mode, while the OP asked how to get the files.Imagination
I'm guessing what ever your pager is is doing that. This command will just spit out filesLapierre
K
80

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.

Kobe answered 1/12, 2016 at 10:26 Comment(8)
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!Kimble
Thanks, this is interesting, more wordy. It provides output fro each commit, in reverse order. git-whatchanged - Show logs with difference each commit introduces git-scm.com/docs/git-whatchangedRampant
From the git docs: 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.Biffin
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 -uSmash
Yeah, the problem with whatchanged is as @Smash 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).Noland
This should have been the accepted answerImpurity
This is the best answerHeterophyllous
I concur, best answer.Mccarthy
C
36

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/

Cybele answered 17/11, 2020 at 18:22 Comment(1)
diff has much more options and overall git-diff is super awesome ;)Cybele
O
33

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)
Occupier answered 4/1, 2017 at 6:29 Comment(3)
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?Karmenkarna
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 answerWaldrop
Awesome! Thanks for the quick reply and insight. Much appreciated.Karmenkarna
A
20
git diff --name-only master...branch-name

to which we want to compare.

Aegeus answered 18/5, 2018 at 11:7 Comment(2)
Seems like a partial of an existing answer, https://mcmap.net/q/92301/-get-all-files-that-have-been-modified-in-git-branchTelepathist
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.Loftis
D
15

git whatchanged seems to be a good alternative.

Doubt answered 15/9, 2016 at 9:7 Comment(2)
What was exactly that I was looking for.Matildamatilde
From the git docs: 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.Biffin
L
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.

Lingcod answered 18/4, 2016 at 22:32 Comment(0)
L
4

For some reason no one mentioned git-tree. See https://mcmap.net/q/14241/-how-do-i-list-all-the-files-in-a-commit

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)

Lowery answered 21/11, 2019 at 10:5 Comment(1)
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)Superficial
Z
4

What about

git diff --name-only HEAD~1
Zenithal answered 19/5, 2022 at 8:27 Comment(0)
R
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
Racer answered 15/10, 2020 at 20:38 Comment(0)
V
2
git show --stat origin/branch_name

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

Vidovic answered 7/1, 2016 at 9:26 Comment(1)
This is wrong, this only shows the files changed in the head commit of that branch, not the whole branch.Cecilycecity
N
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>)
Noaccount answered 10/7, 2018 at 6:33 Comment(0)
U
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
Unbated answered 10/11, 2017 at 5:9 Comment(0)
B
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
Brave answered 2/6, 2016 at 13:41 Comment(0)
A
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)"
Armoured answered 14/12, 2016 at 10:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.