This article explains how a Git server built with git init --bare differs from AngusGit, and how to move a bare repository you already have. After reading it, you can tell that a bare repository can only push and pull, with no website, no pull requests, and no review; when someone else has to look at a change before it lands on main, you open a pull request on AngusGit and push the bare repository into a new empty repository.
Sign in to AngusGit first. If the repository is still empty, or you do not have a key yet, do this before you push. If you have no ~/.ssh/id_ed25519.pub, run ssh-keygen -t ed25519 -C "you@example.com", press Enter for the path, and register the line from cat ~/.ssh/id_ed25519.pub that starts with ssh-ed25519 under Settings → Profile, on the SSH Keys tab. When you open Repositories → New repository in the sidebar, leave Add a README file, Add .gitignore, and Choose a license unchecked. The push address is ssh://git@host:2222/owner/repo.git, and the username is git. For HTTPS, an access token is a secret string you generate and use in place of a password. Open the Access Tokens tab and generate a git:write token with repository permission WRITE. The username is your login name, and the password is the token.
The conversation page is compared with the still-open xlliu/test-pr-example #9. When you move a bare repository, put your own empty repository in the target of the commands. Do not push to anguskit/AngusKit, which already has history.
1. How a bare repository works
Creating a bare repository on a server is short:
sudo adduser git
sudo -u git git init --bare /srv/git/AngusKit.git
A bare repository stores only Git data. It has no working files you can edit. Each person who needs access gives an SSH public key to an administrator. The administrator appends it to ~/.ssh/authorized_keys for the git user on the server. After that, clone and push work:
git clone git@your-server:/srv/git/AngusKit.git
In this setup, the server only checks "can this person sign in as git". A public key in authorized_keys can read and write every repository and every branch on the server, and can force-push or delete a branch. Limiting that means writing your own server-side hook scripts.
2. What a bare repository and AngusGit can each do
| What you want to do | Bare repository | AngusGit |
|---|---|---|
| Push and pull code | Yes, over SSH | Yes, over SSH or HTTPS |
| Read code and commit history without cloning | No | Browse files, commits, and branches on the code page |
| Open a pull request so someone looks before you merge | No. You agree in person or by email | Open it under Pull Requests. The diff and the check results are visible before merge |
| Comment on one line of code | No | Write a line comment under Review, then submit an approval or a request for changes |
Block a direct push to main, and block force-push and deletion |
Write a hook script yourself | Turn the switches on under repository Settings → Branch Protection |
| Let someone look and not push | Hard. A server account is all or nothing | Five repository permissions: Read, Triage, Write, Maintain, and Admin |
| Record bugs and requirements, and tie them to a code change | No | Record them under Issues. A pull request that contains Closes #<number> links and closes the issue |
| Bring a new teammate in | An administrator signs in to the server and appends a public key | The new person registers a public key under Settings → Profile, on the SSH Keys tab. An administrator only adds them to the team or the repository |
A bare repository has a place it fits: one or two people, one extra copy of the code on the intranet, and no need for review or separate permissions. It is simpler than any platform. As soon as you need "someone looks at a change before it lands on main", switch to a platform that can open pull requests.
A pull request is a request to merge one branch into another after someone reviews the change.
3. Open the first pull request on AngusGit
AngusGit calls a merge request a Pull Request. It is the same thing as a GitLab merge request and a GitHub pull request. Starting from a repository that already has code, the shortest path is four steps. The still-open xlliu/test-pr-example #9 is the example. It already exists, so you can look at the page before merge. You do not need to create another one or merge this one.
-
Change code on a new branch and push
Do not edit
maindirectly. Create a new branch locally (git switch -c <branch-name>), commit, and push withgit push -u origin <branch-name>. The example branch isfeature/link-empty-cart. -
Open a pull request
Open the repository in a browser, go to the Branches tab, and on the new branch's row click Compare with default branch. Then click Create Pull Request. Title says what changed. Description says why. This one's title is "docs: 说明空购物车不计算折扣", and the description contains
Closes #4. - Ask a teammate to review The teammate opens the request under Review in the sidebar, reads the diff, and submits Approve, or writes down what should change. On this one, Angus and admin are both still Pending.
-
Merge
After the review is approved and there are no conflicts, go back to the pull request's Conversation tab, click Merge pull request, choose the merge method, and click Confirm merge. The change lands on
mainafter you see Pull request merged successfully. This one cannot be merged yet.
The pull request title is "docs: 说明空购物车不计算折扣". The source branch is feature/link-empty-cart. The target is main. The merge card says "This pull request is not ready to merge": there are No status checks, and "Reviews are still pending and must be approved before merge". The Merge pull request button is there. The review is not finished, so leave it unclicked. #9 is the page to compare with. You do not need to look for fix-install-path.
Prepare the key and the token as at the start of this article. Create the empty repository as at the start, then push the bare repository as in section 4. To make "every change goes through a pull request" a hard rule, turn on branch protection for main. During review, open the request under Review in the sidebar, read the diff under Files changed, comment on a line, then click Submit review and choose Approve, Request changes, or Comment.
4. Move an existing bare repository to AngusGit in full
History, branches, and tags in a bare repository can move as they are. Clone it in full, then push to an empty repository on AngusGit.
-
Create an empty repository on AngusGit
In the sidebar, click Repositories, then New repository. Leave Add a README file, Add .gitignore, and Choose a license unchecked. Otherwise the push is rejected because the histories do not match. Use a repository name that does not exist yet.
anguskit/AngusKitalready has commits, so it cannot be this empty repository. -
Clone the old repository in full
On any computer that can reach the old server, run
git clone --bareand download every branch and tag. -
Push to AngusGit
The first command uses
--allto push every branch. The second uses--tagsto push every tag. -
Have everyone switch to the new URL
Each person runs
git remote set-url originin their local repository, points it at AngusGit, then runsgit fetch origin. The history was copied as it is, so the local repository does not need a fresh clone.
The commands for the move, and for switching the remote, are:
git clone --bare git@your-server:/srv/git/notes.git
cd notes.git
git push ssh://git@git.anguskit.com:2222/<your-team>/notes.git --all
git push ssh://git@git.anguskit.com:2222/<your-team>/notes.git --tags
# Each teammate runs this in their own local working directory:
git remote set-url origin ssh://git@git.anguskit.com:2222/<your-team>/notes.git
git fetch origin
The target of those commands is the empty repository you create. The example name <your-team>/notes has to exist first. When the old repository's main branch is master, run git branch -m master main inside notes.git before the push, so it matches the default branch main on the new AngusGit repository. Other people's local repositories then rename the main branch too, or they clone again.
After the move, open the Branches tab and the commit history. Compare the branch count and the latest commit with the old repository. Stop the old server after they match.
Common questions
Can AngusGit still push and pull over SSH, the way a bare repository does?
Yes. Register a public key under Settings → Profile, on the SSH Keys tab, then push and pull with the SSH URL shown on the page. The page title is My Profile. AngusGit's default SSH port is 2222. The URL already includes it. The username is always git.
Can Community do what this article describes?
Yes. Repository hosting, pull requests, human review, and issue tracking are in Community. Community is open source under GPL-3.0, and you can use it freely.
What about hook scripts on the old server?
Server-side hooks do not travel with git push. A hook that blocked pushes to main becomes branch protection on AngusGit. A hook that started a build becomes a repository webhook that notifies the build system. A webhook is a notice sent to another system when something in the repository changes.
Can the bare repository and AngusGit both be used for a while?
Yes, with one agreement: push to only one side. If people push to both, the histories diverge, and joining them later is messy. Pick the cutover time. Before it, push only to the old server. After it, push only to AngusGit.
Summary
What git init --bare creates is a directory of Git data. It handles push and pull. Permission is the server account, all or nothing. When the team needs "someone looks at a change before it lands on main", you need a platform that can open pull requests. On top of the same Git push and pull, AngusGit adds browsing on the web, pull requests, line-level review, branch protection, issues, and five permission levels on each repository. An existing bare repository moves in full with git clone --bare plus git push --all and --tags. Change origin on the local repository and keep working.
Conclusion: A bare repository only offers Git push and pull through a system account. When you need pull requests, line-level review, branch protection, and five repository permission levels,
git clone --bareplusgit push --alland--tagsmoves the bare repository into AngusGit with its history intact.
Further reading
- AngusGit quick start: the first time through
- AngusGit manual: Organization and permissions (teams and repository permissions)
- Push code after you self-host Git: set up SSH or HTTPS and finish the first push
- Protect the Git main branch: turn on branch protection, then merge through a pull request
- Finish a code review in a pull request: read the diff, comment on a line, approve or request changes
- Import a Git repository: enter one source URL and get the default branch


Top comments (0)