Search code examples
gitawksedsh

Find all branches that follow mine lexicographically


I want to write a POSIX shell (/bin/sh) which will take as input a branch name. These branches are release branches, and they have the format release/yymmDD-HHMMSS, e.g release/240321-170138, /release/240405-095914. A git branch -A | grep release finds them all for me:

origin/release/230823-184353
origin/release/230825-154255
origin/release/230829-112434
origin/release/230905-101013
origin/release/230913-114212
origin/release/230915-105323
origin/release/230920-115230
origin/release/230927-115028
origin/release/230927-125843
origin/release/231016-145729
origin/release/231019-110314
origin/release/231030-150735
origin/release/231102-125814
origin/release/231109-114532
origin/release/231122-120112
origin/release/231123-140553
origin/release/231204-143206
origin/release/231213-153646
origin/release/231229-123237
origin/release/240112-160116
origin/release/240123-093125
origin/release/240201-171058
origin/release/240209-140214
origin/release/240216-121012
origin/release/240222-134817
origin/release/240307-115055
origin/release/240320-111003
origin/release/240321-170138
origin/release/240405-095914

Now suppose my script has been given the branch name release/240216-121012. I would like to receive, in a list or array (not sure what the proper terminology is in POSIX shell), all the branches that follow this branch name chronologically, which in this case also means lexicographically, at least until 2099:

origin/release/240222-134817
origin/release/240307-115055
origin/release/240320-111003
origin/release/240321-170138
origin/release/240405-095914

What would be a quick and elegant way to do this? I am currently envisioning putting all those results in an array, then looping to it from the end backward until I encounter my desired branch. Perhaps something with awk or sed and xargs could do the trick here?


Solution

  • An approach using sort to assure the right order, sed to mark the entry point and awk to print the lines after the mark (here PP<=).

    % mark="release/240216-121012"
    
    % sort -t / -Vk 3 files | 
        sed "s|${mark}|PP<=|" | 
        awk 'set==1{print} /PP<=/{set=1}'
    origin/release/240222-134817
    origin/release/240307-115055
    origin/release/240320-111003
    origin/release/240321-170138
    origin/release/240405-095914
    

    Data

    order changed to make sure sort works as intended

    % cat files
    origin/release/231204-143206
    origin/release/231213-153646
    origin/release/231229-123237
    origin/release/240112-160116
    origin/release/240123-093125
    origin/release/240201-171058
    origin/release/240209-140214
    origin/release/240216-121012
    origin/release/240222-134817
    origin/release/240307-115055
    origin/release/240320-111003
    origin/release/240321-170138
    origin/release/240405-095914
    origin/release/230823-184353
    origin/release/230825-154255
    origin/release/230829-112434
    origin/release/230905-101013
    origin/release/230913-114212
    origin/release/230915-105323
    origin/release/230920-115230
    origin/release/230927-115028
    origin/release/230927-125843
    origin/release/231016-145729
    origin/release/231019-110314
    origin/release/231030-150735
    origin/release/231102-125814
    origin/release/231109-114532
    origin/release/231122-120112
    origin/release/231123-140553