Try the following:
git rev-list --all --not $(git rev-list --all ^branch)
Basically git rev-list --all ^branch gets all revisions not in the branch, and then you all revisions in the repo and subtract the previous list, which is revisions only in the branch.
After @Brian comments:
From the git rev-list documentation:
List commits that are reachable by following the parent links from the given commit(s)
So a command like git rev-list A , where A is a commit, displays the commits available from A, including A.
With that in mind, something like
git rev-list --all ^A
will list commits not available from A
So git rev-list --all ^branch list all the commits that are inaccessible from the tip of the branch. Which will delete all commits in the branch, or, in other words, commits that are only in other branches.
Now let's move on to git rev-list --all --not $(git rev-list --all ^branch)
It will be like git rev-list --all --not {commits only in other branches}
So, we want to list all that are not available from all commits only in other branches
This is a set of commits that are only in a branch . Take a simple example:
master | A------------B \ \ C--------D--------E | branch
Here the goal is to get D and E, commit is not in any other branch.
git rev-list --all ^branch give only B
Now git rev-list --all --not B is what we are reducing to. Which is also git rev-list -all ^B - we want all commits not to be reached from B. In our case, these are D and E. This is what we want.
Hope this explains how the team works correctly.
Edit after comment:
git init echo foo1 >> foo.txt git add foo.txt git commit -am "initial valid commit" git checkout -b merge-only echo bar >> bar.txt git add bar.txt git commit -am "bad commit directly on merge-only" git checkout master echo foo2 >> foo.txt git commit -am "2nd valid commit on master"
After the above steps, if you do git rev-list --all --not $(git rev-list --all ^merge-only) , you will get the command you were looking for - "bad commit directly on merge-only" .
But as soon as you take the last step in the steps of git merge master , the command will not give the expected result. Since there is currently no commit that is not in the merge, only after one additional commit in master has also been merged with the merge. So git rev-list --all ^branch gives an empty result and therefore git rev-list -all --not $(git rev-list --all ^branch) will give everything commits only for merging.