All my Ansible playbooks/roles are checked in to my git repo.
However, for Ansible Galaxy roles I always have to explicitly download them one by one on every machine
You could use an Ansible role to install the needed roles using the command module.
Here is a very basic example that runs ansible-galaxy install:
- name: Install roles from Ansible Galaxy
command: ansible-galaxy install {{ item.item }}
with_items:
- "{{ ansible_roles_list }}"
The ansible_roles_list may be supplied as a variable or as a role parameter.
If you do this in a role, it has to be applied before any other roles that you want to install using it, in a separate playbook. This is because Ansible checks the if all the roles are available before running the playbook where you reference them.