GitLab预接收钩子拒绝SSH推送,HTTPS推送正常求助
Alright, let's break down why your SSH push is failing even though cloning works, and how to fix it. The key clues here are the "project not found" error during the pre-receive hook execution, and your GitLab data directory being on a separate partition with symlinked hooks.
1. First: Fix the Hook Symlink (Most Likely Culprit)
Cloning works because SSH authentication passes and Git can locate the repo files, but pushes trigger the pre-receive hook—which relies on a symlink to GitLab's core hook script. If that symlink uses a relative path (instead of absolute), moving the repo directory to /drive2/repositories breaks the link.
Check the symlink:
ls -l /drive2/repositories/user/repo_name.git/hooks/pre-receive
A valid symlink should look like this (absolute path to GitLab's hook):
lrwxrwxrwx 1 git git 64 Aug 1 10:00 pre-receive -> /opt/gitlab/embedded/service/gitlab-shell/hooks/pre-receive
Fix it (for a single repo):
cd /drive2/repositories/user/repo_name.git/hooks rm pre-receive ln -s /opt/gitlab/embedded/service/gitlab-shell/hooks/pre-receive .
Fix all repos in bulk:
# Remove broken symlinks find /drive2/repositories -name "pre-receive" -type l -exec rm {} \; # Create new absolute symlinks for all hook directories find /drive2/repositories -type d -name "hooks" -exec ln -s /opt/gitlab/embedded/service/gitlab-shell/hooks/pre-receive {} \;
2. Verify GitLab's Data Directory Configuration
Make sure GitLab is aware of your new data directory path, so it generates correct symlinks for future repos:
- Edit
/etc/gitlab/gitlab.rb:git_data_dirs({ "default" => { "path" => "/drive2/repositories" } }) - Reconfigure and restart GitLab:
gitlab-ctl reconfigure gitlab-ctl restart
3. Debug Hook Environment Variables
If the symlink fix doesn't work, add temporary debug logging to the hook script to see what's going wrong. First, back up the original hook:
cp /opt/gitlab/embedded/service/gitlab-shell/hooks/pre-receive /opt/gitlab/embedded/service/gitlab-shell/hooks/pre-receive.bak
Then add these lines at the top of the hook script:
# Debug logging - remove after fixing File.open('/tmp/gitlab_pre_receive_debug.log', 'a') do |f| f.write("=== #{Time.now} ===\n") f.write("Current working directory: #{Dir.pwd}\n") f.write("GL_REPOSITORY variable: #{ENV['GL_REPOSITORY'] || 'NOT SET'}\n") f.write("Git user ID (GL_ID): #{ENV['GL_ID'] || 'NOT SET'}\n") end
Try pushing again, then check the log:
cat /tmp/gitlab_pre_receive_debug.log
- If
GL_REPOSITORYis missing or incorrect: GitLab Shell isn't passing the right project identifier. Check/opt/gitlab/embedded/service/gitlab-shell/config.ymlto ensuregitlab_urlpoints to your GitLab instance's internal API (e.g.,http://localhost:8080). - If
Dir.pwdshows the old repo path: GitLab's database might still have the original repo location stored. Back up your database first, then run:gitlab-rake gitlab:storage:migrate_to_new_layout
4. Confirm Git User Permissions
Ensure the git user has read access to GitLab's embedded libraries (required for the hook to run):
sudo -u git ls -l /opt/gitlab/embedded/service/gitlab-shell/lib/
If you get permission errors, fix them with:
sudo chmod -R o+r /opt/gitlab/embedded/service/gitlab-shell/
5. Match GitLab Shell Version to Your GitLab Instance
Your GitLab version (10.7.3) requires a specific GitLab Shell version (8.4.3). Reconfigure GitLab to ensure the correct version is installed:
gitlab-ctl reconfigure
内容的提问来源于stack exchange,提问作者CastleNtheSky

