public inbox for git@vger.kernel.org
 help / color / mirror / Atom feed
From: Karthik Nayak <karthik.188@gmail.com>
To: git@vger.kernel.org
Cc: "Karthik Nayak" <karthik.188@gmail.com>,
	gitster@pobox.com, ps@pks.im, toon@iotcl.com,
	"Jean-Noël Avila" <jn.avila@free.fr>
Subject: [PATCH v7 0/6] refs: allow setting the reference directory
Date: Thu, 19 Feb 2026 10:38:19 +0100	[thread overview]
Message-ID: <20260219-kn-alternate-ref-dir-v7-0-16f27860dbdf@gmail.com> (raw)
In-Reply-To: <20251119-kn-alternate-ref-dir-v1-0-4cf4a94c8bed@gmail.com>

While Git allows users to select different reference backends, unlike
with objects, there is no flexibility in selecting the reference
directory. Currently, the reference format is obtained from the config
of the repository and the reference directory is set to the $GIT_DIR.

This patch extends the config 'extensions.refStorage' to take in
multiple forms of inputs:

  - A format name alone (e.g., `reftable` or `files`).

  - A URI format `<format>://<payload>` explicitly specifies both the
    format and payload (e.g., `reftable:///foo/bar`).

We also add in a new ENV variable GIT_REFERENCE_BACKEND which can be
used to override the config.

One use case for this is migration between different backends. On the
server side, migrating from the files backend to the newly introduced
reftable backend can be achieved by running 'git refs migrate'. However,
for large repositories with millions of references, this migration can
take from seconds to minutes.

For some background, at GitLab, the criteria for our migration was to
reduce the downtime of the migrate ideally to zero. So running 'git refs
migrate --ref-format=reftable' by itself wouldn't work, since it scales
with the number of references and we have repos with millions of
references, so we need to migrate without loosing any information. We
came up with the following plan:

  1. Run git-pack-refs(1) and note timestamp of the generated packed-refs
     file.
  2. Run git refs migrate –dry-run.
  3. If there are no ongoing reference requests (read/write)
     a. Lock the repository by blocking incoming requests (done on a
        layer above git, in Gitaly [1]).
     b. If the timestamp of the packed-refs file has changed, unlock
        the repo and repeat from step 1.
     c. Apply all the loose refs to the dry-run reftable folder (this
        requires support in Git to write refs to arbitrary folder).
     d. Move the reftable dry-run folder into the GIT_DIR.
     e. Swap the repo config
     f. Unlock repo access

