Атомарно. Часто. Любой целостный, завершенный и логический кусок или кусочек, независимо от размера. И не важно - сам пилю, или с командой. Это вопрос привычки - поначалу и лень, и смысла вроде не видишь. Со временем привыкаешь. И когда приходит время воспользоваться прелестями атомарных коммитов (а оно приходит) - откат фичи или возврат ранее откаченной (по требованию клиента), разрешение конфликтов и тд - радуешься и благодаришь себя прошлого за то, что не поленился.
И еще, очень важно писать адекватные commit message. Никаких "minor fix" и тому подобное. По месседжу должно быть четко понятно при листании истории что к чему и зачем, без необходимости смотреть diff. В идеале, еще и привязка к issues - но это актуально в командной работе, одному не надо.
Что касается бранчей - сильно зависит от проекта. В командной работе это либо feature branches (git flow или своя произвольная схема), либо у каждого своя ветка и там делай что хочешь. Тут смысл в первую очередь в пулл-реквестах, code review, CI и стабильном мастере, в котором всегда находится рабочий код. Если работать одному - лично я привык бранчевать каждую отдельную фичу (не фрагмент, а именно модуль, автономный кусок функциональности). Удобно на серверах чекаутить конкретный бранч, тестить, возвращаться на мастер. И это позволяет одновременно работать над несколькими фичами. Например, одну допилил, отдал на утверждение клиенту, а там есть комменты/фиксы, но ждешь какие-то материалы. Переключился на другую фичу и безопасно работаешь в другом бранче. В общем, удобно и надежно.