Skip to content

Add docs on symlink and "the contract" #916

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,41 @@ git-sync can also be configured to make a webhook call or exec a command upon
successful git repo synchronization. The call is made after the symlink is
updated.

## What it produces and why - the contract

git-sync has two required flags: `--repo`, which specifies which remote git
repo to sync, and `--root` which specifies a working directory for git-sync,
which presents an "API" of sorts.

The `--root` directory is _not_ the synced data.

Inside the `--root` directory git-sync stores the synced git state and other
things. That directory may or may not respond to git commands - it's an
implementation detail.

One of the things in that directory is a symlink (see the `--link` flag) to the
most recently synced data. This is how the data is expected to be consumed,
and is considered to be the "contract" between git-sync and consumers. The
exact target of that symlink is an implementation detail, but the leaf
component of the target (i.e. `basename "$(readlink <link>)"`) is the git hash
of the synced revision. This is also part of the contract.

git-sync looks for changes in the remote repo periodically (see the `--period`
flag) and will attempt to transfer as little data as possible and use as little
disk space as possible (see the `--depth` and `--git-gc` flags), but this is
not part of the contract.

### Why the symlink?

git checkouts are not "atomic" operations. If you look at the repository while
a checkout is happening, you might see data that is neither exactly the old
revision nor the new. git-sync "publishes" updates via the symlink to present
an atomic interface to consumers. When the remote repo has changed, git-sync
will fetch the data _without_ checking it out, then create a new worktree, then
change the symlink to point to that new worktree.

git-sync does not currently have a no-symlink mode.

## Major update: v3.x -> v4.x

git-sync has undergone many significant changes between v3.x and v4.x. [See
Expand Down Expand Up @@ -139,6 +174,38 @@ DESCRIPTION
git-sync can also be configured to make a webhook call upon successful git
repo synchronization. The call is made after the symlink is updated.

CONTRACT

git-sync has two required flags:
--repo: specifies which remote git repo to sync
--root: specifies a working directory for git-sync

The root directory is not the synced data.

Inside the root directory, git-sync stores the synced git state and other
things. That directory may or may not respond to git commands - it's an
implementation detail.

One of the things in that directory is a symlink (see the --link flag) to
the most recently synced data. This is how the data is expected to be
consumed, and is considered to be the "contract" between git-sync and
consumers. The exact target of that symlink is an implementation detail,
but the leaf component of the target (i.e. basename "$(readlink <link>)")
is the git hash of the synced revision. This is also part of the contract.

Why the symlink? git checkouts are not "atomic" operations. If you look
at the repository while a checkout is happening, you might see data that is
neither exactly the old revision nor the new. git-sync "publishes" updates
via the symlink to present an atomic interface to consumers. When the
remote repo has changed, git-sync will fetch the data _without_ checking it
out, then create a new worktree, then change the symlink to point to that
new worktree.

git-sync looks for changes in the remote repo periodically (see the
--period flag) and will attempt to transfer as little data as possible and
use as little disk space as possible (see the --depth and --git-gc flags),
but this is not part of the contract.

OPTIONS

Many options can be specified as either a commandline flag or an environment
Expand Down
32 changes: 32 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2169,6 +2169,38 @@ DESCRIPTION
git-sync can also be configured to make a webhook call upon successful git
repo synchronization. The call is made after the symlink is updated.

CONTRACT

git-sync has two required flags:
--repo: specifies which remote git repo to sync
--root: specifies a working directory for git-sync

The root directory is not the synced data.

Inside the root directory, git-sync stores the synced git state and other
things. That directory may or may not respond to git commands - it's an
implementation detail.

One of the things in that directory is a symlink (see the --link flag) to
the most recently synced data. This is how the data is expected to be
consumed, and is considered to be the "contract" between git-sync and
consumers. The exact target of that symlink is an implementation detail,
but the leaf component of the target (i.e. basename "$(readlink <link>)")
is the git hash of the synced revision. This is also part of the contract.

Why the symlink? git checkouts are not "atomic" operations. If you look
at the repository while a checkout is happening, you might see data that is
neither exactly the old revision nor the new. git-sync "publishes" updates
via the symlink to present an atomic interface to consumers. When the
remote repo has changed, git-sync will fetch the data _without_ checking it
out, then create a new worktree, then change the symlink to point to that
new worktree.

git-sync looks for changes in the remote repo periodically (see the
--period flag) and will attempt to transfer as little data as possible and
use as little disk space as possible (see the --depth and --git-gc flags),
but this is not part of the contract.

OPTIONS

Many options can be specified as either a commandline flag or an environment
Expand Down
Loading