gitbranchalias

git: don't sort 'for-each-ref' output


Is there a way to not sort the action of git for-each-ref, i.e., leave it in the same order as specified on the command line?

My use case: I want to find the first (or last) branch name from the following set of patterns:

% git for-each-ref --format '%(refname:short)' 'refs/heads/dev/v*' 'refs/heads/develop' 'refs/heads/master' 'refs/heads/main' 
develop
main
master

However, as you can see, main is appearing before master, because according to the docs for --sort, "when unspecified, refname is used."

In case this is an x-y problem - this is part of a heuristic alias to find the dev head (using whatever precedence is handy for our team), so if anyone has a better technique for that, I'd be interested too.

# Determine the development head of this repository.  If there's not one, assume we're using mainline development.
# Handy for rebasing feature branches.
dev-branch = "!f() { \n\
    git for-each-ref --format '%(refname:short)' 'refs/heads/dev/v*' 'refs/heads/develop' 'refs/heads/main' 'refs/heads/master' | \n\
    head -n 1; \n\
}; f"

Solution

  • Most probably no. 'refs/heads/dev/v*' must be sorted anyway; and BTW are you sure you want to get the first of v* if there're many, not the last? Well, I don't see any other way but to check them one by one:

    for branch in 'refs/heads/dev/v*' 'refs/heads/develop' 'refs/heads/main' 'refs/heads/master'; do
        git for-each-ref --format '%(refname:short)' "$branch"
    done | head -1
    

    To get the last one use tail and of course the loop must be reversed:

    for branch in 'refs/heads/master' 'refs/heads/main' 'refs/heads/develop' 'refs/heads/dev/v*'; do
        git for-each-ref --format '%(refname:short)' "$branch"
    done | tail -1