From 9156bb2ebdf1def072313d1f1cee634a9dde914c Mon Sep 17 00:00:00 2001 From: DevSoftTech Server Date: Tue, 4 Aug 2026 03:04:53 +0530 Subject: [PATCH] improve: comprehensive git diagnostics and automated setup script Enhanced error reporting: - Show detailed diagnostic information: git version, user config, email, remote, branch - Check .git directory and config file existence - Detect if repository has uncommitted changes - Error categorization: PERMISSION, CONFIG, REPO, NETWORK, SSL, GIT errors - Actionable error messages with command suggestions - Report raw error output to log file for debugging Added setup_git_config.sh script: - Automated configuration for www-data user - Creates .ssh directory with proper permissions - Sets git user.name and user.email globally - Disables SSL verification (for HTTPS repos) - Configures git to use HTTPS remote URL - Fixes directory ownership and permissions - Tests git status to verify configuration Usage on live server: sudo bash setup_git_config.sh This script handles the common git configuration issues that prevent 'Update HMS' button from working. --- app/Libraries/SystemOperations.php | 86 +++++++++++++++++++++------- setup_git_config.sh | 90 ++++++++++++++++++++++++++++++ 2 files changed, 155 insertions(+), 21 deletions(-) create mode 100644 setup_git_config.sh diff --git a/app/Libraries/SystemOperations.php b/app/Libraries/SystemOperations.php index e345640..675cd1d 100644 --- a/app/Libraries/SystemOperations.php +++ b/app/Libraries/SystemOperations.php @@ -91,34 +91,47 @@ class SystemOperations $statusError = trim($statusResult['output']); $errorMsg = ''; + // Get diagnostics first + $diagnostics = $this->getGitDiagnostics($gitPath, $repoPath); + + // Build detailed diagnostic summary + $diagSummary = 'DIAGNOSTICS: ' . + 'Version=' . $diagnostics['git_version'] . '; ' . + 'User=' . $diagnostics['git_config_user_name'] . '; ' . + 'Email=' . $diagnostics['git_config_user_email'] . '; ' . + 'Remote=' . $diagnostics['remote_url'] . '; ' . + 'Branch=' . $diagnostics['current_branch'] . '; ' . + '.git=' . $diagnostics['git_dir_exists'] . '; ' . + 'Config=' . $diagnostics['git_config_exists']; + // Parse error message if (strpos($statusError, 'Permission denied') !== false) { - $errorMsg = 'Permission denied. Git directory may not be writable by current user.'; + $errorMsg = 'PERMISSION ERROR: Git directory may not be writable by www-data user. Check directory ownership.'; } elseif (strpos($statusError, 'fatal: Not a git repository') !== false) { - $errorMsg = 'Not a git repository. Repository initialization may be corrupted.'; + $errorMsg = 'REPO ERROR: Not a valid git repository. .git directory corrupted.'; } elseif (strpos($statusError, 'user.email') !== false || strpos($statusError, 'user.name') !== false) { - $errorMsg = 'Git user configuration missing. Run: git config user.name "name" && git config user.email "email@example.com"'; + $errorMsg = 'CONFIG ERROR: Git user not configured. RUN: git config user.name "www-data" && git config user.email "deploy@example.com"'; } elseif (strpos($statusError, 'SSL certificate problem') !== false) { - $errorMsg = 'SSL certificate verification failed. Run: git config --global http.sslVerify false (if using HTTPS)'; - } elseif (strpos($statusError, 'fatal') !== false) { - $errorMsg = 'Git error: ' . $statusError; + $errorMsg = 'SSL ERROR: Certificate verification failed. RUN: git config http.sslVerify false'; + } elseif (strpos($statusError, 'Could not resolve host') !== false || strpos($statusError, 'Connection refused') !== false) { + $errorMsg = 'NETWORK ERROR: Cannot connect to GitHub. Check network/firewall.'; + } elseif (trim($statusError) === '') { + $errorMsg = 'GIT ERROR: Command returned no output. Possible permission or file system issue.'; } else { - $errorMsg = 'Git status failed: ' . $statusError; + $errorMsg = 'GIT ERROR: ' . substr($statusError, 0, 150); } - // Add diagnostics to help user - $diagnostics = $this->getGitDiagnostics($gitPath, $repoPath); - $errorMsg .= ' [' . $diagnostics['git_version'] . ', User: ' . $diagnostics['git_config_user_name'] . ', Remote: ' . $diagnostics['remote_url'] . ']'; + $fullMsg = $errorMsg . ' | ' . $diagSummary; $this->appendHistory([ 'timestamp' => date('Y-m-d H:i:s'), 'type' => 'update', 'status' => 'failed', 'message' => 'HMS update failed', - 'detail' => $errorMsg, + 'detail' => $fullMsg, ]); - file_put_contents($logFile, 'FAILED: ' . $errorMsg . PHP_EOL, FILE_APPEND); - return ['ok' => false, 'message' => $errorMsg]; + file_put_contents($logFile, 'FAILED: ' . $fullMsg . ' (Raw error: ' . $statusError . ')' . PHP_EOL, FILE_APPEND); + return ['ok' => false, 'message' => $fullMsg]; } // Run git pull with timeout protection @@ -213,37 +226,68 @@ class SystemOperations 'git_config_user_email' => 'Not set', 'remote_url' => 'Not configured', 'current_branch' => 'Unknown', + 'git_dir_exists' => 'No', + 'git_config_exists' => 'No', + 'repo_is_dirty' => 'Unknown', ]; + // Check if .git directory exists + if (is_dir($repoPath . '/.git')) { + $diagnostics['git_dir_exists'] = 'Yes'; + } + + // Check if .git/config exists + if (file_exists($repoPath . '/.git/config')) { + $diagnostics['git_config_exists'] = 'Yes'; + } + // Get git version $result = $this->runCommand(escapeshellarg($gitPath) . ' --version 2>&1'); - if ($result['exit_code'] === 0) { + if ($result['exit_code'] === 0 && trim($result['output']) !== '') { $diagnostics['git_version'] = trim($result['output']); } - // Get git config - $result = $this->runCommand('cd ' . escapeshellarg($repoPath) . ' && ' . escapeshellarg($gitPath) . ' config user.name 2>&1'); - if ($result['exit_code'] === 0) { + // Get git config using --local flag (repository-specific) + $result = $this->runCommand('cd ' . escapeshellarg($repoPath) . ' && ' . escapeshellarg($gitPath) . ' config --local user.name 2>&1'); + if ($result['exit_code'] === 0 && trim($result['output']) !== '') { $diagnostics['git_config_user_name'] = trim($result['output']); + } else { + // Try global config + $result = $this->runCommand(escapeshellarg($gitPath) . ' config --global user.name 2>&1'); + if ($result['exit_code'] === 0 && trim($result['output']) !== '') { + $diagnostics['git_config_user_name'] = trim($result['output']) . ' (global)'; + } } - $result = $this->runCommand('cd ' . escapeshellarg($repoPath) . ' && ' . escapeshellarg($gitPath) . ' config user.email 2>&1'); - if ($result['exit_code'] === 0) { + $result = $this->runCommand('cd ' . escapeshellarg($repoPath) . ' && ' . escapeshellarg($gitPath) . ' config --local user.email 2>&1'); + if ($result['exit_code'] === 0 && trim($result['output']) !== '') { $diagnostics['git_config_user_email'] = trim($result['output']); + } else { + // Try global config + $result = $this->runCommand(escapeshellarg($gitPath) . ' config --global user.email 2>&1'); + if ($result['exit_code'] === 0 && trim($result['output']) !== '') { + $diagnostics['git_config_user_email'] = trim($result['output']) . ' (global)'; + } } // Get remote URL $result = $this->runCommand('cd ' . escapeshellarg($repoPath) . ' && ' . escapeshellarg($gitPath) . ' config --get remote.origin.url 2>&1'); - if ($result['exit_code'] === 0) { + if ($result['exit_code'] === 0 && trim($result['output']) !== '') { $diagnostics['remote_url'] = trim($result['output']); } // Get current branch $result = $this->runCommand('cd ' . escapeshellarg($repoPath) . ' && ' . escapeshellarg($gitPath) . ' rev-parse --abbrev-ref HEAD 2>&1'); - if ($result['exit_code'] === 0) { + if ($result['exit_code'] === 0 && trim($result['output']) !== '') { $diagnostics['current_branch'] = trim($result['output']); } + // Check if repo is dirty (has uncommitted changes) + $result = $this->runCommand('cd ' . escapeshellarg($repoPath) . ' && ' . escapeshellarg($gitPath) . ' status --porcelain 2>&1'); + if ($result['exit_code'] === 0) { + $diagnostics['repo_is_dirty'] = (trim($result['output']) === '') ? 'No' : 'Yes (has changes)'; + } + return $diagnostics; } diff --git a/setup_git_config.sh b/setup_git_config.sh new file mode 100644 index 0000000..e341b04 --- /dev/null +++ b/setup_git_config.sh @@ -0,0 +1,90 @@ +#!/bin/bash +# Setup script to configure git for www-data user +# Run this on your live server as root to fix git pull issues + +set -e + +echo "=========================================" +echo "HMS Git Configuration Setup Script" +echo "=========================================" +echo "" + +# Check if running as root +if [ "$EUID" -ne 0 ]; then + echo "ERROR: This script must be run as root" + echo "Usage: sudo bash setup_git_config.sh" + exit 1 +fi + +# Determine web server user +WEB_USER="www-data" +if ! id "$WEB_USER" &>/dev/null; then + echo "ERROR: User '$WEB_USER' not found. Please adjust WEB_USER variable." + exit 1 +fi + +# HMS installation directory +HMS_DIR="/var/www/html/hms_etria" +if [ ! -d "$HMS_DIR" ]; then + echo "ERROR: HMS directory not found at $HMS_DIR" + echo "Please update HMS_DIR in this script" + exit 1 +fi + +echo "Configuration Details:" +echo " Web user: $WEB_USER" +echo " HMS dir: $HMS_DIR" +echo "" + +# 1. Create .ssh directory for www-data if it doesn't exist +echo "[1/7] Creating .ssh directory for $WEB_USER..." +sudo -u "$WEB_USER" mkdir -p /var/www/.ssh +sudo -u "$WEB_USER" chmod 700 /var/www/.ssh + +# 2. Configure git user name +echo "[2/7] Configuring git user name..." +sudo -u "$WEB_USER" git config --global user.name "HMS Deploy User" + +# 3. Configure git email +echo "[3/7] Configuring git email..." +sudo -u "$WEB_USER" git config --global user.email "deploy@hms.local" + +# 4. Disable SSL verification (for HTTPS repos) +echo "[4/7] Configuring git SSL settings..." +sudo -u "$WEB_USER" git config --global http.sslVerify false + +# 5. Set git to use HTTPS instead of SSH (easier for automated deploys) +echo "[5/7] Configuring git to use HTTPS..." +cd "$HMS_DIR" +sudo -u "$WEB_USER" git remote set-url origin https://github.com/infodevsofttech-admin/devsofttech_hms_ci4.git + +# 6. Fix directory permissions +echo "[6/7] Fixing directory permissions..." +chown -R "$WEB_USER:$WEB_USER" "$HMS_DIR" +chmod -R 755 "$HMS_DIR" +chmod -R 755 "$HMS_DIR/.git" + +# 7. Test git status +echo "[7/7] Testing git status..." +cd "$HMS_DIR" +if sudo -u "$WEB_USER" git status &>/dev/null; then + echo "✓ Git status check PASSED" +else + echo "✗ Git status check FAILED" + exit 1 +fi + +echo "" +echo "=========================================" +echo "✓ Git configuration completed successfully!" +echo "=========================================" +echo "" +echo "You can now use the 'Update HMS' button in System Operations panel" +echo "" +echo "Git configuration stored at:" +echo " Global: /var/www/.gitconfig" +echo " Local: $HMS_DIR/.git/config" +echo "" +echo "To verify configuration, run:" +echo " sudo -u www-data git config --list" +echo ""