How to compare files from two different branches
Asked Answered
E

14

2195

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
Enplane answered 4/11, 2010 at 18:4 Comment(1)
might be helpful to read the git diff: #2529941Dendrology
M
2993

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 (mind the space between the separator and the filename). 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.

Maladjustment answered 4/11, 2010 at 18:13 Comment(25)
is it possible that if there's no changes it wont launch the difftool?Enplane
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.)Preconscious
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!?!?!Enplane
@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.)Preconscious
the file is in the root directory of my branch (and that's directory I'm running the command from) git diff alerts master -- bd.ps1 (just fails silently)Enplane
@Micah: Hm. Fails, or succeeds? Check the exit code. If it's reporting success, it means it thinks there's no difference; I'm guessing that's the case. Is one of those branches not where you think it is? This doesn't happen to be a public repository, does it - I'd be happy to just look, if it is.Preconscious
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).Commensal
This also did not work for me. I used $ git diff {branch} master --{filename copied from git status result} and it just said "usage: git diff [<options>] [<commit> [<commit>]] [--] [<path>...]"Wintertime
Did you have a space between -- and {filename}? If not, Git will think you were trying to specify a --long-switch.Maladjustment
dahlbyk solution works for me, however for curiosity sake I attempted @Jefromi version using -- but it only gave this error: fatal: ambiguous argument 'myflie.cs': unknown revision or path not in the working tree. Use '--' to separate paths from revisions, like this: 'git <command> [<revision>...] -- [<file>...]'Telecast
Can you be more specific about the command you used? If you provided two refs and a path, the only thing I can think of is an incorrect path.Maladjustment
doubledash -- is necessary for me, at least when using the glob "*/filename.txt"Karyn
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.Insolence
@Jefromi Correct me if I am wrong, so if you want to compare from your current work tree with a branch you would just do: git diff anotherBranch myfile.cs ?Wilk
Correct me if I'm wrong. This only fits the need of 'comparing two commits', it doesn't address the situation where you want to compare your uncommited work with a commited file from another branch? But the answer here does address it right?Wilk
Omitting a second <commit> value will "view the changes you have in your working tree relative to the named <commit>. You can use HEAD to compare it with the latest commit, or a branch name to compare with the tip of a different branch." So git diff mybranch -- myfile.cs will compare the working directory's myfile.cs with that file in mybranch.Maladjustment
When you do this which one shows up as adding and which one shows up subtracing?Peaceful
Can I compare the file between local branches, not from remote branches?@MaladjustmentAppointment
@Appointment Yes, in my example above both mybranch and master are local branches.Maladjustment
The key was "Are you correctly typing the path relative to the current directory?" Thanks to @Jefromi :) Now it works.Reflection
From Win cmd prompt - after checking out branch to diff with master branch: Had some issues but found to resolve easily as c:\>git diff c:\<FULL_PATH_TO_MY_BRANCH>..master /<relative_path of my file - as shown by git diff --name-status master>. This was more convenient as I had multiple files and i could just use up arrow key to bring back previous command and just paste the relative path of next file from the output of git diff --name-status. Its better than the other option providing full path of the file as it would be difficult to edit the file path each time from relative to full.Rutaceous
it should also be explained how to read the git diffDendrology
Neither of these work.Thousandfold
@Thousandfold this behavior hasn't changed in at least 12 years. Are you trying to diff a renamed file or something?Maladjustment
Is there a way to see changes made on my branch, but ignore those lines which are already on master? Please help me to achieve this result: https://mcmap.net/q/45658/-how-to-see-differences-in-a-file-between-two-branches-which-i-made-on-my-branch/4632019Crowded
M
604

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?

Moo answered 4/11, 2010 at 18:12 Comment(9)
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.Preconscious
@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).Historiography
@Historiography 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.Preconscious
@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 askingHistoriography
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!Flabby
On Windows still use / path separator else git diff silently does nothing.Munster
this answer is the best for the case that a file was renamed, especially if the old name is reused in the new branch. putting this here for people ctrl+fing for "renamed" or "different files" or "different file names"Kuntz
One of the ways file can change is surely a change of its name! That's why this is a better answer than the accepted one.Ophir
Instead of using 'mybranch', I found I could also do the commit id which is kind of helpful in my environment.Shanks
P
222

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.
President answered 25/6, 2015 at 0:41 Comment(0)
G
44

