Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to list all changed files in a particular branch?

Tags:

git

I have created one branch xyz from master. I have done approximately 1000 commits and probably modified 20 files in xyz branch. Now I want to list all the files which I have modified in xyz branch.

Following command lists files modified in both branches.

git diff --name-only master...xyz
like image 743
vivek nuna Avatar asked Sep 26 '16 07:09

vivek nuna


2 Answers

As pointed out by @torek, the git diff command ignores the dot notation completely.

Therefore, the following command should lead to the desired results:

git log --oneline --name-only develop..xyz | sort | uniq

Which prints out something like this, with the modified files at the end:

0871be6 commit 1
9caad09 commit 2
bb714f0 commit 3
...
path/to/file1
path/to/file2
path/to/file3
path/to/file4

Notice, there are only two dots. This means, take into consideration all revisions which are in xyz but not in develop.

Using three dots uses all revisions which are exclusively in one of the two branches, but not in both.

Reference: https://git-scm.com/book/tr/v2/Git-Tools-Revision-Selection#Commit-Ranges

like image 74
gucce Avatar answered Oct 10 '22 02:10

gucce


The fundamental problem here is that git diff compares two specific commits.1 No matter what arguments you give it, it's still going to choose two specific commits, and compare those two.2

What this means is that to get git diff to show you what you have done in some branch, you must pick two commits within that branch: one to call a "starting point" and one to call an "ending point". If you choose to do this, it usually helps to draw the commit graph. You can do this manually, or use git log --oneline --graph to help out. (A nice way to see this graph for your two branches in comparison with each other is git log --oneline --graph --decorate --boundary master...xyz.) Another way is to try drawing your graph yourself, which can let you represent it more compactly, or to use gitk or some other graphical viewer that will draw the graph.

If there is a single merge base commit between the tip commit on master and the tip commit on xyz, then:

git diff --name-only master...xyz

will compare (and list the names of files modified) that particular merge base, vs the tip-most commit of branch XYZ. That is, if the graph looks something like:

          o--o--o--o--...--o--Z   <-- master
         /
...--o--*
         \
          F--G-...--X             <-- xyz

then * is the merge base commit, Z is the tip commit on master,3X is the tip commit on xyz, and git diff master...xyz will compare commit * vs commit X. (By contrast, git diff master..xyz—note the two dots instead of three, here—will compare commit Z vs commit X.)

That said, given that git diff --name-only master...xyz is not showing you what you want, you might want git log --name-only master..xyz (probably also with --oneline; I see gucce added this as a comment as well), to show you what happens in each commit that is in xyz that is not also in master. That is, given the above graph, this will diff commit * against commit F, then F against G, and so on up to the comparison against X. Note that this is using git log's built-in ability to diff each commit against its parent.4


1It can also compare one commit to the index, or one commit to the work-tree, or the index to the work-tree. In another mode it can be used to compare two specific files, either or both of which need not be stored in the repository at all, but that's even more different from the way you want to use it.

2This, too, is a bit of an overstatement: by giving git diff more than one pair of commits, you can get it to produce what it calls a combined diff. This is normally used for merge commits, to show points where the merged contents differ from all parent commits, i.e., where a merge conflict was resolved by choosing something other than "what was in one branch". But this, too, goes quite a bit in the wrong direction, compared to what you want to achieve.

3I had this as T, for tip-of-master, for a moment, but then realized that T is alphabetically between F and X. X is for xyz, so I changed T to Z here so that it comes after X. The general idea is that we're not interested in most of the commits exclusively on master, except for the tip-most one that the name master selects.

4If any of the commits in the F-through-X chain is a merge commit, git log won't even bother to diff it at all unless you add some additional options. That is, git log skips over merges when it comes time to diff them, unless you either ask for combined diffs (-c or --cc) or to split merges (-m). All three of these options have drawbacks as well, so your best bet is to work with a no-merges situation in the first place.

like image 36
torek Avatar answered Oct 10 '22 02:10

torek