Reputation: 5865
I've found information on showing all branches that contain a given commit. However, how do I find branches on my remote that are newly created that have no commits against them?
Upvotes: 2
Views: 989
Reputation: 488183
It's not really clear to me what the question means.
Here is a simple example. Suppose we draw this graph:
...--o--o--o--o <-- master
\
o--X <-- br1, br2
master
points to its tip commit. Branches br1
and br2
both point to their own tip commits, but both commits are commit X
. In that sense, at least one of these branch names is redundant.
Now, you said:
branches on my remote that are newly created
It's easy to find remote-tracking branch names: they're the ones in the refs/remotes/
namespace. The ones for the remote named origin
are in refs/remotes/origin/
.
"Newly created", however, is not meaningful in Git. Branch names can be created or destroyed at any time, pointing to any commit. Given the graph drawn so far, we can add a new br3
pointing to the commit before X
. If we do that on origin
and then run git fetch
, we get:
...--o--o--o--o <-- master
\
o <-- origin/br3
\
X <-- br1, br2
This really is the same commit graph; I just moved X
down to a new row so that I had space to fit in the name, origin/br3
.
That name—origin/br3
—is, in a sense, redundant with both of our own br1
and br2
names, as it does not serve to retain any commits we would not already retain. But it's different from any names we have.
The git branch
options --contains
, --merged
, and --no-merged
(now available in git for-each-ref
as well, since Git 2.7.0) are merely en-masse tests for "is or is not an ancestor", with some variation on precisely what is tested against what-else. Going back to this graph but adding more names:
...--U--V--Y--Z <-- master
\
W--X <-- br1, br2
the graph tells us that U
is an ancestor of every other labeled commit, Y
is an ancestor of Z
, W
is an ancestor of X
, and so on. W
is not an ancestor of Y
, however, as commit nodes only link "backwards"—leftwards, in these graph drawings—so W
goes back to V
, and Y
goes back to V
, but Y
does not connect to W
at all.
For these "is an ancestor" tests, a commit is always considered an ancestor of itself. (That is, these are less-than-or-equal-to, ≤, tests, rather than strictly-less-than.)
Running git branch --contains <id>
commit means: for each branch name, look up its tip commit. (That's Z
, X
, and then X
again.) Then, see if the named commit <id>
is an ancestor of the tip. If so, print the branch name. So if we name commit U
we get all the branch names, but if we name commit X
we get just br1
and br2
.
Running git branch --merged [<commit>]
means: for each branch name, look up its tip commit. (Z
, X
, and X
again.) Then, see if the tip commit is an ancestor of the commit we just named, or of HEAD
if we did not name one. If so, print that branch name. So if we are sitting on commit X
right now, we'll see br1
and br2
. However, if we name commit U
, we get no branch names, because Z
and X
are not ancestors of U
.
Running git branch --no-merged [<commit>]
means: for each branch name, look up its tip commit. Then, see if the tip commit is an ancestor of the commit we just named, or of HEAD
. If not, print the branch name.
Again, these are all just simple "is an ancestor" tests, and git branch
simply runs them for all branch names. The --contains
, --merged
, and --no-merged
control:
(There's no --does-not-contain
test to put the argument hash-ID on the left, but print only if the test says "no". For that, you have to spell out the loop manually.)
Upvotes: 0
Reputation: 2678
You can see all branches that have no commits not merged, by running git branch --merged
This should accomplish what you want. Newly created branches that have no commits are really no different than old branches that have been merged.
Upvotes: 2