There are many ways to compare files from two different branches:

  • Option 1: If you want to compare the file from n specific branch to another specific branch:

    git diff branch1name branch2name path/to/file
    

    Example:

    git diff mybranch/myfile.cs mysecondbranch/myfile.cs
    

    In this example you are comparing the file in “mybranch” branch to the file in the “mysecondbranch” branch.

  • Option 2: Simple way:

     git diff branch1:file branch2:file
    

    Example:

     git diff mybranch:myfile.cs mysecondbranch:myfile.cs
    

    This example is similar to the option 1.

  • Option 3: If you want to compare your current working directory to some branch:

    git diff ..someBranch path/to/file
    

    Example:

    git diff ..master myfile.cs
    

    In this example you are comparing the file from your actual branch to the file in the master branch.

Guertin answered 4/4, 2018 at 13:34 Comment(0)
H
23

For Visual Studio Code I strongly suggest the extension:

Git History Diff docs

You can use it two compare between files or even branches!

From console, you can simply use this command :

git diff <Your_Branch> <Branch_To_Compare_With> -- myfile.cs
Haviland answered 20/12, 2021 at 13:40 Comment(0)
C
21

If you want to make a diff against the current branch you can commit it and use:

git diff $BRANCH -- path/to/file

This way it will diff from the current branch to the referenced branch ($BRANCH).

Covering answered 14/2, 2019 at 18:55 Comment(0)
F
18

I simply do git diff branch1 branch2 path/to/file

This checks for differences between the files. Changes in branch1 would be in red. Changes in branch2 would be in green.

It's assumed that branch1 is the past and branch2 is the future. You can reverse this by reversing the order of the branches in the diff: git diff branch2 branch1

Flaminius answered 22/5, 2017 at 14:14 Comment(1)
Which version of git diff can do this? It doesn't seem to be supported in the version I'm running (2..9.2.windows.1).Youngster
M
10

There are two scenarios to compare files:

Scenario 1: Compare files at remote branches (both branches should exists in the remote repository)

Scenario 2: Compare local files (at the local working area copy) to the files at the remote repository.

The logic is simple. If you provide two branch names to diff, it will always compare the remote branches, and if you provide only one branch name, it will always compare your local working copy with the remote repository (the one you provided). You can use range to provide remote repositories.

E.g., check out a branch:

git checkout branch1
git diff branch2 [filename]

In this case, if you provide filename, it will compare your local copy of filename with the remote branch named "branch2".

git diff branch1 branch2 [filename]

In this case, it will compare filename from remote branches named "branch1" vs "branch2"

git diff ..branch2 [filename]

In this case also, it will compare filename from remote branches named "branch1" vs "branch2". So, it's the same as above. However, if you have just created a branch from another branch, say "master" and your current branch doesn't exists on the remote repository, it will compare remote "master" vs. remote "branch2".

Multifid answered 29/9, 2019 at 14:14 Comment(1)
This worked well for me. Thanks Dharmender for your answer.Fred
H
5

I am agreeing with the answer by dahlbyk. If you want the diff to be written to a diff file for code reviews, use the following command.

git diff branch master -- filepath/filename.extension > filename.diff --cached
Hispanic answered 6/10, 2017 at 7:19 Comment(0)
I
5

In my case, I use the below command:

git diff <branch name> -- <file path + file name>

This command can help you compare the same file in two different branches.

Inconvertible answered 11/1, 2019 at 3:1 Comment(1)
Should explain path with example that applies to a file not in top directoryDoityourself
P
4

Use commit hashes as this:

git diff <hash1> <hash2> <filename>

where hash1 can be any commit from any branch, and the same for hash2.

Playlet answered 28/5, 2019 at 13:35 Comment(2)
How does that answer the question? Can you elaborate? For instance, what are some ways to find the two hash values?Urbana
Ask stackoverflowPlaylet
F
3

There is another interesting point about these various ways of doing the comparison: I want to compare a file in my current branch to the same file in another branch. If I use

git difftool otherbranch.. filespec

I end up comparing two files which are actually in my temporary folder. However, If I use

git difftool otherbranch filespec

I end up comparing a file in my temporary folder (the version on otherbranch) with the actual file in my Git folder, which a) makes it much easier to tell which is which, and b) means I can use the diff tool (Beyond Compare 4 in my case) to copy changes from my other branch into my current branch.

Foggia answered 24/5, 2021 at 11:13 Comment(0)
I
1

In order to compare two files in Git Bash you need to use the command:

git diff <Branch name>..master -- Filename.extension

This command will show the difference between the two files in Bash itself.

Ithunn answered 17/1, 2018 at 4:26 Comment(0)
R
1

The best way to do it is by using git diff in the following way:

git diff <source_branch> <target_branch> -- file_path

It will check the difference between files in those branches. Take a look at this article for more information about Git commands and how they work.

Remitter answered 7/5, 2018 at 12:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.