gitHTTP.py
Python script, ASCII text executable
1from gitme import app 2 3import os 4import config 5import flask 6import git 7import subprocess 8 9 10@app.route("/git/<username>/<repository>/<path:git_path>", methods=["GET", "POST"]) 11def git_http_backend(username, repository, git_path): 12repo_path = os.path.join(config.REPOS_PATH, username, repository, ".git") 13repo = git.Repo(repo_path) 14git_cmd = repo.git 15 16if flask.request.method == "GET": 17result = git_cmd.upload_pack() 18elif flask.request.method == "POST": 19result = git_cmd.receive_pack() 20 21response = flask.Response(result, content_type="application/x-git-" + git_cmd[-1]) 22return response 23 24 25@app.route("/git/<username>/<repository>/info/refs") 26def gitInfoRefs(username, repository): 27serverRepoLocation = os.path.join(config.REPOS_PATH, os.path.join(username, repository)) 28 29app.logger.info(f"Loading {serverRepoLocation}") 30 31if not os.path.exists(serverRepoLocation): 32app.logger.error(f"Cannot load {serverRepoLocation}") 33flask.abort(404) 34 35repo = git.Repo(serverRepoLocation) 36text = f"{repo.heads[0].commit.hexsha}\tHEAD\n" 37for ref in repo.heads: 38text += f"{ref.commit.hexsha}\trefs/heads/{ref.name}\n" 39 40app.logger.warning(text) 41 42return flask.Response(text, content_type="application/x-git-upload-pack-result") 43 44 45@app.route("/git/<username>/<repository>/objects/info/alternates", methods=["GET"]) 46def gitInfoAlternates(username, repository): 47# Handle the request and provide the response 48text = "#Alternate object stores\n" 49 50return flask.Response(text, content_type="text/plain") 51 52 53@app.route("/git/<username>/<repository>/objects/info/http-alternates") 54def gitHttpAlternates(username, repository): 55# Return an empty response 56return flask.Response("", content_type="text/plain") 57 58 59@app.route("/git/<username>/<repository>/HEAD") 60def gitHead(username, repository): 61serverRepoLocation = os.path.join(config.REPOS_PATH, os.path.join(username, repository)) 62 63app.logger.info(f"Loading {serverRepoLocation}") 64 65if not os.path.exists(serverRepoLocation): 66app.logger.error(f"Cannot load {serverRepoLocation}") 67flask.abort(404) 68 69repo = git.Repo(serverRepoLocation) 70 71text = f"ref: {repo.head.ref}\n" 72 73return flask.Response(text, content_type="text/plain") 74 75 76@app.route("/git/<username>/<repository>/objects/info/packs") 77def gitInfoPacks(username, repository): 78repo_path = os.path.join(config.REPOS_PATH, username, repository) 79 80# List the pack files in the repository 81packs = [f for f in os.listdir(os.path.join(repo_path, "objects", "pack")) if f.endswith(".pack")] 82 83# Generate a response with the list of pack files 84response_text = "\n".join(packs) + "\n" 85 86return flask.Response(response_text, content_type="text/plain") 87 88 89@app.route("/git/<username>/<repository>/objects/<path:object_path>") 90def gitObject(username, repository, object_path): 91repo_path = os.path.join(config.REPOS_PATH, username, repository) 92object_full_path = os.path.join(repo_path, ".git/objects", object_path) 93 94# Check if the object file exists 95if not os.path.exists(object_full_path): 96return flask.Response("Object not found", status=404, content_type="text/plain") 97 98# Serve the object as binary data 99with open(object_full_path, "rb") as object_file: 100object_data = object_file.read() 101 102return flask.Response(object_data, content_type="application/octet-stream") 103 104 105@app.route("/git/<username>/<repository>/git-upload-pack", methods=["POST"]) 106def gitUploadPack(username, repository): 107repoPath = "/path/to/repos/{}/{}/".format(username, repository) 108cmd = ["git", "--git-dir", repoPath, "upload-pack"] 109 110gitProcess = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 111 112# Forward the Git process input and output 113inputData = flask.request.get_data() 114output = gitProcess.communicate(input=inputData) 115return flask.Response(output[0], content_type="application/x-git-upload-pack-result") 116 117 118@app.route("/git/<username>/<repository>/git-receive-pack", methods=["POST"]) 119def gitReceivePack(username, repository): 120repoPath = "/path/to/repos/{}/{}/".format(username, repository) 121cmd = ["git", "--git-dir", repoPath, "receive-pack"] 122 123gitProcess = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 124 125# Forward the Git process input and output 126inputData = flask.request.get_data() 127output = gitProcess.communicate(input=inputData) 128return flask.Response(output[0], content_type="application/x-git-receive-pack-result") 129