background
If you are curious about the principle behind the github platform, let’s explore and develop our own Github
There are several open source projects on the market where we can deploy private Git services
project | Development of language | address |
---|---|---|
gitlab | ruby | Gitlab.com/gitlab-org/… |
gogs | go | github.com/gogs/gogs |
gitea | go | Github.com/go-gitea/gi… |
Here are some of the problems I encountered while building a private Git service using these projects
- Gitlab has certain performance requirements for machines like raspberry pie (
My 4 b / 4 g
) This system often freezes after installation. Please refer to the installation requirements for details:Docs. Gitlab. Cn/jh/install /…- Gogs running does not have high requirements on machine performance, but it is developed based on GO language. As a front-end developer, it is not conducive to secondary function expansion
- Gitea is based on goGS
project
In line with the spirit of technical exploration and the enthusiasm of repeating the wheel, so set out to build a front-end developer friendly Git code management platform [Heart code]
Open source: github.com/lzuntalente… Example site: git.lzz.show/lz/lz-git
The principle of plane analysis
In fact, the essence of these platforms is to execute git commands remotely. When we operate on a page or execute git commands locally, we send a request to a remote server and attach the request content. These platforms help us execute git commands on the server
For example, when we create a project on the page, we are actually executing git init on the server
If you have Git installed, run the git clone dir command to clone a repository and run all git commands in the dir directory
implementation
technology
Lerna front-end: Typescript + React + ANTD back-end: Nestjs + mysql
The project architecture
Create a project
Git init –bare blog. Git init –bare blog. Git does not need to store a working directory on the server. Create an empty repository with –bare (red box at the top of the image below). When you clone a project, you will have an extra directory in your local directory
You can see that we have added.git to the name of the repository, which means that it is a git repository. As you can see when you clone a project from GitHub, they also provide a clone address with.git, so that it is the same
Pull and push code
Since it is not possible to clone dir on a remote server, we use HTTP mode for cloning
# Experience the sample site clone project feature
git clone http://git.lzz.show/lz/lz-git.git
Copy the code
What happens when you run git clone? See git-scm.com/docs/http-p…
- Sends a path to the remote end
/info/refs? service=git-upload-pack
GET request to GET reference information for the remote repository- Upon receiving the request, the HTTP service executes the command under the remote repository
git upload-pack --stateless-rpc --advertise-refs remote/repository/dir
And returns the command output as an HTTP response to the client- The client initiation path is
/git-upload-pack
To obtain a remote resource- Upon receiving the request, the HTTP service executes the command under the remote repository
git upload-pack --stateless-rpc remote/repository/dir
And returns the command output as an HTTP response to the client- The command is executed
The git push command is similar to the clone command except that the service parameter changes from git-upload-pack to git-receive-pack, and the git command parameter changes from upload-pack to receive-pack
The problem record
Because the content-Type in the HTTP request header initiated by Git is a non-standard header, Express cannot automatically parse the body in the request body, so we need to customize the middleware to parse the body
export function header(req: Request, res: Response, next: NextFunction) {
if (req.header('Content-Type'.toLowerCase()) === 'application/x-git-upload-pack-request'
|| req.header('Content-Type'.toLowerCase()) === 'application/x-git-receive-pack-request'
) {
const body = [];
req.on('data'.(chunk) = > {
body.push(chunk);
}).on('end'.() = > {
// Body is converted to buffer format to make it easier to pass the body content as input to git commands
req.body = Buffer.concat(body);
next();
});
} else{ next(); }};Copy the code
The last
So far, we have preliminarily built a Git code management platform based on Javascript development, and we will continue to look at Github and improve the function. If you think this article is useful to you, welcome to leave a like or welcome to the project site ⭐ open source address
History project
- Introduction to the Open source microscene editor
- Start from scratch – Basic flowchart editing library