Skip to content
This repository has been archived by the owner on Apr 19, 2022. It is now read-only.

Commit

Permalink
Merge branch 'features'
Browse files Browse the repository at this point in the history
Conflicts:
	dialog.php
	templates/overview.html
  • Loading branch information
Andr3as committed Mar 22, 2017
2 parents f4f1c71 + 1e07381 commit 396b190
Show file tree
Hide file tree
Showing 12 changed files with 683 additions and 29 deletions.
215 changes: 208 additions & 7 deletions class.git.php
Expand Up @@ -5,7 +5,7 @@
* See http://opensource.org/licenses/MIT for more information.
* This information must remain intact.
*/
include_once('config.php');
include_once('config.php');

class Git {

Expand Down Expand Up @@ -95,10 +95,14 @@ public function commit($path, $msg) {
return $this->parseShellResult(-1, null, "Failed to set settings!");
}

public function getLog($path) {
if (!is_dir($path)) return false;
chdir($path);
$result = $this->executeCommand("git log");
public function getLog($repo) {
if (!is_dir($repo)) return false;
chdir($repo);
$cmd = "git log --relative-date ";
if (isset($_GET['path'])) {
$cmd .= " -- " . $_GET['path'];
}
$result = $this->executeCommand($cmd);
if ($result !== 0) {
return false;
}
Expand Down Expand Up @@ -422,7 +426,7 @@ public function renameItem($path, $old_name, $new_name) {
$result = $this->executeCommand($command);
if (strpos($this->result, "fatal: not under version control") !== false) {
if (rename($old_name,$new_name)) {
return $this->returnMessage("succes", "Renamed");
return $this->returnMessage("success", "Renamed");
} else {
return $this->returnMessage("error", "Could Not Rename");
}
Expand Down Expand Up @@ -529,6 +533,203 @@ public function numstat($path) {
}
}

public function showCommit($path, $commit) {
if (!is_dir($path)) return false;
chdir($path);
$result = $this->executeCommand("git show " . $commit);
if ($result !== 0) {
return $this->returnMessage("error", "Failed to show commit");
} else {
foreach($this->resultArray as $index => $line) {
$line = str_replace ("\t", " ", $line);
$this->resultArray[$index] = htmlentities($line);
}
return json_encode(array("status" => "success", "data" => $this->resultArray));
}
}

public function blame($repo, $path) {
if (!is_dir($repo)) return false;
chdir($repo);
$result = $this->executeCommand("git blame --line-porcelain " . $path);
if ($result !== 0) {
return $this->returnMessage("error", "Failed to get git blame");
} else {
foreach($this->resultArray as $index => $line) {
$line = str_replace ("\t", " ", $line);
$this->resultArray[$index] = htmlentities($line);
}
return json_encode(array("status" => "success", "data" => $this->resultArray));
}
}

public function network($repo) {
if (!is_dir($repo)) return false;
chdir($repo);
$cmds = array(
"git log --date-order --branches --pretty=format:%H%n%P%n%an%n%at%n%s",
"git show-ref --tags",
"git show-ref --heads",
"git rev-parse --abbrev-ref HEAD"
);
$results = array();
foreach($cmds as $cmd) {
$result = $this->executeCommand($cmd);
if ($result !== 0 && $result !== 1) { // Ignore unclean exit
return false;
}
array_push($results, $this->resultArray);
}
$log = $results[0];
$tags = $results[1];
$heads = $results[2];
$branch = $results[3][0];
//Compute commits
$log = array_chunk($log, 5);
$this->commits = array();
$keys = array("hash", "parents", "author", "time", "subject");
$this->hash_to_commit = array();
foreach ($log as $i => $commit) {
$commit = array_combine($keys, $commit);
$commit['computed'] = false;
$commit['id'] = $i;
if (strlen($commit['parents']) !== 0) {
$commit['parents'] = str_split(str_replace(" ", "", $commit['parents']), 40);
} else {
$commit['parents'] = array();
}
array_push($this->commits, $commit);
$this->hash_to_id[$commit['hash']] = $i;
}
//Compute refs
$keys = array("hash", "name");
$branch_to_hash = array();
foreach($heads as $i => $ref) {
$ref = str_replace("refs/heads/", "", $ref);
$ref = str_replace(" ", "", $ref);
$ref = str_split($ref, 40);
$ref = array_combine($keys, $ref);
$heads[$i] = $ref;
$branch_to_hash[$ref['name']] = $ref['hash'];
}
foreach($tags as $i => $ref) {
$ref = str_replace("refs/tags/", "", $ref);
$ref = str_replace(" ", "", $ref);
$ref = str_split($ref, 40);
$ref = array_combine($keys, $ref);
$tags[$i] = $ref;
}

//Line counter
$this->n_lines = 0;
$this->lineRanges = array();
//Walk line of current branch
$start = $branch_to_hash[$branch];
$this->walkLines($start, $this->n_lines, true);
//Walk lines of all branches
foreach($heads as $head) {
$this->walkLines($head['hash'], $this->n_lines, true);
}

//Extend ranges with parent
foreach($this->lineRanges as $line => $range) {
$start_id = $range['start_id'];
$commit = $this->commits[$start_id];
if (count($commit['parents']) > 0) {
$parent_hash = $commit['parents'][0];
$parent_id = $this->hash_to_id[$parent_hash];
$parent = $this->commits[$parent_id];
$this->lineRanges[$line]['start'] = $parent['time'];
$this->lineRanges[$line]['start_id'] = $parent_id;
}
}

//Sort ranges
function sort_ranges_by_start($a, $b) {
return $a['start'] - $b['start'];
}
uasort($this->lineRanges, 'sort_ranges_by_start');

$levels = array();
foreach($this->lineRanges as $line => $range) {
$merged = false;
foreach($levels as $index => $level) {
if ($level['end'] < $range['start']) {
array_push($levels[$index]['lines'], $line);
$levels[$index]['end'] = $range['end'];
$merged = true;
break;
}
}

if (!$merged) {
array_push($levels,array(
'lines' => array($line),
'start' => $range['start'],
'end' => $range['end']
));
}
}

foreach($levels as $index => $level) {
foreach($level['lines'] as $line) {
$this->lineRanges[$line]['level'] = $index;
}
}

foreach($this->commits as $id => $c) {
$this->commits[$id]['level'] = $this->lineRanges[$c['line']]['level'];
}

//Return
return array('commits' => $this->commits, 'heads' => $heads, 'tags' => $tags, 'branch' => $branch, 'hash_to_id' => $this->hash_to_id, 'lines' => ++$this->n_lines);
}

private function walkLines($hash, $line, $new_line) {
//Get commit id by given hash
$id = $this->hash_to_id[$hash];
if ($this->commits[$id]['computed']) {
return;
}
if ($new_line) {
$this->n_lines++;
$line = $this->n_lines;
}
$this->commits[$id]['line'] = $line;
$this->commits[$id]['computed'] = true;

//Ranges of lines
$time = $this->commits[$id]['time'];
if (!isset($this->lineRanges[$line])) {
$this->lineRanges[$line] = array(
'start' => $time,
'start_id' => $id,
'end' => $time,
'end_id' => $id
);
} else {

if ($time < $this->lineRanges[$line]['start']) {
$this->lineRanges[$line]['start'] = $time;
$this->lineRanges[$line]['start_id'] = $id;
}
if ($time > $this->lineRanges[$line]['end']) {
$this->lineRanges[$line]['end'] = $time;
$this->lineRanges[$line]['end_id'] = $id;
}
}

foreach($this->commits[$id]['parents'] as $i => $parent) {
if ($i == 0) {
//Same line
$this->walkLines($parent, $line, false);
} else {
//New line
$this->walkLines($parent, $this->n_lines, true);
}
}
}

public function getSettings($path) {
$settings = getJSON(CONFIG, 'config');
if (empty($settings)) {
Expand Down Expand Up @@ -777,7 +978,7 @@ private function untrackedDiff($path) {
}
} else {
$this->executeCommand('cat ' . $path);
array_push($result, "+++ ". $path);
array_push($result, "diff --git a/". $path . " b/" . $path);
foreach($this->resultArray as $index => $line) {
array_push($result, "+" . $line);
}
Expand Down
38 changes: 36 additions & 2 deletions controller.php
Expand Up @@ -93,8 +93,8 @@
break;

case 'log':
if (isset($_GET['path'])) {
$result = $git->getLog(getWorkspacePath($_GET['path']));
if (isset($_GET['repo'])) {
$result = $git->getLog(getWorkspacePath($_GET['repo']));
if ($result === false) {
echo '{"status":"error","message":"Failed to get log!"}';
} else {
Expand Down Expand Up @@ -347,6 +347,40 @@
}
break;

case 'showCommit':
if (isset($_GET['path']) && isset($_GET['commit'])) {
echo $git->showCommit(getWorkspacePath($_GET['path']), $_GET['commit']);
} else {
echo '{"status":"error","message":"Missing parameter!"}';
}
break;

case 'blame':
if (isset($_GET['repo']) && isset($_GET['path'])) {
$result = $git->blame(getWorkspacePath($_GET['repo']), $_GET['path']);
if ($result === false) {
echo '{"status":"error","message":"Failed to get diff!"}';
} else {
echo $result;
}
} else {
echo '{"status":"error","message":"Missing parameter!"}';
}
break;

case 'network':
if (isset($_GET['path'])) {
$result = $git->network(getWorkspacePath($_GET['path']));
if ($result === false) {
echo '{"status":"error","message":"Failed to get network!"}';
} else {
echo '{"status":"success","data":'. json_encode($result) .'}';
}
} else {
echo '{"status":"error","message":"Missing parameter!"}';
}
break;

case 'getSettings':
if (isset($_GET['path'])) {
$settings = $git->getSettings(getWorkspacePath($_GET['path']));
Expand Down
9 changes: 9 additions & 0 deletions dialog.php
Expand Up @@ -7,6 +7,9 @@
<form>
<?php
switch($_GET['action']) {
case 'blame':
include('templates/blame.html');
break;
case 'branches':
include('templates/branch.html');
break;
Expand All @@ -31,6 +34,9 @@
case 'newRemote':
include('templates/newRemote.html');
break;
case 'network':
include('templates/network.html');
break;
case 'passphrase':
include('templates/passphrase.html');
break;
Expand All @@ -55,6 +61,9 @@
case 'settings':
include('templates/settings.php');
break;
case 'showCommit':
include('templates/showCommit.html');
break;
case 'submodule':
include('templates/submodule.html');
break;
Expand Down

0 comments on commit 396b190

Please sign in to comment.