Perusing a Git Rev News article [1], I thought there must be a better way to turn the commits between 2 revisions into a list of branch names—better, that is, than parsing git-log output. I wound up with 3 options, but I wonder if any are canonical or if I'm missing the "standard" approach? My current best attempt leaves me concerned via the documentation. 1. Use join: join <(git rev-list "$upstream..$base" | sort) \ <(git for-each-ref --format="%(objectname) %(refname:strip=2)" refs/heads | sort) Requires Bash or Zsh due to process substitution, and the |sort pipe loses topological order. But elegant, from a certain point of view, perhaps. 2. Use git-name-rev, but post-process output (because name-rev gives results that aren't refs): git rev-list "$upstream..$base" | xargs git name-rev --refs='refs/heads/*' | while read -r sha ref; do if git check-ref-format --branch "$ref" >/dev/null 2>&1; then printf '%s %s\n' "$sha" "$ref" fi done Not my favorite, but seems to work 3. Use git-name-rev after filtering with --simplify-by-decoration git rev-list --simplify-by-decoration "$upstream..$base" | xargs git name-rev Clearly the most elegant, but only if I can rely on --simplify-by-decoration not outputting commits not pointed directly to by a branch. But the docs say "Note that extra commits can be shown to give a meaningful history." Hm. (Of course, all the git-name-rev solutions are broken in the presence of tags, too, though for my use case I will just ignore that for now…) [1]: Pushing a whole stack of branches with a single Git command <https://andrewlock.net/pushing-a-whole-stack-of-branches-with-a-single-git-command/> -- D. Ben Knoble