The approach you described is actually one I used to use. It’s nice having a separate branches for each part of the feature. The problem though, as you described, is rebaseing (in your case, specifically squashing). If you make any changes to a branch that another branch depends on, you have to rebase onto that new version of the branch. Or worse, say I have branches for part1, part2, and part3. If I rebase part1 onto a new version of master (say someone else landed new code I’d like to use), I now have to rebase part2 on to the rebased part1, and then rebase part3 onto the rebased part2. This can become very very tedious.
The approach described in this article get’s around this problem by only having a single branch. It’s a little more risky (there’s more chance to screw something up in the interactive rebase), but it’s a lot less tedious.