title: Run git post-receive hook as user1, and checkout as user2
body: <p>I'm setting up a deploy-on-git-push process on a remote Debian server.  It is basically the common approach of having a bare repository with a post-receive hook which does a checkout to the web server's docroot, more or less.</p>
  <p>I've used slightly simpler variations of this set up successfully for years, but this time around I'm complicating it by trying to separate ownership of the git repo and the site files between 2 different users.  I don't want the user who can SSH in (the git push happens over SSH) to have write perms to the site, and vice-versa (the site user shouldn't have write perms to the git repository).</p>
  <ul>
  <li><p>I have 1 user, let's call her <code>git-user</code>, who owns a bare git repository at <code>/var/gitrepos/my_site.git</code>, and this user is the only user allowed to connect over SSH;</p>
  </li>
  <li><p>I have a 2nd user, say <code>site-user</code>, who should own the checked-out files at <code>/var/www/site</code>;</p>
  </li>
  </ul>
  <p>I push over SSH to the repo, and this means any post-receive hook runs as the user I SSH in as - <code>git-user</code> in this case.  So the post-receive hook can't do the checkout itself, as the site files would end up being owned by <code>git-user</code>, not <code>site-user</code>.</p>
  <p>So my post-receive simply touches a trigger file, <code>/var/run/deploy</code>.  A separate script is run from <code>site-user</code>'s cron frequently, eg every minute, looking for that file.  If it sees it, it does a checkout to <code>/var/www/site</code>.  The relevant part of that script looks something like:</p>
  <pre><code># Running as site-user
  mkdir $NEW \
    &amp;&amp; cd $NEW \
    &amp;&amp; git --work-tree=. --git-dir=/var/gitrepos/my_site.git checkout -f www
  </code></pre>
  <p>However this fails with:</p>
  <blockquote>
  <p>fatal: Unable to create '/var/gitrepos/my_site.git/index.lock': Permission denied</p>
  </blockquote>
  <p>This is true, <code>site-user</code> - intentionally - does not have write permission to <code>/var/gitrepos/my_site.git</code>.  I am not sure why doing a checkout to a different directory <em>needs</em> to create a lockfile in the repo, but apparently it does, and I guess I shouldn't fight that.</p>
  <p>So what are the options?</p>
  <ul>
  <li><p><code>git clone</code> doesn't need write perms to the repo, so this works, but it means I get the whole <code>.git/</code> directory.  I have to remove that, or configure the web server to disallow access, both extra steps I'd rather avoid.  Not a big deal obviously but this still feels wrong;</p>
  </li>
  <li><p>I could add both users to a group and set up <code>g+w</code> etc, but this voids the whole point of this approach (to deny each user write perms to the other's files);</p>
  </li>
  <li><p>I guess I could mess with <code>sudoers</code>, and allow one user to run a command as the other user, but again this feels like I am just chipping away at the separation I'm trying to enforce?</p>
  </li>
  <li><p>I can do a <code>git clone</code> to <code>$TMP_DIR</code>, followed by a <code>git checkout --git-dir=$TMP_DIR/.git/</code>, but this seems super clunky, as well as taking 2x as long;</p>
  </li>
  </ul>
  <p>Any other neat options I am missing?</p>
  <h3>UPDATE</h3>
  <p>As suggested by @Matt below I tried setting <code>GIT_INDEX_FILE</code> to a writeable (by <code>site-user</code>) file outside the repository.  This does seem to get past the first problem, but still fails with:</p>
  <blockquote>
  <p>error: Unable to create '/var/gitrepos/my_site.git/HEAD.lock': Permission denied</p>
  </blockquote>
  <p>I don't understand why a checkout to a new location needs to modify anything in the repository?</p>