4

git branch --contains master returns the names of branches from whose tips master is reachable.

git branch --merged master returns the names of branches whose tips are reachable from master.

git branch --no-merged master returns the names of branches whose tips aren't reachable from master.

What is the flag (perhaps in a newer version of git?) to show the names of branches whose tips are neither reachable from master, nor can reach master in their own ancestry? In other words, what flag gives the effect of --no-merged --no-contains?

To put it another way, how to show branches which could not have a fast forward merge into master nor have a fast forward merge from master into them?

Wildcard
  • 1,302
  • 2
  • 20
  • 42
  • @TimBiegeleisen, not necessarily at all. Try `git checkout -b divergent_branch master~3`, then make a commit, then `git log --online --graph master divergent_branch`. `master` itself is just a movable pointer to a commit; just because a branch shares history in common with master doesn't mean that branch fully includes *or* is included in `master`'s history. – Wildcard Mar 16 '16 at 11:07
  • @TimBiegeleisen also see [What exactly do we mean by "branch"?](http://stackoverflow.com/q/25068543/5419599) When I say one branch "includes another" I mean the DAG of history reachable from the branch pointer includes the full DAG of history reachable from the other branch pointer. – Wildcard Mar 16 '16 at 11:09

1 Answers1

5

Update April 2017, as I mentioned in "How to list all git branches containing a commit", the option --no-contains is now supported with Git 2.13.

Original Answer

What is the flag (perhaps in a newer version of git?)

First, the --(no-)merged flags you mention have been generalized as ref-filter fairly recently (git 2.7, Sept. 2015).

--no-contains

A quick search reveals this option does not exist (in any of the branches of the git repo:

MINGW64 ~/git/git (master)
$ git branch -a | tr -d \*|grep -v origin|xargs git grep --break --heading --line-number 'no\-contain'

So you would need to script that, listing all branches which are not selected by --contains (but are listed in --no-merged).

"git tag/branch/for-each-ref" family of commands long allowed to filter the refs by:

  • "--contains X" (show only the refs that are descendants of X),
  • "--merged X" (show only the refs that are ancestors of X),
  • "--no-merged X" (show only the refs that are not ancestors of X).

One curious omission, "--no-contains X" (show only the refs that are not descendants of X) has been added to them.

Beni Cherniavsky-Paskin
  • 9,483
  • 2
  • 50
  • 58
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • Thanks, I didn't think `--no-contains` was a real option; I thought it would convey in simple fashion what I meant. I'm not sure I quite get the significance of `ref-filter`. Is that a new `git` command in 2.7? E.g. `git ref-filter (something)`? – Wildcard Mar 16 '16 at 11:57
  • @Wildcard no, ref-filter refers to https://github.com/git/git/blob/8a54523f0f70134327e7b2a625b1777c796b07d5/ref-filter.h#L82-L87: "API for filtering a set of refs. Based on the type of refs the user has requested, we iterate through those refs and apply filters as per the given ref_filter structure and finally store the filtered refs in the ref_array structure". – VonC Mar 16 '16 at 11:59
  • Ah, okay. I'm not up on C code yet (hasn't been in my line of territory) so I only get the general idea. If I'm understanding you correctly it seems like this is just an implementation detail that has changed, and `git branch (--merged | --no-merged | --contains)` will still work just the same in 2.7? – Wildcard Mar 16 '16 at 12:05
  • @Wildcard yes, that set of options if available to git branch only for git 2.7+ – VonC Mar 16 '16 at 12:05
  • Now I'm confused. Git 1.7.12.4 works correctly with all three options specified in my last comment. What options are you referring to that are only available in 2.7+? – Wildcard Mar 16 '16 at 12:08
  • @Wildcard you are right. I mixed it up with `git tag`. The ref-filter was more an internal refactoring which allowed to propose those same options (initially avaible in git branch) to other commands like `git-tag` and `git for-each-ref` (hence the importance of using the ref-filter API). But the answer stands: no '`--no-merged`', and a need for a script. – VonC Mar 16 '16 at 12:11