You Already Have a Git Server
136 comments
·October 26, 2025jonhohle
webstrand
git clone --mirror <remote>
is another good one to know, it also makes a bare repository that is an exact clone (including all branches, tags, notes, etc) of a remote repo. Unlike a normal clone that is set up for local tracking branches of the remote.It doesn't include pull requests, when cloning from github, though.
Sharlin
Git was always explicitly a decentralized, "peer to peer" version control system, as opposed to centralized ones like SVN, with nothing in the protocol itself that makes a distinction between a "server" and a "client". Using it in a centralized fashion is just a workflow that you choose to use (or, realistically, one that somebody else chose for you). Any clone of a repository can be a remote to any other clone, and you can easily have a "git server" in your local filesystem, which is a perfectly reasonable workflow in some cases.
jonhohle
This is a better summary than mine.
There was a thread not to long ago where people were conflating git with GitHub. Git is an incredible tool (after coming from SVN/CVS/p4/source safe) that stands on its own apart from hosting providers.
webstrand
It's a little more complex than that. Yes git can work in a peer-to-peer fashion, but the porcelain is definitely set up for a hub-and-spoke model, given how cloning a remote repo only gives you a partial copy of the remote history.
There's other stuff too, like git submodules can't be configured to reference another branch on the local repository and then be cloned correctly, only another remote.
jonhohle
> given how cloning a remote repo only gives you a partial copy of the remote history
When you clone you get the full history and all remote branches (by default). That’s painfully true when you have a repo with large binary blobs (and the reason git-lfs and others exist).
isaacremuant
I'd say git submodules have such an awkward UX that should probably not be used except in very rare and organized cases. I've done it before but it has to be worth it.
But I get your larger point.
thyristan
Maybe I'm too old, but are there people that really didn't know that any ssh access is sufficient for using git?
victorbjorklund
I never thought about it. If somebody had asked me, yeah. Of course it makes sense. But it's just one of those things where I haven't thought about possibility.
__MatrixMan__
I've been using git since 2007, this only dawned on me last year.
Git is especially prone to the sort of confusion where all the experts you know use it in slightly different ways so the culture is to just wing it until you're your own unique kind of wizard who can't tie his shoes because he favors sandals anyhow.
tianqi
I like this comment. Over the years I've always found that whenever I see others using git, everyone uses it in different way and even for different purposes. This has left me really confused about what is the standard practice of Git exactly.
haskellshill
> all the experts you know use it in slightly different ways
What? Knowing that a git repo is just a folder is nowhere near "expert" level. That's basic knowledge, just like knowing that the commits are nodes of a DAG. Sadly, most git users have no idea how the tool works. It's a strange situation, it'd be like if a majority of drivers didn't know how to change gears.
skydhash
The Pro Git book is available online for free
thwarted
Yes. I've been subject to claims that a single person can't start a project unless and until an official, centralized repo is setup for them. I've responded with "git init is all that is necessary to get started", but they wouldn't hear it.
t_mahmood
My way used to be in the past, put bare repos on Dropbox, clone the bare repo to a real path. Done.
That way, I
1. didn't have to worry about sync conflicts. Once complete, just push to origin 2. had my code backed up outside my computer
I can't exactly remember, if it saves space. I assumed it does, but not sure anymore. But I feel it was quite reliable.
I gave that way up with GitHub. But thinking of migrating to `Codeberg`
With `tailscale`, I feel we have so much options now, instead of putting our personal computer out on the Internet.
politelemon
Also relatively unknown: You can clone from a directory. It won't accomplish the backup feature but it's another option/feature.
null
superdisk
If you do it over NFS or whatever then you can collaborate as well.
null
dtgriscom
I actually realized this last week, and have yet to try it. Programming for almost fifty years, using Git for thirteen years, and not an idiot (although there are those who would dispute this, including at times my spouse).
kace91
I didn’t know either - or rather, I had never stopped to consider what a server needs to do to expose a git repo.
But more importantly, I’m not sure why I would want to deploy something by pushing changes to the server. In my mental model the repo contains the SOT, and whatever’s running on the server is ephemeral, so I don’t want to mix those two things.
I guess it’s more comfortable than scp-ing individual files for a hotfix, but how does this beat pushing to the SOT, sshing into the server and pulling changes from there?
skydhash
There's a lot of configuration possible due to the fact that git is decentralized. I have a copy on my computer which is where I do work. Another on a vps for backup. Then one on the app server which only tracks the `prod` branch. The latter is actually bare, but there's a worktree for the app itself. The worktree is updated via a post-receive hook and I deploy change via a simple `git push server prod`
isodev
I imagine larger part of the developer community does not, in fact, know that GitHub is not git and one can get everything they need without feeding their code to Microsoft's AI empire. Just another "Embrace, extend, and extinguish"
seba_dos1
Just make the repository on the server side bare and you won't have to worry about checked out branches or renaming ".git" directory.
cl3misch
> This is a great way to [...] work on server-side files without laggy typing or manual copying
This is the usecase mentioned in the article and it wouldn't work with a bare repo. But if the server your SSH'ing to is just a central point to sync code across machines, then you're right: multiple hoops mentioned in the article are solved by having the central repo bare.
liveoneggs
yeah it seems odd that they don't just have remote> $HOME/repos/foo.git and then clone from there locally and remotely
seba_dos1
FWIW a single user working on a remote versioned directory is indeed a reasonable use-case for receive.denyCurrentBranch=updateInstead, but IMO the article should have made it clear that it's not necessarily a good choice in general.
eqvinox
git clone ssh://username@hostname/path/to/repo
this is equivalent to: git clone username@hostname:path/to/repo
and if your usernames match between local and remote: git clone hostname:path/to/repo
(if the path has no leading /, it is relative to your home directory on the remote)ninkendo
I remember the first time I tried git, circa 2006, and the first 3 commands I tried were:
git init
git commit -am Initial\ commit
git clone . ssh://server/path/to/repo
And it didn’t work. You have to ssh to the remote server and “git init” on a path first. How uncivilized.Bitkeeper and a few other contemporaries would let you just push to a remote path that doesn’t exist yet and it’d create it. Maybe git added this since then, but at the time it seemed like a huge omission to me.
seba_dos1
Hah, you made me check whether clone's second argument can be a URL. But no, it's explicitly "<directory>", so it can't be used as a equivalent of "git push --mirror" :)
bitbasher
I have been doing this for many years.
If you want a public facing "read only" ui to public repositories you can use cgit (https://git.zx2c4.com/cgit/about/) to expose them. That will enable others to git clone without using ssh.
I keep my private repositories private and expose a few public ones using cgit.
null
binary132
This is definitely nice but it doesn’t really support the full range of features of Git, because for example submodules cannot be local references. It’s really just easier to set up gitolite and use that in almost the same exact way but it’s much better.
tangotaylor
Beware of using this to publish static sites: you can accidentally expose your .git directory to the public internet.
I got pwned this way before (by a pentester fortunately). I had to configure Apache to block the .git directory.
timmg
There was a brief period when Google Cloud had support for hosting git on a pay-per-use basis. (I think it was called Google Cloud Repositories.) It had a clunky but usable UI.
I really preferred the idea of just paying for what I used -- rather than being on a "freemium" model with GitHub.
But -- as many things with Google -- it was shutdown. Probably because most other people do prefer the freemium model.
I wonder if this kind of thing will come back in style someday, or if we are stuck with freemium/pro "tiers" for everything.
null
singpolyma3
One note, xcode and maybe some other clients can't use http "dumb mode". Smart mode is not hard to set up, but it's a few lines of server config more than this hook.
TIL about the update options for checked out branch. In practise though usually you want just the .git "bare" folder on server
saagarjha
I feel like this is a bug that Xcode should fix
I feel like something was lost along the way.
will give you a git repo without a working set (just the contents typically in the .git directory). This allows you to create things like `foo.git` instead of `foo/.git`.“origin” is also just the default name for the cloned remote. It could be called anything, and you can have as many remotes as you’d like. You can even namespace where you push back to the same remotes by changing fetch and push paths. At one company it was common to push back to `$user/$feature` to avoid polluting the root namespace with personal branches. It was also common to have `backup/$user` for pushing having a backup of an entire local repo.
I often add a hostname namespace when I’m working from multiple hosts and then push between them directly to another instead of going back to a central server.
For a small static site repo that has documents and server config, I have a remote like:
So I can push from my computer directly to that server, but those branches won’t overwrite the server’s branches. It acts like a reverse `git pull`, which can be useful for firewalls and other situations where my laptop wouldn’t be routable.