Using such a route, scales much better since we only have to worry about
blocking the repository by O(ref written between #1 and #3a) and not
O(refs in repo). But for doing so, we need to be able to write to a
arbitrary reference backend + path. This is to add the missing
references to the dry-run reftable folder. This series, achieves that.

Since there was a long gap between v3 <> v4, the version 4 onward is
based on top of 2258446484 (RelNotes: correct "fast-import" option name,
2026-01-30).

[1]: https://gitlab.com/gitlab-org/gitaly

---
Changes in v7:
- Add more details in the commit messages.
- Cleanup some whitespace.
- Reorder the commits to be group related changes together.
- Add checks for stubs in the tests when creating new repos.
- Link to v6: https://patch.msgid.link/20260214-kn-alternate-ref-dir-v6-0-86a82c77cf59@gmail.com

Changes in v6:
- The biggest change in this version is that we now support using the
  environment variable with 'git-clone(1)' and 'git-init(1)'. In such
  situations, the alternate reference directory is created and the
  config is added to the repository.
- Add a new commit which moves stub creation/removal to the generic
  layer.
- Cleanup logic flow in `refs_compute_filesystem_location()`.
- Add more tests for usage with 'git-clone(1)', 'git-init(1)' and
  migration of repositories using alternate refs backend.
- Fixup documentation, commit messages and typos.
- Link to v5: https://patch.msgid.link/20260209-kn-alternate-ref-dir-v5-0-740899834ceb@gmail.com

Changes in v5:
- Moved around the commits, to ensure that the code to handle the config
  in the backend is first. Previously, we added the config first, which
  meant the commit allowed users to provide a URI but it was simply
  ignore.
- Fix typos and grammar and rename variables.
- Clean up the description and documentation to actually specify
  protocol over location.
- Avoid an extra memory allocation by detaching the strbuf value.
- Link to v4: https://patch.msgid.link/20260202-kn-alternate-ref-dir-v4-0-3b30430411e3@gmail.com

Changes in v4:
- Mostly re-wrote the code to also support worktree. Now, the existing
  backends will store worktree references in 'ref_dir/worktrees/wt_id'
  and add corresponding stubs in 'git_dir/worktrees/wt_id'.
- We also support relative paths in the reference directories. These
  relative paths are resolved relative to the GIT_DIR.
- Link to v3: https://patch.msgid.link/20251201-kn-alternate-ref-dir-v3-0-c11b946bc2fa@gmail.com

Changes in v3:
- Cleanup some stale code which wasn't removed.
- Localize strings which will be output to the user.
- Remove additional defensive checks which are not needed.
- Link to v2: https://patch.msgid.link/20251126-kn-alternate-ref-dir-v2-0-8b9f6f18f635@gmail.com

Changes in v2:
- Added more clarification and proper intent in the cover message.
- Changed the format from '<ref_backend>://<path>' to
  `<ref_backend>://<URI-for-resource>` as it much clearer.
- Added logic to check for the '//' in the provided URI and a test for
  the same.
- In the tests:
  - Use test_must_fail() instead of ! git
  - Fix looped tests not using the variables correctly and ensure that
    the test description is correct.
- Link to v1: https://patch.msgid.link/20251119-kn-alternate-ref-dir-v1-0-4cf4a94c8bed@gmail.com

---
 Documentation/config/extensions.adoc |  16 +-
 Documentation/git.adoc               |   5 +
 builtin/clone.c                      |   9 +-
 builtin/worktree.c                   |  34 +++++
 environment.h                        |   1 +
 refs.c                               | 126 +++++++++++++++-
 refs.h                               |  13 ++
 refs/files-backend.c                 |  23 ++-
 refs/packed-backend.c                |   5 +
 refs/packed-backend.h                |   1 +
 refs/refs-internal.h                 |  14 ++
 refs/reftable-backend.c              |  61 ++------
 repository.c                         |   9 +-
 repository.h                         |   8 +-
 setup.c                              |  96 ++++++++++--
 setup.h                              |   4 +-
 t/meson.build                        |   1 +
 t/t1423-ref-backend.sh               | 282 +++++++++++++++++++++++++++++++++++
 18 files changed, 627 insertions(+), 81 deletions(-)

Karthik Nayak (6):
      setup: don't modify repo in `create_reference_database()`
      refs: extract out `refs_create_refdir_stubs()`
      refs: move out stub modification to generic layer
      refs: receive and use the reference storage payload
      refs: allow reference location in refstorage config
      refs: add GIT_REFERENCE_BACKEND to specify reference backend

Range-diff versus v6:

1:  bbc8d0678c ! 1:  d958e2597e setup: don't modify repo in `create_reference_database()`
    @@ Commit message
         dynamically allocated strings, where we would free/allocate the same
         string back into `the_repostiory`.
     
    -    To avoid all this confusion, clean up the function to longer take in and
    -    set the repo's reference storage format.
    +    To avoid all this confusion, clean up the function to no longer take in
    +    and set the repo's reference storage format.
     
         Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
     
2:  4f868d2f4c = 2:  f6583f00b1 refs: extract out `refs_create_refdir_stubs()`
4:  6e4c372402 ! 3:  bffb0ede9d refs: move out stub modification to generic layer
    @@ Commit message
         ensure that the directory can be recognized as a Git repository. This is
         done by calling `refs_create_refdir_stubs()`. Move this to the generic
         layer as this is needed for all backends excluding from the files
    -    backends. In an upcoming commit, we'll also need to extend this logic to
    -    create stubs when using alternate reference directories.
    +    backends. In an upcoming commit where we introduce alternate reference
    +    backend locations, we'll have to also create stubs in the $GIT_DIR
    +    irrespective of the backend being used. This commit builds the base to
    +    add that logic.
     
         Similarly, move the logic for deletion of stubs to the generic layer.
         The files backend recursively calls the remove function of the
    @@ refs.c: void refs_create_refdir_stubs(struct repository *repo, const char *refdi
     -	return refs->be->remove_on_disk(refs, err);
     +	int ret = refs->be->remove_on_disk(refs, err);
     +
    -+	if (!ret) {
    -+		enum ref_storage_format format = ref_storage_format_by_name(refs->be->name);
    ++	if (!ret &&
    ++	    ref_storage_format_by_name(refs->be->name) != REF_STORAGE_FORMAT_FILES) {
     +		struct strbuf sb = STRBUF_INIT;
     +
    -+		/* Backends apart from the files backend create stubs. */
    -+		if (format == REF_STORAGE_FORMAT_FILES)
    -+			return ret;
    -+
     +		strbuf_addf(&sb, "%s/HEAD", refs->gitdir);
     +		if (unlink(sb.buf) < 0) {
     +			strbuf_addf(err, "could not delete stub HEAD: %s",
3:  363e36875b ! 4:  a7d4c22861 refs: receive and use the reference storage payload
    @@ refs.c: const char *ref_transaction_error_msg(enum ref_transaction_error err)
     +	if (*is_worktree) {
     +		const char *wt_id = strrchr(gitdir, '/');
     +		if (!wt_id)
    -+			BUG("worktree path does not contain slash ");
    ++			BUG("worktree path does not contain slash");
     +		strbuf_addf(refdir, "/worktrees/%s", wt_id + 1);
     +	}
     +
5:  da04b77ed6 = 5:  dca8fc6b77 refs: allow reference location in refstorage config
6:  78b9589da7 ! 6:  d515ab78e3 refs: add GIT_REFERENCE_BACKEND to specify reference backend
    @@ refs.c: int ref_store_create_on_disk(struct ref_store *refs, int flags, struct s
      	}
      
      	return ret;
    -+
    - }
    - 
    - int ref_store_remove_on_disk(struct ref_store *refs, struct strbuf *err)
     @@ refs.c: int ref_store_remove_on_disk(struct ref_store *refs, struct strbuf *err)
    - 		if (format == REF_STORAGE_FORMAT_FILES)
    - 			return ret;
    + {
    + 	int ret = refs->be->remove_on_disk(refs, err);
    + 
    +-	if (!ret &&
    +-	    ref_storage_format_by_name(refs->be->name) != REF_STORAGE_FORMAT_FILES) {
    ++	if (!ret) {
    ++		enum ref_storage_format format = ref_storage_format_by_name(refs->be->name);
    + 		struct strbuf sb = STRBUF_INIT;
      
    ++		/* Backends apart from the files backend create stubs. */
    ++		if (format == REF_STORAGE_FORMAT_FILES)
    ++			return ret;
    ++
     +		/* Alternate refs backend require stubs in the gitdir. */
     +		if (refs->repo->ref_storage_payload)
     +			return ret;
    @@ t/t1423-ref-backend.sh: run_with_uri() {
      }
      
     -test_expect_success 'URI is invalid' '
    ++# Verify that the expected files are present in the gitdir and the refsdir.
    ++# Usage: verify_files_exist <gitdir> <refdir>
    ++#   <gitdir> is the path for the gitdir.
    ++#   <refdir> is the path for the refdir.
    ++verify_files_exist() {
    ++	gitdir=$1 &&
    ++	refdir=$2 &&
    ++
    ++	# verify that the stubs were added to the $GITDIR.
    ++	cat $gitdir/refs/heads >actual &&
    ++	echo "repository uses alternate refs storage" >expect &&
    ++	test_cmp expect actual &&
    ++	cat $gitdir/HEAD >actual &&
    ++	echo "ref: refs/heads/.invalid" >expect &&
    ++	test_cmp expect actual
    ++
    ++	# verify that backend specific files exist.
    ++	case "$GIT_DEFAULT_REF_FORMAT" in
    ++	files)
    ++		test_path_is_dir $refdir/refs/heads &&
    ++		test_path_is_file $refdir/HEAD;;
    ++	reftable)
    ++		test_path_is_dir $refdir/reftable &&
    ++		test_path_is_file $refdir/reftable/tables.list;;
    ++	*)
    ++		BUG "unhandled ref format $GIT_DEFAULT_REF_FORMAT";;
    ++	esac
    ++}
    ++
     +methods="config env"
     +for method in $methods
     +do
    @@ t/t1423-ref-backend.sh: do
     +	mkdir refdir &&
     +	BACKEND="$(test_detect_ref_format)://$(pwd)/refdir" &&
     +	GIT_REFERENCE_BACKEND=$BACKEND git init repo &&
    ++	verify_files_exist repo/.git refdir &&
     +	(
     +		cd repo &&
     +
    @@ t/t1423-ref-backend.sh: do
     +	echo $BACKEND >actual &&
     +	test_cmp expect actual &&
     +
    ++	verify_files_exist repo/.git refdir &&
    ++
     +	git -C source for-each-ref refs/tags/ >expect &&
     +	git -C repo for-each-ref refs/tags/ >actual &&
     +	test_cmp expect actual


base-commit: 22584464849815268419fd9d2eba307362360db1
change-id: 20251105-kn-alternate-ref-dir-3e572e8cd0ef

Thanks
- Karthik


  parent reply	other threads:[~2026-02-19  9:38 UTC|newest]

Thread overview: 131+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-11-19 21:48 [PATCH 0/2] refs: allow setting the reference directory Karthik Nayak
2025-11-19 21:48 ` [PATCH 1/2] refs: support obtaining ref_store for given dir Karthik Nayak
2025-11-20 19:05   ` Justin Tobler
2025-11-21 11:18     ` Karthik Nayak
2025-11-19 21:48 ` [PATCH 2/2] refs: add GIT_REF_URI to specify reference backend and directory Karthik Nayak
2025-11-19 22:13   ` Eric Sunshine
2025-11-19 23:01     ` Karthik Nayak
2025-11-20 10:00   ` Jean-Noël Avila
2025-11-21 11:21     ` Karthik Nayak
2025-11-20 19:38   ` Justin Tobler
2025-11-24 13:23     ` Karthik Nayak
2025-11-21 13:42   ` Toon Claes
2025-11-21 16:07     ` Junio C Hamano
2025-11-24 13:25       ` Karthik Nayak
2025-11-26 13:11         ` Toon Claes
2025-11-24 13:26     ` Karthik Nayak
2025-12-01 13:28   ` Patrick Steinhardt
2025-12-02 22:21     ` Karthik Nayak
2025-11-23  4:29 ` [PATCH 0/2] refs: allow setting the reference directory Junio C Hamano
2025-12-01 13:19   ` Patrick Steinhardt
2025-12-02 10:25     ` Junio C Hamano
2025-12-02 15:29     ` Karthik Nayak
2025-11-26 11:11 ` [PATCH v2 " Karthik Nayak
2025-11-26 11:12   ` [PATCH v2 1/2] refs: support obtaining ref_store for given dir Karthik Nayak
2025-11-26 15:16     ` Junio C Hamano
2025-11-26 11:12   ` [PATCH v2 2/2] refs: add GIT_REF_URI to specify reference backend and directory Karthik Nayak
2025-11-26 16:17     ` Junio C Hamano
2025-11-27 14:52       ` Karthik Nayak
2025-11-27 20:02         ` Junio C Hamano
2025-11-27 21:45           ` Karthik Nayak
2025-12-01 11:24 ` [PATCH v3 0/2] refs: allow setting the reference directory Karthik Nayak
2025-12-01 11:24   ` [PATCH v3 1/2] refs: support obtaining ref_store for given dir Karthik Nayak
2025-12-01 11:24   ` [PATCH v3 2/2] refs: add GIT_REF_URI to specify reference backend and directory Karthik Nayak
2026-01-05 15:13   ` [PATCH v3 0/2] refs: allow setting the reference directory Patrick Steinhardt
2026-01-05 20:13     ` Karthik Nayak
2026-01-20 21:03       ` Junio C Hamano
2026-01-22 12:36         ` Karthik Nayak
2026-02-02 12:26 ` [PATCH v4 0/4] " Karthik Nayak
2026-02-02 12:26   ` [PATCH v4 1/4] refs: allow reference location in refstorage config Karthik Nayak
2026-02-06 14:33     ` Patrick Steinhardt
2026-02-09 12:25       ` Karthik Nayak
2026-02-02 12:26   ` [PATCH v4 2/4] refs: extract out `refs_create_refdir_stubs()` Karthik Nayak
2026-02-06 14:33     ` Patrick Steinhardt
2026-02-09 11:21       ` Karthik Nayak
2026-02-02 12:26   ` [PATCH v4 3/4] refs: parse and use the reference storage payload Karthik Nayak
2026-02-06 14:33     ` Patrick Steinhardt
2026-02-09 12:52       ` Karthik Nayak
2026-02-02 12:26   ` [PATCH v4 4/4] refs: add GIT_REFERENCE_BACKEND to specify reference backend Karthik Nayak
2026-02-06 14:33     ` Patrick Steinhardt
2026-02-09 12:53       ` Karthik Nayak
2026-02-06 14:33   ` [PATCH v4 0/4] refs: allow setting the reference directory Patrick Steinhardt
2026-02-06 17:50     ` Junio C Hamano
2026-02-09 12:53     ` Karthik Nayak
2026-02-09 15:58 ` [PATCH v5 " Karthik Nayak
2026-02-09 15:58   ` [PATCH v5 1/4] refs: extract out `refs_create_refdir_stubs()` Karthik Nayak
2026-02-09 15:58   ` [PATCH v5 2/4] refs: forward and use the reference storage payload Karthik Nayak
2026-02-09 16:34     ` Patrick Steinhardt
2026-02-10 10:09       ` Karthik Nayak
2026-02-10 22:46     ` Jeff King
2026-02-13 14:45       ` Karthik Nayak
2026-02-15  9:12         ` Jeff King
2026-02-09 15:58   ` [PATCH v5 3/4] refs: allow reference location in refstorage config Karthik Nayak
2026-02-09 16:34     ` Patrick Steinhardt
2026-02-10 13:02       ` Karthik Nayak
2026-02-10 22:44     ` Jeff King
2026-02-11 10:27       ` Karthik Nayak
2026-02-09 15:58   ` [PATCH v5 4/4] refs: add GIT_REFERENCE_BACKEND to specify reference backend Karthik Nayak
2026-02-09 16:34   ` [PATCH v5 0/4] refs: allow setting the reference directory Patrick Steinhardt
2026-02-09 18:02   ` Junio C Hamano
2026-02-10 13:02     ` Karthik Nayak
2026-02-10 15:35       ` Junio C Hamano
2026-02-14 22:34 ` [PATCH v6 0/6] " Karthik Nayak
2026-02-14 22:34   ` [PATCH v6 1/6] setup: don't modify repo in `create_reference_database()` Karthik Nayak
2026-02-17  7:24     ` Patrick Steinhardt
2026-02-17  9:15       ` Karthik Nayak
2026-02-14 22:34   ` [PATCH v6 2/6] refs: extract out `refs_create_refdir_stubs()` Karthik Nayak
2026-02-14 22:34   ` [PATCH v6 3/6] refs: receive and use the reference storage payload Karthik Nayak
2026-02-17  7:24     ` Patrick Steinhardt
2026-02-17  9:16       ` Karthik Nayak
2026-02-14 22:34   ` [PATCH v6 4/6] refs: move out stub modification to generic layer Karthik Nayak
2026-02-17  7:24     ` Patrick Steinhardt
2026-02-17  9:29       ` Karthik Nayak
2026-02-18 14:21         ` Toon Claes
2026-02-19  9:31           ` Karthik Nayak
2026-02-14 22:34   ` [PATCH v6 5/6] refs: allow reference location in refstorage config Karthik Nayak
2026-02-14 22:34   ` [PATCH v6 6/6] refs: add GIT_REFERENCE_BACKEND to specify reference backend Karthik Nayak
2026-02-17  7:24     ` Patrick Steinhardt
2026-02-17  9:32       ` Karthik Nayak
2026-02-17 10:15         ` Patrick Steinhardt
2026-02-18 15:27     ` Toon Claes
2026-02-19  9:35       ` Karthik Nayak
2026-02-19  9:38 ` Karthik Nayak [this message]
2026-02-19  9:38   ` [PATCH v7 1/6] setup: don't modify repo in `create_reference_database()` Karthik Nayak
2026-02-19  9:38   ` [PATCH v7 2/6] refs: extract out `refs_create_refdir_stubs()` Karthik Nayak
2026-02-19  9:38   ` [PATCH v7 3/6] refs: move out stub modification to generic layer Karthik Nayak
2026-02-20 15:21     ` Toon Claes
2026-02-19  9:38   ` [PATCH v7 4/6] refs: receive and use the reference storage payload Karthik Nayak
2026-02-20 15:32     ` Toon Claes
2026-02-22 20:12       ` Karthik Nayak
2026-02-19  9:38   ` [PATCH v7 5/6] refs: allow reference location in refstorage config Karthik Nayak
2026-02-20 15:36     ` Toon Claes
2026-02-20 16:53       ` Junio C Hamano
2026-02-22 20:15         ` Karthik Nayak
2026-02-19  9:38   ` [PATCH v7 6/6] refs: add GIT_REFERENCE_BACKEND to specify reference backend Karthik Nayak
2026-02-19 15:35     ` Patrick Steinhardt
2026-02-20  9:15       ` Karthik Nayak
2026-02-23  8:01 ` [PATCH v8 0/6] refs: allow setting the reference directory Karthik Nayak
2026-02-23  8:01   ` [PATCH v8 1/6] setup: don't modify repo in `create_reference_database()` Karthik Nayak
2026-02-23  8:01   ` [PATCH v8 2/6] refs: extract out `refs_create_refdir_stubs()` Karthik Nayak
2026-02-23  8:01   ` [PATCH v8 3/6] refs: move out stub modification to generic layer Karthik Nayak
2026-02-23  8:01   ` [PATCH v8 4/6] refs: receive and use the reference storage payload Karthik Nayak
2026-02-23  8:01   ` [PATCH v8 5/6] refs: allow reference location in refstorage config Karthik Nayak
2026-02-23 17:43     ` Kristoffer Haugsbakk
2026-02-24 13:09       ` Karthik Nayak
2026-02-24 13:20         ` Kristoffer Haugsbakk
2026-02-24 15:05           ` Karthik Nayak
2026-02-23  8:01   ` [PATCH v8 6/6] refs: add GIT_REFERENCE_BACKEND to specify reference backend Karthik Nayak
2026-02-25  8:50     ` Toon Claes
2026-02-25  9:41       ` Karthik Nayak
2026-02-23 10:54   ` [PATCH v8 0/6] refs: allow setting the reference directory Patrick Steinhardt
2026-02-23 13:37     ` Karthik Nayak
2026-02-23 20:05       ` Junio C Hamano
2026-02-25  9:42         ` Karthik Nayak
2026-02-25  9:40 ` [PATCH v9 " Karthik Nayak
2026-02-25  9:40   ` [PATCH v9 1/6] setup: don't modify repo in `create_reference_database()` Karthik Nayak
2026-02-25  9:40   ` [PATCH v9 2/6] refs: extract out `refs_create_refdir_stubs()` Karthik Nayak
2026-02-25  9:40   ` [PATCH v9 3/6] refs: move out stub modification to generic layer Karthik Nayak
2026-02-25  9:40   ` [PATCH v9 4/6] refs: receive and use the reference storage payload Karthik Nayak
2026-02-25  9:40   ` [PATCH v9 5/6] refs: allow reference location in refstorage config Karthik Nayak
2026-02-25 17:42     ` Junio C Hamano
2026-02-25  9:40   ` [PATCH v9 6/6] refs: add GIT_REFERENCE_BACKEND to specify reference backend Karthik Nayak

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260219-kn-alternate-ref-dir-v7-0-16f27860dbdf@gmail.com \
    --to=karthik.188@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=jn.avila@free.fr \
    --cc=ps@pks.im \
    --cc=toon@iotcl.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox