Is using Git for deploying a bad practice?
I would go as far as considering using git for deployment very good practice.
The two problems you listed has very little to do with using git for deployment itself. Substitute .git/
for the config file containing database passwords and you have the same problem. If I have read access to your web root, I have read access to whatever is contained in it. This is a server hardening issue that you have to discuss with your system administration.
git offers some very attractive advantages when it comes to security.
You can enforce a system for deploying to production. I would even configure a
post-receive
hook to automatically deploy to production whenever a commit tomaster
is made. I am assuming of course, a workflow similar to git flow.git makes it extremely easy to rollback the code deployed on production to a previous version if a security issue is raised. This can be helpful in blocking access to mission-critical security flaws that you need time to fix properly.
You can enforce a system where your developers have to sign the commits they make. This can help in tracing who deployed what to production if a deliberate security flaw is found.
There's nothing wrong with deploying from a git repo, in fact it's a pretty common practice and as you say a lot less prone to errors than copying files over ftp or rsync.
Given the information you've provided I'd note the following points:
Don't just pull in the latest master. Production should be deployed from a release tag. Use git flow or similar to get a little more process around the deployment of the code and creation of the tags. Because tags are an immutable reference to your code at a given time it's more stable than pointing to a master branch that could be updated by an errant commit.
As for serving the .git directory this shouldn't be a big issue. Just redirect anything prefixed with .git to a 404 in .htaccess.
Your git authentication should be ssh key based so no repo passwords need to be stored on the server.
Hurray for git deployment workflows!
I'm going to disagree with popular opinion here. Git is for version control, it is not for deployment/CI.
The methods people are advocating here are fine for small projects, but generally speaking, do not scale very well.
...which is not to say that you should not continue to do what you're doing. Just keep in mind, as your career progresses, that the projects you're working on will likely outgrow a purely git-based deployment workflow.
The main shift in paradigm is to stop thinking about deploying branches, and start thinking about deploying build results, and injecting environment dependencies to decouple your infrastructure from your branching strategy.
For example, to use the paradigm above about 'deploying files' and rollback. If you were deploying files, you could keep multiple versions of the application on the production server, and if you need to rollback, you can point your webserver to an older version by re-symlinking the web root. Two shell commands, microseconds of downtime, less room for error than using git.
Another example - you have the standard dev branch > staging branch > master workflow, with a server for each. You have stuff ready to go in dev, but some other stuff on staging failed QA. So you need to do some ugly operations - strip the bad commits from stage, redeploy stage, and also strip or fix the bad commits in development, and hope that development and staging don't end up out of sync.
Instead, what if you cut a release branch off master, merged the stuff that is ready to go into that release branch and built the result, spun up a testing server on AWS and deployed the result to it, ran your QA and functional tests against that temporary staging server, and then pushed that same result to the production cluster and deployed it? Then decommission the temporary staging box you spun up, merge the release into master, and tag master with a release number.
Obviously those are extreme examples. Usually, it's not that clean, even if we want it to be - you probably need to run some build processes at the target environment because you have database changes that need to happen. And if you've got non-idempotent database mods between versions, well, rollback isn't going to be that easy not matter what method you use, because you'll need to rollback the db (generally speaking, try to deploy idempotent database changes, then remove the obsolesced database bits in a later release, after you're sure they're out of application flow).
Anyway, I guess what I'm getting at, is that my answer to 'Is using git for deployment bad practice?' is, generally speaking, 'Yes', in the same way that using training wheels is bad for bike riding. It's an improvement over busting your ass on the concrete repeatedly, but you hopefully outgrow it eventually.