Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

local git repositories access #25

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## About this fork

This fork adds ability to run webui in directory with your local git repositories.

# Git WebUI

This git extension is a standalone web based user interface for git repositories.
Expand Down
64 changes: 53 additions & 11 deletions src/libexec/git-core/git-webui
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import argparse
import codecs
import datetime
import os
import glob
import platform
import posixpath
import shlex
Expand Down Expand Up @@ -64,17 +65,23 @@ class HTTPServerIPng(HTTPServer):
class WebUiRequestHandler(SimpleHTTPRequestHandler):

WEB_ROOT = None
REPO_ROOT = None
BASE_ROOT = None

def __init__(self, request, client_address, server):
self.repo_root = WebUiRequestHandler.BASE_ROOT
self.isrepo = os.path.exists(self.repo_root + '.git')
SimpleHTTPRequestHandler.__init__(self, request, client_address, server)

@classmethod
def initialize(cls, repo_root):
web_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(sys.argv[0]))))
web_root = os.path.join(web_root, "share", "git-webui", "webui")
WebUiRequestHandler.WEB_ROOT = web_root
WebUiRequestHandler.REPO_ROOT = repo_root
WebUiRequestHandler.BASE_ROOT = repo_root


def translate_path(self, path):
path = self.prenavigate(path)
if self.is_git_request():
return path

Expand All @@ -96,26 +103,50 @@ class WebUiRequestHandler(SimpleHTTPRequestHandler):
path += '/'
return path

def prenavigate(self, path):
# navitage to git repo
dirs = filter(lambda pe: pe, path.split('/'))
subdir = []
self.isrepo = False
while dirs != None:
if os.path.exists(os.path.join(WebUiRequestHandler.BASE_ROOT, *(subdir + ['.git']))):
self.repo_root = os.path.join(WebUiRequestHandler.BASE_ROOT, *subdir)
path = '/' + '/'.join(dirs)
self.isrepo = True
break
if len(dirs) == 0:
dirs = None
else:
subdir.append(dirs.pop(0))
return path

def do_GET(self):
self.path = self.prenavigate(self.path)
print self.path, self.repo_root
if self.path.startswith("/git/cat-file/"):
obj = self.path[14:]
self.process(["git", "cat-file", "-p", obj], b"", True, False)
elif self.path == "/dirname":
wc = os.path.split(WebUiRequestHandler.REPO_ROOT)[1]
wc = os.path.split(self.repo_root)[1]
self.send_text(200, codecs.encode(wc, "utf-8"))
elif self.path == "/hostname":
self.send_text(200, codecs.encode(socket.gethostname(), "utf-8"))
elif self.path == "/viewonly":
vo = "1" if self.is_view_only() else "0"
self.send_text(200, codecs.encode(vo, "utf-8"))
elif self.path == "/isrepo":
isrepo = "1" if self.isrepo else "0"
self.send_text(200, codecs.encode(isrepo, "utf-8"))
elif self.path == "/dirlist":
self.send_git_dirlist()
elif self.is_git_request():
self.process_http_backend()
else:
SimpleHTTPRequestHandler.do_GET(self)


def do_POST(self):
self.path = self.prenavigate(self.path)
if self.path == "/git":
content_length = int(self.headers["Content-Length"])
content = self.rfile.read(content_length)
Expand Down Expand Up @@ -148,7 +179,7 @@ class WebUiRequestHandler(SimpleHTTPRequestHandler):
parsed_path = urlparse(self.path)

env = {}
env["GIT_PROJECT_ROOT"] = WebUiRequestHandler.REPO_ROOT + "/.git"
env["GIT_PROJECT_ROOT"] = self.repo_root + "/.git"
env["GIT_HTTP_EXPORT_ALL"] = ""
env["REQUEST_METHOD"] = self.command
env["REMOTE_ADDR"] = self.client_address[0]
Expand Down Expand Up @@ -181,7 +212,7 @@ class WebUiRequestHandler(SimpleHTTPRequestHandler):
# Finially we add footers: a blank line followed by key / value pairs as in HTTP headers
if IS_WINDOWS:
# On windows we cannot pipe the process output directly to the socket.
git = subprocess.Popen(cmd, stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE, cwd = WebUiRequestHandler.REPO_ROOT, env = env)
git = subprocess.Popen(cmd, stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE, cwd = self.repo_root, env = env)
git.stdin.write(stdin)
git.stdin.close()
bufferlen = 64 * 1024
Expand All @@ -193,7 +224,7 @@ class WebUiRequestHandler(SimpleHTTPRequestHandler):
stderr = git.stderr.read()
git.wait()
else:
git = subprocess.Popen(cmd, stdin = subprocess.PIPE, stdout = self.wfile, stderr = subprocess.PIPE, cwd = WebUiRequestHandler.REPO_ROOT, env = env)
git = subprocess.Popen(cmd, stdin = subprocess.PIPE, stdout = self.wfile, stderr = subprocess.PIPE, cwd = self.repo_root, env = env)
stdout, stderr = git.communicate(stdin)
if add_footers:
self.wfile.write(stderr)
Expand All @@ -211,7 +242,18 @@ class WebUiRequestHandler(SimpleHTTPRequestHandler):
self.end_headers()
self.wfile.write(text)


