Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env php
- <?php
- $wd = getcwd();
- $git_dir = shell_exec('git rev-parse --show-toplevel');
- if(!$git_dir) {
- fprintf(STDERR, "Not inside a git path");
- exit(1);
- }
- $git_wd = substr($wd, strlen($git_dir));
- [$arguments, $flags] = parse_arguments(array_slice($argv, 1));
- $branches = [];
- if(count($arguments) == 1)
- {
- $branches['HEAD'] = hash_branch('HEAD', $flags);
- }
- foreach($arguments as $branch_name)
- {
- if(!isset($branches[$branch_name]))
- {
- $branches[$branch_name] = hash_branch($branch_name, $flags);
- }
- }
- $patch_index = [];
- foreach($branches as $branch_name => $branch_commits)
- {
- foreach($branch_commits as $commit)
- {
- if(empty($commit['patch_hash'])) continue;
- $patch_index[$commit['patch_hash']][$commit['commit_hash']] = $commit['branches'];
- }
- }
- $branch_compare_count = count($branches);
- foreach($patch_index as $patch_hash => $patch_commits)
- {
- $patch_branches = [];
- foreach($patch_commits as $commit_branches)
- {
- foreach($commit_branches as $branch_name)
- {
- $patch_branches[$branch_name] = $branch_name;
- }
- }
- $patch_branch_count = count($patch_branches);
- $first_commit = array_keys($patch_commits)[0];
- $first_branch = $patch_commits[$first_commit][0];
- $short_commit = substr($first_commit, 0, 7);
- if($patch_branch_count == $branch_compare_count)
- {
- if(count($patch_commits) > 1)
- {
- echo "{$short_commit} (ALL:cherry) {$branches[$first_branch][$first_commit]['title']}\n";
- }
- else
- {
- echo "{$short_commit} (ALL:same) {$branches[$first_branch][$first_commit]['title']}\n";
- }
- }
- else
- {
- echo "{$short_commit} (" . implode(', ', $patch_branches) . ") {$branches[$first_branch][$first_commit]['title']}\n";
- }
- }
- exit(0);
- function hash_branch($branch_name, $flags)
- {
- static $hashes = [];
- $cmd = 'git log --format="format:%H %s" ';
- if(!empty($flags['-c']))
- {
- $cmd .= ' -' . ((int) $flags['-c'][0]) . ' ';
- }
- if($branch_name)
- {
- $cmd .= escapeshellarg($branch_name);
- }
- $error = 0;
- $output = [];
- exec($cmd, $output, $error);
- if($error)
- {
- return FALSE;
- }
- $branch_hases = [];
- foreach($output as $row)
- {
- [$commit_hash, $commit_title] = explode(' ', $row, 2);
- if(!isset($hashes[$commit_hash]))
- {
- $hashes[$commit_hash] = load_commit($commit_hash, $commit_title, $flags);
- }
- $hashes[$commit_hash]['branches'][] = $branch_name;
- $branch_hases[$commit_hash] = &$hashes[$commit_hash];
- }
- return $branch_hases;
- }
- function load_commit($commit_hash, $commit_title, $flags)
- {
- $commit = ['commit_hash' => $commit_hash, 'title' => $commit_title, 'patch_hash' => NULL, 'branches' => []];
- $cmd = 'git show --format=format:%H ' . escapeshellarg($commit_hash);
- $error = 0;
- $output = [];
- exec($cmd, $output, $error);
- if($error)
- {
- return FALSE;
- }
- $compare_commit_hash = trim(array_shift($output));
- if($compare_commit_hash != $commit_hash)
- {
- return FALSE;
- }
- $hash_data = array();
- $include_file = TRUE;
- foreach($output as $row)
- {
- if(substr($row, 0, 5) == 'diff ')
- {
- if($flags AND isset($flags['-x']))
- {
- $match = FALSE;
- $row_parts = explode(' ', $row, 3);
- foreach($flags['-x'] as $path)
- {
- $path = trim($path);
- if(substr($path, 0, 1) == '/')
- {
- $path = substr($path, 1);
- }
- if(substr($path, -1) == '*')
- {
- $path = substr($path, 0, -1);
- }
- else if(substr($path, -1) != '/')
- {
- $path .= ' ';
- }
- if($row_parts[1] == '--git')
- {
- if(substr($row, 0, 13 + strlen($path)) == "diff --git a/{$path}")
- {
- $match = TRUE;
- break;
- }
- }
- else if($row_parts[1] == '--cc')
- {
- if(substr($row, 0, 10 + strlen($path)) == "diff --cc {$path}")
- {
- $match = TRUE;
- break;
- }
- }
- }
- if($match)
- {
- $include_file = FALSE;
- continue;
- }
- }
- $include_file = TRUE;
- $hash_data[] = $row;
- continue;
- }
- if(!$include_file)
- {
- continue;
- }
- if(substr($row, 0, 6) == 'index ')
- {
- continue;
- }
- if(substr($row, 0, 3) == '@@ ')
- {
- $hash_data[] = '@@';
- continue;
- }
- $hash_data[] = $row;
- }
- if($hash_data)
- {
- $commit['patch_hash'] = sha1(implode(PHP_EOL, $hash_data));
- }
- return $commit;
- }
- function parse_arguments($raw_arguments)
- {
- $arguments = array();
- $flags = array();
- while($raw_arguments)
- {
- $current_arguemnt = array_shift($raw_arguments);
- if(substr($current_arguemnt, 0, 1) != '-')
- {
- $arguments[] = $current_arguemnt;
- continue;
- }
- if($current_arguemnt == '--')
- {
- while($current_arguemnt = array_shift($raw_arguments))
- {
- $arguments[] = $current_arguemnt;
- }
- break;
- }
- $next_argument = array_shift($raw_arguments);
- $flags[$current_arguemnt][] = $next_argument;
- }
- return array($arguments, $flags);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement