This is one workflow that might work for sfdx and git, main priority is to allow for development in scratch org, to deply for testing into a UAT sandbox and then deploy into production.
Starting point: master branch with source code and linked to scratch org.
Task: New feature to be developed
- Master has the main details of the package
- Create new branch called develop (pull requests/commits into develop will deply package to UAT)
- Create new branch from develop called feature (commits to feature will deploy a scratch org)
- After successful coding
- Pull request feature into develop (so package installed in UAT)
- Test in UAT
- Pull request develop into master (so package deployed in production)