I am not sure if there really is a correct, or best way. All of the core devs I have interacted with have their own setup that works best for them.
My general setup is
- directory per remote branch: right now I have drupal-8.8.x, drupal 8.9.x, and drupal 9.0.x
- git branch for each patch that is in the issue-comment form: 3113284-02, 3113284-04)
I do this because I have a bunch of shell scripts for installing, cleaning, diffing, generating patches, running tests, etc. All of these scripts get ignored.
As far as drush goes, I keep a global install and checkout a tag periodically. I then have a .envrc in each branch directory to $PATH everything correctly. This prevents changes to composer.json.
However, there are some things you can try. A while ago, running tests locally with certain PHP versions meant updating phpunit via a post-composer script. You then had to restore composer.json and composer.lock before running a git diff ...
to generate a patch/interdiff. You can do the something similar with drush:
- git pull origin/8.8.x
- composer require drush/drush:^10
- git checkout composer.json composer.lock
The above approach is on my short-list for updates to my scripts.