Home > OS >  git-merge In public bare repos
git-merge In public bare repos

Time:11-24

Sites like GitHub and GitLab provide ways to merge branches directly in their web interface. Given that those sites store only bare repos, how do they perform those merges? Can the same thing be done on the command line in a bare clone? I found this as a possible answer using plumbing commands.

CodePudding user response:

Because GitHub is closed source, we can't say for sure exactly how their backend handles merge operations. However, GitLab is Open Source and we can peek at the implementation details, which have changed over time.

How GitLab does it

Today, most git-related features that are surfaced in the UI, including git merges on GitLab are handled by the gitaly component of GitLab, which interacts with the physical storage of git repositories. It primarily uses its dependent library, git2go, for performing actual git operations.

Looking closer at the source code for gitaly, the best assessment I can make is that gitaly actually does make extensive use of working trees for git operations, including for merges. Repositories and working trees are generally opened and cloned to "quarantine" directories, which are just temp directories made on-the-fly and the repository's working tree is cloned into the temp directory. (see quarantine.go#L40-58, called from merge.go#L53).

how do they perform those merges?

So, to answer your question: at least with GitLab, working trees are used for merges (among other operations) and are not carried out in bare repositories. You just don't see them because temporary directories are used before they are committed to the actual repository path.

We can perhaps assume that GitHub does something similar, but it's impossible to know for sure.

Can it be done?

Can the same thing be done on the command line in a bare clone?

You pointed to one example that seems to work without checking out a working tree? But it works by writing out the tree (using git write-tree), which on a practical level doesn't seem to have any advantage over, say cloning from the bare repo and checking out the working tree and using git operations normally. For performance (anticipating possible objections), you could use tempfs or some other memory-mapped location.

I'm also unsure that linked answer would be sufficient for carrying out various merge strategies used by git merge.

So, on a technicality, maybe? The answer you linked seems to answer that question well. On a practical level that would be useful, no, it doesn't seem so.

  • Related