I am trying to do a git diff between two separate repositories. Using git diff ProjectA ProjectB
alone works, but I have to scroll through all the differences in the .git
directory.
I've tried git diff ProjectA ProjectB -- . ':!.git'
to exclude the .git
directory, but I get the following error.
Not a git repository
To compare two paths outside a working tree:
usage: git diff [--no-index] <path> <path>
I've also tried git diff --no-index ProjectA ProjectB -- . ':!.git'
but simply receive the message:
usage: git diff --no-index <path> <path>
What is the correct way to git diff two different repositories while excluding certain directories?
Much of what I have to say here is in other answers and their comments, but to fill in a few blanks, emphasize a few points, and generally provide what I hope is a single, organized, useful answer:
Most forms of git diff
expect to be run within a repository work tree, to compare two versions of a file (or of each of a set of files). For each file to be compared, maybe you're comparing the work tree version against the index version, or the version in commit A against the version in commit B.
In these cases, though, you can't compare against something outside your repository (e.g., a path outside the work tree). If you try to refer to something outside your current repository work tree, and Git thinks you're using one of these forms, then it will raise an error.
There is one specific form of git diff
that lifts this restriction:
git diff [--no-index] path1 path2
where either: (a) you include the --no-index
option, or (b) one of the paths is outside the current repository's work tree. In that case, Git will compare two arbitrary paths on your filesystem. But, various features of Git that are tied to a repository - like comparing with historical versions - aren't accessible when using this form.
So, when you say
git diff projectA projectB
since that paths you've given are not both in a single repository work tree, Git figures it has to switch to this one special form, and so it works.
But:
That one special form is pretty limited. You only get to list the two root paths - not an arbitrary number of path specs, like when you compare versions of a file within a repository. When you start trying to give more general git diff
syntax, then git says "well, this isn't the filesystem-to-filesystem comparison syntax, so I can't have this path outside the work tree"... and you get your error message.
So you have two choices.
You can use a tool other than Git to compare the directories. Such a tool might have functionality for path-based exclusions.
Or, you can use Git, but do the comparison within a single repository.
mkdir compare
cd compare
git init
git remote add ProjectA ../ProjectA
git remote add ProjectB ../ProjectB
git fetch ProjectA
git fetch ProjectB
git diff ProjectA/master ProjectB/master
Now Git understands that you're comparing two content versions.
You can also do this by just making ProjectB a remote of ProjectA (or vice versa) and fetching so that one of the two repositories has both sets of objects. The thing to watch for is, just deleting the remote doesn't necessarily remove all of the objects fetched from the other repository. (It definitely doesn't remove them right away.)