Subject: Re: [PATCH v2 1/3] Documentation/git-bundle.txt: mention full backup example

From: Junio C Hamano <[email-masked]>
Date: Fri, 01 Nov 2024 18:27:24 -0700

[email-masked] writes:

> From: Kristoffer Haugsbakk <[email-masked]>
>
> Tell the user how to make a full backup of the repository right at the
> start of the doc.
>
> This is a requested use-case.[1]  But the doc is a bit unassuming
> about it:
>
>   “ If you want to match `git clone --mirror`, which would include your
>     refs such as `refs/remotes/*`, use `--all`.

What's the open fancy quote followed by a SP doing there, apparently
without the matching closing one?  Can we replace it with a SP?

> The user cannot be expected to formulate “I want a full backup” as “I
> want to match `git clone --mirror`” for a bundle file or something.
> Let’s drop this mention of `--all` later in the doc and frontload it.

> diff --git a/Documentation/git-bundle.txt b/Documentation/git-bundle.txt
> index 3ab42a19cae..0fa181c749d 100644
> --- a/Documentation/git-bundle.txt
> +++ b/Documentation/git-bundle.txt
> @@ -23,8 +23,8 @@ the "offline" transfer of Git objects without an active "server"
>  sitting on the other side of the network connection.
>  
>  They can be used to create both incremental and full backups of a
> -repository, and to relay the state of the references in one repository
> -to another.
> +repository (`git bundle create <file> --all`), and to relay the state of
> +the references in one repository to another.

In the new construction, it is unclear if the new command line
example is about making a "full backup" and not "incremental", or it
applies to both.  I am not sure if this, especially with the removal
of "--all" from the later section, is an improvement.  Let me try if
I can come up with a better version by elaborating the later section
without touching this part.

This is not a new issue, but naïvely, one would expect "full backup"
to allow one to recover lost .git/config entries.  We should tighten
the phrasing for "backups of a repository" to avoid such misleading
false promises.  As it is the primary motivation of this series to
clarify how you would use the command for "full backup", I think
this point is worth tackling as part of this series.

This also is not a new issue, but the dashed-option "--all" after
"<file>" is an oddball from "git help cli"'s point of view.  It
perfectly fits within the SYNOPSIS for this command in that "--all"
is merely a form of valid arguments you can give to "git rev-list",
so I do not see anything that needs to be done on this point, though.

So, here is my attempt.

 Documentation/git-bundle.txt | 39 +++++++++++++++++++++++++++++----------
 1 file changed, 29 insertions(+), 10 deletions(-)

diff --git c/Documentation/git-bundle.txt w/Documentation/git-bundle.txt
index 3ab42a19ca..633c99c8b2 100644
--- c/Documentation/git-bundle.txt
+++ w/Documentation/git-bundle.txt
@@ -22,9 +22,10 @@ Create, unpack, and manipulate "bundle" files. Bundles are used for
 the "offline" transfer of Git objects without an active "server"
 sitting on the other side of the network connection.
 
-They can be used to create both incremental and full backups of a
-repository, and to relay the state of the references in one repository
-to another.
+They can be used to create both incremental and full backups of
+objects and refs in a repository.  They can be used to transfer the
+state of the references to another repository, together with objects
+these references point at.
 
 Git commands that fetch or otherwise "read" via protocols such as
 `ssh://` and `https://` can also operate on bundle files. It is
@@ -176,7 +177,7 @@ OBJECT PREREQUISITES
 When creating bundles it is possible to create a self-contained bundle
 that can be unbundled in a repository with no common history, as well
 as providing negative revisions to exclude objects needed in the
-earlier parts of the history.
+earlier parts of the history.  This is like taking a "full backup".
 
 Feeding a revision such as `new` to `git bundle create` will create a
 bundle file that contains all the objects reachable from the revision
@@ -192,9 +193,11 @@ will require the revision `old` (and any objects reachable from it)
 to exist for the bundle to be "unbundle"-able:
 
 ----------------
-$ git bundle create full.bundle old..new
+$ git bundle create incremental.bundle old..new
 ----------------
 
+Such a bundle file is like an "incremental backup".
+
 A self-contained bundle without any prerequisites can be extracted
 into anywhere, even into an empty repository, or be cloned from
 (i.e., `new`, but not `old..new`).
@@ -203,11 +206,27 @@ It is okay to err on the side of caution, causing the bundle file
 to contain objects already in the destination, as these are ignored
 when unpacking at the destination.
 
-If you want to match `git clone --mirror`, which would include your
-refs such as `refs/remotes/*`, use `--all`.
-If you want to provide the same set of refs that a clone directly
-from the source repository would get, use `--branches --tags` for
-the `<git-rev-list-args>`.
+If you want to prepare a bundle from which you can "git clone" as if
+you were cloning from the repository, you can use `--branches
+--tags` for the `<git-rev-list-args>`, as "git clone" transfers only
+these two kinds of refs.
+
+If you use `--all` for the `<git-rev-list-args>`, the resulting
+bundle will be able to recreate all the refs, including those
+outside branches and tags, when extracted with "git clone --mirror".
+
+When creating an incremental bundle on top of an existing bundle,
+`git bundle list-heads <existing-bundle>` can be used to extract
+the then-current tips of the history recorded in it.  Then you can
+list them as the prerequisite objects when creating an incremental
+bundle, e.g.
+
+    $ git bundle create incremental.bundle --all --not \
+	$(git bundle list-heads old.bundle | awk '{print $1}')
+
+which tells the command to include all refs (as if cloning with the
+`--mirror` option), but without duplicating the objects already
+available in the `old.bundle` bundle.
 
 The 'git bundle verify' command can be used to check whether your
 recipient repository has the required prerequisite commits for a