In composer.json you tell Composer in which directories it should put certain types of dependencies.
"installer-paths": {
"web/core": ["type:drupal-core"],
"web/libraries/{$name}": ["type:drupal-library"],
"web/modules/contrib/{$name}": ["type:drupal-module"],
"web/profiles/contrib/{$name}": ["type:drupal-profile"],
"web/themes/contrib/{$name}": ["type:drupal-theme"],
"drush/Commands/contrib/{$name}": ["type:drupal-drush"]
},
These directories are now managed by Composer. For example web/modules/contrib for type drupal-module dependencies. While at the same time everything put in web/modules/custom or any other custom location will be preserved.
Your repo in the end basically only contains the composer.json/lock files at the repo root and all custom code (custom themes, custom modules, custom scripts, custom patches etc.) and config YAML files in their desired directories.
You should gamble around a bit with the official recommended-project template or the community drupal-project template. Learn to read the composer.json file. Run composer install, manually delete certain directories, composer install again and observe what happens.