| | if (!$sha) return; |
| | |
| | - $treeSha = $this->findTree($sha); |
| | - if (!$treeSha) return; |
| | - |
| | - $data = $this->read($treeSha); |
| | + // Check if this is a tree object directly, or a commit containing a tree |
| | + $data = $this->read($sha); |
| | if (!$data) return; |
| | + |
| | + // If it's a commit, extract the tree hash |
| | + if (preg_match('/^tree ([0-9a-f]{40})$/m', $data, $m)) { |
| | + $treeSha = $m[1]; |
| | + $data = $this->read($treeSha); |
| | + if (!$data) return; |
| | + } |
| | + // If it's not a commit and not a valid tree format, bail out |
| | + elseif (!$this->isTreeData($data)) { |
| | + return; |
| | + } |
| | + // Otherwise, $data already contains the tree content (we have a tree hash) |
| | |
| | $pos = 0; |
 |
| | |
| | $pos = $null + 21; |
| | + } |
| | + } |
| | + |
| | + // Helper to detect if raw data is a tree object |
| | + private function isTreeData(string $data): bool { |
| | + if (strlen($data) < 25) return false; |
| | + if (preg_match('/^(40000|100644|100755|120000) /', $data)) { |
| | + $null = strpos($data, "\0"); |
| | + if ($null !== false && ($null + 21 <= strlen($data))) { |
| | + return true; |
| | + } |
| | } |
| | + return false; |
| | } |
| | |