The thing to understand here is that branches in Git are not things. They aren’t places, or collections of commits, or histories. They are just names. A branch is a name that is currently attached to some commit; and it is movable, so it can be attached to some other commit, as desired. To "make a branch" just creates a name and points it — by default to where we are right now.
And HEAD is an even simpler name; it just points (usually) at the branch name where you are working.
So, as already explained in a comment: you have
1 -- 2 -- 3 -- 4 -- 5 -- 6 -- 7 -- 8 <- main <- HEAD
So main is pointing at 8, and we are at 8. So now say git branch branchA. Now you have
1 -- 2 -- 3 -- 4 -- 5 -- 6 -- 7 -- 8 <- main <- HEAD, branchA
with both branch names pointing to 8. Note that you are still on main; you didn't checkout branchA so HEAD still points to main.
Since branchA now looks exactly the way you want it to, you can now just move main by saying git reset --hard HEAD~3. That simply lifts the main pointer and moves it, and so it gives:
                  main <- HEAD
                    |
                    v
1 -- 2 -- 3 -- 4 -- 5 -- 6 -- 7 -- 8 <- branchA
But that is topologically identical to what you want:
1 -- 2 -- 3 -- 4 -- 5 <- main <- HEAD
                     \
                      -- 6 -- 7 -- 8 <- branchA
You are still on main so just keep working: add-and-commit, add-and-commit.
1 -- 2 -- 3 -- 4 -- 5 -- 9 -- 10 <- main <- HEAD
                     \
                      -- 6 -- 7 -- 8 <- branchA
Meanwhile branchA is sitting there holding your old place at 8.