Take for example:
> Developers work in total isolation for weeks or months at a time on feature branches and then try to merge all their work together into a release branch at the very last minute.
You have also option 3: Come up with a specification (not design) for all the components up front in such a way that it minimizes integration risks. Split tasks and define interfaces and/or protocols so that the work can be developed in parallel. Still, try to follow up with the changes in other branches and keep your work up-to-date with major changes that may happen in the main branch. Try to merge to see if there is any conflict, but don't push half-work. However, if you have to modify a main component that is used by other in order to implement your thing, and that change can be merged back safely, do it as soon as possible.