Notice
Beta quality stuff, which hasn't seen production use, and is pretty hackily thrown together.
Introduction
Pull Reqer is grab bag of tools, both client and server side
for setting implementing a pull request like feature usable on the command line
and conversion of repo
manifests to locally hosted repositories.
Important this project works with the alibaba git-repo
client not the google repo-tool
.
After setting everything up you'll have a locally hosted repository to which you can make pull requests to. usable either the normal git checkouts, or a git-repo multi-repository manifest.
Most of this is driven by the alibaba git-repo
client utility
Pull Reqer provides the needed hooks, and some utilities for converting git-repo checkouts into locally usable variants.
Client components
For mirroring remote git-repo repositories,
Externally provided utilities:
- git (at least version 2.29)
- git-repo.info from alibaba
Server components
A git hook implementing the pull request protocol.
Externally provided requirements:
- git (at least version 2.29)
- an ssh daemon.
There is not currently any web interface available.
Container
Scripts for building a container with everything needed on the server.
External dependencies:
Installation
Installation steps,
- Build the container
- Run the container
- Build the client utilities
- Client ssh setup
Step 1
Building the container.
pullreqr_container/mk_pullreqr_container
Step 2
Running the container.
build/host_scripts/git_start.sh
To stop it:
build/host_scripts/git_stop.sh
Optionally enable it to start via systemd
install -D -t ~/.config/systemd/user/ build/host_scripts/pullreqr.service
systemctl --user enable pullreqr.service --now
Step 3
Client installation
installation:
Step 4
Client setup:
- Add keys to
~/.ssh/config
cat <<"EOF" | envsubst '${PWD}' >>~/.ssh/config
Host localhost
HostName localhost
User git
Port 2222
IdentityFile ${PWD}/persistent/keys/user_key
EOF
Initial Testing
Check that you can ssh into the container, and create a repository. Next We'll use this test repostory in single repostory
ssh localhost create_pr_repo test
Single repository usage
Now that the server and client are built and running, create a test repository, and commit to it, and make a pull request.
- Client setup for a single repository
Previously we created an empty repository on the server which we can push to, before we can make a pull request, we need to add an initial commit.
git init
cd test
echo "foo" >README.md
git add README.md
git commit -m "An initial commit"
git remote add origin ssh://localhost/~/test.git
git push --set-upstream origin main
Now create a pull request:
echo "test 1" >>README.md
git add README.md
git commit -m "a test pull-request"
git pr
This should launch your editor, after filling in the form and exiting you should see:
$ git pr
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Writing objects: 100% (3/3), 252 bytes | 252.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To ssh://localhost:2222/~/test.git
* [new branch] master -> for/master/pr1
----------------------------------------------------------------------
Check out the pull-request to a local branch:
git fetch origin for/master/pr1:pr1
git checkout pr1
Multi repository
After successfully testing everything works with a single repository
we'll mirror a repo
manifest, and set up a mirror so that our pull-requests will go our local system.
It is best to do this on a repository with no review url to ensure that you aren't accidentally sending bogus pull-requests upstream.
mirroring a multi-repository repo
checkout
Has a few steps,
- Setting up a local mirror
- Download the repositories
git repo
using the--mirror
flag. - Create repositories for these on our local server
- Push the downloaded repositories to our local server
- Download the repositories
- Using the local mirror with
git repo
- Repo init the repository again without the
--mirror
flag. - Make a modified manifest, putting that in the
local_manifests
directory. - Use
git repo sync
to make a clone which fetches and pulls from out local repository.
- Repo init the repository again without the
- Using
git repo upload
, to make changesmanifest-tool
is a tool which helps with the above steps 2 and 4.
Configuring manifest-tool for step 1.
Add the following to your ~/.config/manifest-tool/projects/default.env
ssh localhost create_pr_repo ${remote_name}/${project_name} </dev/null
GIT_DIR="$(basename -s .git ${project_name}).git" git remote add mine ssh://localhost/~/${remote_name}/${project_name}
GIT_DIR="$(basename -s .git ${project_name}).git" git push --all mine
Rather than performing a checkout into a work tree, --mirror
will just download the repositories. We use manifest-tool to:
- Create a repo for the local mirror
- Add a remote the cloned repository
git repo
- Push the repository to our mirror.
We want to run this for every project in the manifest.
Step 1
Setting up a local mirror:
mkdir mirror
cd mirror
git repo init -u https://example.com/foo/example.git --mirror
git repo sync
manifest-tool --projects | sh
Configuring manifest-tool for step 2.
Add the following to ~/.config/manifest-tool/convert/default.env
push_url=ssh://localhost/~git/${remote_name}/
review_url=ssh://localhost/~/
fetch_url=ssh://localhost/~git/${remote_name}/
review_proto=agit
Unlike --projects
which just emitted a shell script,
the --convert
flag, reads the manifest performs substitutions,
and then writes a new manifest to the local_manifests
directory.
We run manifest tool in between git repo init
, and git repo sync
. In the process git repo sync
should now be checking out from and pushing to localhost.
Step 2
Using the local mirror with git repo
:
mkdir work
cd work
git repo init -u https://example.com/foo/example.git
manifest-tool --convert
git repo sync
Step 3
Using git repo upload
, to make changes:
cd test/
git repo start pull-test
echo "test" > test.txt
git add test.txt
git commit -m "test commit for multi-repo"
git repo upload
Containers build process
Here is a general overview of the container building process. There are 3 containers
TODO This could use a lot more explanation.
- build_env
- build
- run
build_env
- Install development tools for git
- Install development tools for rust
build
- Compile git & pullreqr_hook
run
- Generate user keys & account to push to, using git-shell.
- Copy public key into a mounted volume.
- installs git and the hook, and ssh daemon.
- Configures the ssh daemon