kubernetes/git-sync: a sidecar that clones a repo and republishes it atomically
A sidecar app which clones a git repo and keeps it in sync with the upstream.
At a glance
- What is it?
- git-sync pulls a git repository into a local directory on a loop and flips a symlink so consumers never see a half-finished checkout. It is a Kubernetes sidecar first, and the README's contract is a symlink, not a directory of files.
- Who is it for?
- Adopt git-sync when a workload needs files from a git repository and cannot run git itself: it is a single container that needs --repo and --root, and it publishes each revision through a symlink you can read the hash from. Do not adopt it if you need to write back to the repository, if your consumer cannot follow a symlink, or if the only volume you can mount is a filesystem root, since git-sync wants an empty --root and will abort if it cannot empty it.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 64 days ago.
- What is it written in?
- Mainly Shell, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem git-sync solves: files from git without git in your app
A container image is immutable, but configuration files, dashboards, templates and static sites often live in a git repository that changes far more often than the image does. Rebuilding and redeploying the application image on every commit is one answer. Mounting a ConfigMap is another, and it falls over once the files are large or numerous. git-sync takes a third route: run a second container in the same Pod that owns a git checkout and keeps it current, while the application container only reads files.
The README describes the program plainly: it "pulls a git repository into a local directory, waits for a while, then repeats." It can pull once or on an interval, from the HEAD of a branch, from a tag, or from a specific git hash, and it only re-pulls when the referenced target has changed upstream. It speaks HTTP(S), with or without authentication, and SSH. The intended audience is anyone running Kubernetes who wants repository contents available to a process that has no git binary and no credentials of its own.
The symlink is the API: how git-sync publishes an atomic checkout
The design detail that matters most is that a git checkout is not atomic. If a reader looks at the working tree while a checkout is in progress, it can see a mixture of the old revision and the new one. git-sync avoids that by never letting consumers read the checkout directory directly.
The README states that git-sync has two required flags, --repo and --root. The --root directory is explicitly not the synced data; it holds git state and other working files, and the README warns that it may or may not respond to git commands because that is an implementation detail. Inside it, git-sync maintains a symlink, configured with the --link flag, that points at the most recently synced data. That symlink is the contract.
When the remote changes, the sequence is: fetch the new data without checking it out, create a new worktree, then change the symlink to point at the new worktree. A consumer that opens the symlink either gets the old tree or the new tree, never a partial one. The README adds a second contractual detail: the leaf component of the symlink target, what you get from basename "$(readlink <link>)", is the git hash of the synced revision. So a deployment can read the link target to learn which commit is live. Everything else about the target path is not promised. There is no no-symlink mode, so a consumer that cannot follow symlinks is out of scope.
Running git-sync in Docker and reading the first sync
The README's usage section starts by creating a directory owned by the current user for the volume, then running the container as that same UID. The two flags are --repo and --root, and --period sets the polling interval.
export DIR="/tmp/git-data"
mkdir -p $DIR
docker run -d \
-v $DIR:/tmp/git \
-u$(id -u):$(id -g) \
registry/git-sync:tag \
--repo=https://github.com/kubernetes/git-sync \
--root=/tmp/git/root \
--period=30sAfter this, $DIR contains the root directory git-sync manages, and inside it the symlink that points at the synced revision. The README then serves the content with nginx, mounting the same host directory at the web root:
docker run -d \
-p 8080:80 \
-v $DIR:/usr/share/nginx/html \
nginxNote the mismatch worth understanding before you copy this: git-sync writes into /tmp/git/root inside its container, which is a subdirectory of the mounted volume, while nginx serves the volume root. The symlink sits under the root directory, so a real consumer either reads through that path or follows the link itself. If you build the image yourself, the Makefile exposes make container with REGISTRY and VERSION variables, and accepts HTTP_PROXY, HTTPS_PROXY, GOOS and GOARCH for proxy builds and cross-compilation.
Flags over environment variables, and the empty --root requirement
Two operational constraints in the README are easy to skip and expensive to hit later.
The first is that --root must be a directory that either does not exist, or exists and is empty, or can be emptied by removing all of its contents. Git wants an empty directory. If the directory exists and is not empty, git-sync tries to remove everything inside it, because it cannot simply rm -rf the directory itself when that directory is a mounted volume. If the removal fails, git-sync aborts. The README names the problematic case directly: a volume that is the root of a filesystem, which sometimes carries metadata such as the lost+found directory on ext2, ext3 and ext4. The stated fix is to use a subdirectory of the volume as --root, which is why the example above points at /tmp/git/root rather than /tmp/git.
The second is configuration style. Most flags can be set through environment variables, but the README prefers flags, with the obvious exception of passwords, because the program can abort on an invalid flag while a misspelled environment variable is silently ignored. That is a real failure mode: a typo in a flag stops the container, a typo in an environment variable lets it run with defaults you did not intend. The README also notes that deprecated flags and variables from older majors are still accepted, but encourages using the current flags for your major version.
What git-sync does not do, and when a different tool fits better
git-sync is one-directional. The README describes pulling a remote repository into a local directory and polling for changes; nothing in it covers committing, pushing or resolving conflicts. If your workflow needs a container to write changes back to a repository, git-sync is the wrong component, and an init container running git directly, or a job that performs a commit and push, is the shape you want.
It is also not a general file synchronizer. It syncs git revisions, so the unit of change is a commit, and the polling interval is the floor on how fast a change becomes visible. The README is explicit that looking for changes periodically and transferring as little data as possible are not part of the contract, so you should not build timing guarantees on --period, --depth or --git-gc behavior.
A third boundary is the symlink itself. Because there is no no-symlink mode, an application that resolves paths once at startup, or a web server configured with a document root that will not follow links, will not see updates. Compared with mounting a ConfigMap or a Secret, git-sync gives you full repository history, worktrees and much larger payloads, at the cost of a git process and a writable volume in the Pod. Compared with an init container that runs git clone once, git-sync keeps running and republishes on change, which is the whole point of the sidecar pattern.
Licence, versions and what upgrading costs
The repository is licensed Apache-2.0, and the Makefile header carries the standard Apache boilerplate. For most users the practical consequence is that you can run and redistribute the container image and the binary under those terms, including the patent grant the licence contains. This is not legal advice; if you embed git-sync in a product, read the licence text in the repository rather than this summary.
The README opens with a version warning worth repeating: the master branch documents git-sync v4 and is described as under development, while documentation for v3 lives on the release-3.x branch. The repository also carries a v3-to-v4.md file for the migration details. The stated compatibility posture is that deprecated flags and environment variables are accepted across major versions, so an upgrade does not necessarily break a running deployment, but the README still tells users to move to the most recent flags for their major version. The last push to the repository was on 2026-07-28, and the most recent release listed is v4.7.1 from 2026-07-16. Plan upgrades around the flags you actually set: the ones documented in the v4 manual are the ones you can rely on, and the deprecated spellings are a grace period, not a target state.
Editorial conclusion
Adopt git-sync when a workload needs files from a git repository and cannot run git itself: it is a single container that needs --repo and --root, and it publishes each revision through a symlink you can read the hash from. Do not adopt it if you need to write back to the repository, if your consumer cannot follow a symlink, or if the only volume you can mount is a filesystem root, since git-sync wants an empty --root and will abort if it cannot empty it. Before rollout, verify two things against your own cluster: that the --root you mount is a subdirectory rather than a volume root, and that the leaf component of the symlink target is the git hash your deployment logic expects, because the README calls that part of the contract while the rest of the target path is an implementation detail.
Frequently asked questions
What is kubernetes/git-sync?
It is a command that pulls a remote git repository into a local directory, waits, and repeats, syncing changes as the remote repository changes. The README presents it as a sidecar container in Kubernetes that pulls files down from a repository so an application can consume them.
Is kubernetes/git-sync free?
The repository is licensed Apache-2.0, which permits use and redistribution under that licence. The README does not describe a paid tier or any hosted service.
What is the difference between git pull and git sync in kubernetes/git-sync?
git-sync is not the git pull command. It fetches the remote without checking out, creates a new worktree, and then flips a symlink to publish the new revision atomically, so consumers never see a partially constructed checkout.
How do I use kubernetes/git-sync?
Set the two required flags, --repo for the remote repository and --root for the working directory, and optionally --period for the polling interval. The README's example runs the container with a mounted volume and a period of 30s.
What does git-sync do when the remote repository changes?
It fetches the new data without checking it out, creates a new worktree, and changes the symlink configured by --link to point at that worktree. The README states the webhook or exec hook, if configured, runs after the symlink is updated.
What is the git sync command in kubernetes/git-sync?
The command is git-sync, with a required --repo for the remote repository and --root for the working directory. It is a stand-alone binary and container image, not a git subcommand.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/kubernetes-git-sync)