{"thread":{"id":"63619","subject":"Canonical way to filter list of commits to those pointed to by branches (preserving order)?","startedAt":"2025-06-10T21:29:57Z","lastAt":"2025-06-10T21:29:57Z","messageCount":1,"participants":["D. Ben Knoble"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"520058","messageId":"20250610212954.51868-1-ben.knoble+github@gmail.com","threadId":"63619","inReplyTo":null,"subject":"Canonical way to filter list of commits to those pointed to by branches (preserving order)?","fromName":"D. Ben Knoble","fromEmail":"ben.knoble+github@gmail.com","sentAt":"2025-06-10T21:29:48Z","receivedAt":"2025-06-10T21:29:57Z","isPatch":false,"sender":{"key":"ben.knoble@gmail.com","avatar":"https://avatars.githubusercontent.com/u/22802209?v=4"},"body":"Perusing a Git Rev News article [1], I thought there must be a better way to\nturn the commits between 2 revisions into a list of branch names—better, that\nis, than parsing git-log output.\n\nI wound up with 3 options, but I wonder if any are canonical or if I'm missing\nthe \"standard\" approach? My current best attempt leaves me concerned via the\ndocumentation.\n\n1. Use join:\n\n    join <(git rev-list \"$upstream..$base\" | sort) \\\n         <(git for-each-ref --format=\"%(objectname) %(refname:strip=2)\" refs/heads | sort)\n\n    Requires Bash or Zsh due to process substitution, and the |sort pipe loses\n    topological order. But elegant, from a certain point of view, perhaps.\n\n2. Use git-name-rev, but post-process output (because name-rev gives results\nthat aren't refs):\n\n    git rev-list \"$upstream..$base\" | xargs git name-rev --refs='refs/heads/*' |\n      while read -r sha ref; do\n        if git check-ref-format --branch \"$ref\" >/dev/null 2>&1; then\n          printf '%s %s\\n' \"$sha\" \"$ref\"\n        fi\n      done\n\n    Not my favorite, but seems to work\n\n3. Use git-name-rev after filtering with --simplify-by-decoration\n\n    git rev-list --simplify-by-decoration \"$upstream..$base\" | xargs git name-rev\n\n    Clearly the most elegant, but only if I can rely on --simplify-by-decoration\n    not outputting commits not pointed directly to by a branch. But the docs say\n    \"Note that extra commits can be shown to give a meaningful history.\" Hm. (Of\n    course, all the git-name-rev solutions are broken in the presence of tags,\n    too, though for my use case I will just ignore that for now…)\n\n[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/>\n\n--\nD. Ben Knoble\n"}]}