I can't speak for the OP, but I've used a bare git repo for a number of years to manage my dotfiles, and in the few cases where I need to handle differences between machines, I've always been able to find a simple and straightforward, albeit ad-hoc, solution: for my shell, I `source local-config.${hostname}` when it exists; for my emacs config, I have a couple `cond` blocks in my config.el file; my preferred terminal emulator (kitty) can load multiple configuration files in sequence via passed arguments, so I can write a simple wrapper script and use a per-machine override .conf if necessary; etc etc. I don't currently put secrets in any text configuration files (nor can I envision myself doing so in the near future; I generally use a password manager, ssh/scp, or magic-wormhole to move secrets between workstations and servers where I have a user account), so I don't have a good answer for that one.
I imagine these solutions would scale poorly if I had a large number (dozens? hundreds?) of machines which all needed unique configurations, or if I used more tools which needed per-machine configuration, or if I needed to stick secrets in configuration files for some reason. Luckily for me, that's not the case, and my system has served me quite well as a result.