def send_git_dirlist(self):
dirlist = []
for dir_raw in glob.glob(os.path.join(WebUiRequestHandler.BASE_ROOT, '*')):
reldir = os.path.relpath(dir_raw, WebUiRequestHandler.BASE_ROOT)
if os.path.exists(os.path.join(WebUiRequestHandler.BASE_ROOT, reldir, '.git')):
dirlist.append(reldir)
dirlist = '\n'.join(dirlist)
self.send_response(200)
self.send_header("Content-Type", "text/plain")
self.send_header("Content-Length", len(dirlist))
self.end_headers()
self.wfile.write(dirlist)


def auto_update():
Expand Down Expand Up @@ -303,10 +345,10 @@ if __name__ == '__main__':
if args.allow_hosts is not None:
allowed_hosts += args.allow_hosts.split(',')

if args.repo_root is None or '.git' not in os.listdir(args.repo_root):
sys.stderr.write("No git repository found\n")
sys.exit(1)
WebUiRequestHandler.initialize(args.repo_root)
#if args.repo_root is None or '.git' not in os.listdir(args.repo_root):
# sys.stderr.write("No git repository found\n")
# sys.exit(1)
WebUiRequestHandler.initialize(args.repo_root or os.getcwd())

args.port = get_setting_string(args, 'port', None)
port = int(args.port) if args.port is not None else 8000
Expand Down
20 changes: 20 additions & 0 deletions src/share/git-webui/webui/css/git-webui.less
Original file line number Diff line number Diff line change
Expand Up @@ -621,3 +621,23 @@ body {
}
}
}

#dirlist-container {

.repos-header {
magring: 0;
padding: 0.7em;
font-size: 12pt;
background-color: @gray-dark;
color: @gray-lighter;
}

.repo-item {
font-size: 12pt;
padding: 0.7em;
}

.repo-item:nth-of-type(even) {
background-color: #eee;
}
}
74 changes: 48 additions & 26 deletions src/share/git-webui/webui/js/git-webui.js
Original file line number Diff line number Diff line change
Expand Up @@ -1710,6 +1710,17 @@ webui.RemoteView = function(mainView) {
$(".git-pull", self.element).text("git pull http://" + webui.hostname + ":" + document.location.port + "/");
};

webui.DirlistView = function (mainView) {

var globalContainer = $('<div id="dirlist-container">').appendTo('body');

globalContainer.append('<div class="repos-header">Collection of GIT repositories</div>')

$.each(mainView.repos, function (i, repo) {
globalContainer.append('<div class="repo-item"><a href="/'+repo+'/">'+repo+'</a></div>');
})
}

/*
* == Initialization =========================================================
*/
Expand All @@ -1722,33 +1733,44 @@ function MainUi() {
self.mainView.appendChild(element);
}

$.get("/dirname", function (data) {
webui.repo = data;
var title = $("title")[0];
title.textContent = "Git - " + webui.repo;
$.get("/viewonly", function (data) {
webui.viewonly = data == "1";
$.get("/hostname", function (data) {
webui.hostname = data

var body = $("body")[0];
$('<div id="message-box">').appendTo(body);
var globalContainer = $('<div id="global-container">').appendTo(body)[0];

self.sideBarView = new webui.SideBarView(self);
globalContainer.appendChild(self.sideBarView.element);

self.mainView = $('<div id="main-view">')[0];
globalContainer.appendChild(self.mainView);

self.historyView = new webui.HistoryView(self);
self.remoteView = new webui.RemoteView(self);
if (!webui.viewonly) {
self.workspaceView = new webui.WorkspaceView(self);
}
$.get('isrepo', function (data) {

if (data == "1") {
$.get("/dirname", function (data) {
webui.repo = data;
var title = $("title")[0];
title.textContent = "Git - " + webui.repo;
$.get("/viewonly", function (data) {
webui.viewonly = data == "1";
$.get("/hostname", function (data) {
webui.hostname = data

var body = $("body")[0];
$('<div id="message-box">').appendTo(body);
var globalContainer = $('<div id="global-container">').appendTo(body)[0];

self.sideBarView = new webui.SideBarView(self);
globalContainer.appendChild(self.sideBarView.element);

self.mainView = $('<div id="main-view">')[0];
globalContainer.appendChild(self.mainView);

self.historyView = new webui.HistoryView(self);
self.remoteView = new webui.RemoteView(self);
if (!webui.viewonly) {
self.workspaceView = new webui.WorkspaceView(self);
}
});
});
});
});
});
} else {
$.get("/dirlist", function (data) {
self.repos = data.split('\n');
self.dirlistView = new webui.DirlistView(self);
})
}

})
}

$(document).ready(function () {
Expand Down