Categories
git git-diff

How to compare files from two different branches

1979

I have a script that works fine in one branch and is broken in another. I want to look at the two versions side-by-side and see what’s different. Is there a way to do this?

To be clear I’m not looking for a compare tool (I use Beyond Compare). I’m looking for a Git diff command that will allow me to compare the master version to my current branch version to see what has changed. I’m not in the middle of a merge or anything. I just want to say something like

git diff mybranch/myfile.cs master/myfile.cs

    2724

    git diff can show you the difference between two commits:

    git diff mybranch master -- myfile.cs
    

    Or, equivalently:

    git diff mybranch..master -- myfile.cs
    

    Note you must specify the relative path to the file. So if the file were in the src directory, you’d say src/myfile.cs instead of myfile.cs.

    Using the latter syntax, if either side is HEAD it may be omitted (e.g., master.. compares master to HEAD).

    You may also be interested in mybranch...master (from git diff documentation):

    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.

    In other words, this will give a diff of changes in master since it diverged from mybranch (but without new changes since then in mybranch).


    In all cases, the -- separator before the file name indicates the end of command line flags. This is optional unless Git will get confused if the argument refers to a commit or a file, but including it is not a bad habit to get into. See Dietrich Epp’s answer to Meaning of Git checkout double dashes for a few examples.


    The same arguments can be passed to git difftool if you have one configured.

    22

    • 62

      And if neither of the two versions you want to compare is the work tree, you can use git diff branch1 branch2 myfile.cs. (The -- shouldn’t be necessary anymore, as it can only take up to two revision arguments.)

      – Cascabel

      Nov 4, 2010 at 18:43

    • 10

      I’ve tried every version of this and nothing happens. I have my difftool configured (it works for merging). I have a file called bd.ps1. Every version of the command I type does nothing. Doesn’t even give an errer. WTH!?!?!

      – Micah

      Nov 4, 2010 at 18:46

    • 3

      @Micah: Are you trying it with plain diff too? Are you correctly typing the path relative to the current directory? (It will silently show no diff if the file doesn’t exist, and you use the --. Common and easy mistake to make.)

      – Cascabel

      Nov 4, 2010 at 18:58


    • 7

      This didn’t work for me unless I included the full path to the file, as shown by git diff --name-status branch1..branch2 (probably obvious, but thought I’d mention it in case someone else has the same trouble I did).

      – hBrent

      Aug 19, 2013 at 21:42

    • 4

      The order of mybranch and master is also important. The file in the first branch will be shown with ‘-‘ prefixes, the file in the second branch will be shown with ‘+’ prefixes.

      – timbo

      Sep 14, 2015 at 23:48

    526

    You can do this:
    git diff branch1:path/to/file branch2:path/to/file

    If you have difftool configured, then you can also:
    git difftool branch1:path/to/file branch2:path/to/file

    Related question:
    How do I view ‘git diff’ output with my preferred diff tool/ viewer?

    8

    • 4

      Using the colons is not really a great way – it means you’re referencing the files through the tree objects, so you have to type out the full path, instead of relative to your current directory.

      – Cascabel

      Nov 4, 2010 at 18:42

    • 19

      @Jefromi, this may have changed in a more recent version, but at least now you can use relative paths (e.g. branch1:./file). This is also useful if the file is in a separate location between branches (e.g. git diff branch1:old/path/to/file branch2:new/path/to/file).

      – redbmk

      Mar 15, 2014 at 0:36

    • 7

      @redbmk Yeah, that was sometime between 2010 and now! Still, if it’s the same file on both branches, no need to do it like this, just git diff branch1 branch2 path/to/file.

      – Cascabel

      Mar 15, 2014 at 0:47

    • 3

      @jefromi cool, I wasn’t sure the timeline on when that was added. Yeah I would normally use the syntax you mentioned, but Tim’s answer helped me figure out how to compare files with different paths, even though it’s not really what the question was asking

      – redbmk

      Mar 17, 2014 at 15:47

    • 2

      While I love this idea, I can’t get this syntax to work or find any mention of it in the git diff docs. What am I missing? Thanks!

      – yoyo

      Dec 17, 2014 at 23:22

    203

    More modern syntax:

    git diff ..master path/to/file
    

    The double-dot prefix means “from the current working directory to”. You can also say:

    • master.., i.e. the reverse of above. This is the same as master.
    • mybranch..master, explicitly referencing a state other than the current working tree.
    • v2.0.1..master, i.e., referencing a tag.
    • [refspec]..[refspec], basically anything identifiable as a code state to Git.

    0