diff mbox series

[v3,1/4] Documentation/git-bundle.txt: mention full backup example

Message ID b222c6787a79c852442969721dadc629ca84cd5b.1730979849.git.code@khaugsbakk.name (mailing list archive)
State New
Headers show
Series [v3,1/4] Documentation/git-bundle.txt: mention full backup example | expand

Commit Message

Kristoffer Haugsbakk Nov. 7, 2024, 11:57 a.m. UTC
From: Kristoffer Haugsbakk <code@khaugsbakk.name>

Provide an example about how to make a “full backup” with caveats about
what that means in this case.

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`.

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.

† 1: E.g.:

    • https://stackoverflow.com/questions/5578270/fully-backup-a-git-repo
    • https://stackoverflow.com/questions/11792671/how-to-git-bundle-a-complete-repo

Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
---

Notes (series):
    v3:
    • Elaborate on “full backups” in Examples instead
    • Just point to the section in the second paragraph where everything is
      elaborated
    • Incorporate some of Junio’s suggestions:
      • Mention what the “full backup” here does not include
    
        Link: https://lore.kernel.org/git/xmqqh68q1l37.fsf@gitster.g/
        Link: https://lore.kernel.org/git/xmqqzfmiza69.fsf@gitster.g/#t
    • Remove the final paragraph pointing to Examples now that we mention it
      in the second paragraph
    v2:
    • Mention as a parenthetical on an existing paragraph (don’t create a
      new sentence and paragraph)
    • Remove the “mirror” mention
    
      Link (both): https://lore.kernel.org/git/ZxbIWEGS1UB3UIg+@nand.local/

Notes (meta-trailers):
    Helped-by: Junio C Hamano <gitster@pobox.com>
        Link: https://lore.kernel.org/git/xmqqzfmiza69.fsf@gitster.g/

 Documentation/git-bundle.txt | 30 ++++++++++++++++++++++++------
 1 file changed, 24 insertions(+), 6 deletions(-)

Comments

Junio C Hamano Nov. 8, 2024, 2:01 a.m. UTC | #1
kristofferhaugsbakk@fastmail.com writes:

> +We'll discuss two cases:
> +
> +1. Taking a full backup of a repository
> +2. Transfer the history of a repository to another machine when the two
> +   machines have no direct connection

Contrasting (1) taking a backup and (2) extracting a backup later is
a very useful way to frame the problem, but then, I'd say

 1. taking a backup, either full or incremental, of a repository

 2. using the backup, either full or incremental, to transfer the
    history of the origin repository to any repository (including
    itself) without needing any other connection between the two
    repositories.

Whether a full or an incremental, the resulting bundle file can be
used as an offline medium and then later extracted elsewhere, even
if there is no direct network connection between the origin
repository and the destination repository.  But you can extract in
the origin repository as well.

But that would require a bit more surgery to the presentation order
of the text, so I do not mind deferrring it to a later and separate
series.  If we were to go that route, it would be helpful to have a
paragraph to describe how you use your "full backup" bundle to recover
lost data from, though.  To those of us who know what is happening,
there is not much difference between the extraction side of the
sneaker-net example, but as we framed the use in two distinct cases,
it would be helpful to make each case stand on its own.

> +First let's consider a full backup of the repository.  The following
> +command will take a full backup of the repository in the sense that all
> +refs are included in the bundle (except `refs/stash`, i.e. the stash):

Are you sure the "except" part is factually correct?

I did

    $ git bundle create x.bndl --all && git ls-remote x.bndl |
      grep stash

and I see refs/stash listed there just fine.  You should be able to
extract them all with

    $ git clone --mirror x.bndl xxx && cd xxx && git for-each-ref |
      grep stash

and see that refs/stash gets propagated.

Fix is a simple s/except/including/ ;-)

> +----------------
> +$ git bundle create <file> --all
> +----------------
> +
> +But note again that this is only for the refs, i.e. you will only
> +include refs and commits reachable from those refs.  You will not
> +include other local state, such as the contents of the index, working
> +tree, per-repository configuration, hooks, etc.

And to make each case stand on its own, we would want to teach
readers how to use the full backup to recover data from here, before
moving on to the "next example".

    You can use the resulting bundle file as if it is a repository,
    a snapshot of it at the time the bundle was created.  You can
    use

    ---
    $ git ls-remote full.bndl
    ---

    to inspect what refs are recorded in it, and you can fetch from or
    even merge a branch out of it, with commands like:

    ---
    $ git fetch full.bndl my-butchered-topic
    $ git show-branch my-butchered-topic FETCH_HEAD
    $ git branch -f my-butchered-topic FETCH_HEAD
    $ git pull full.bndl  my-butchered-topic
    ---

    after you screwed up one of your branches and resurrect it from
    the backup.

or something like that.

> +For the next example, assume you want to transfer the history from a
> +repository R1 on machine A to another repository R2 on machine B.
>  For whatever reason, direct connection between A and B is not allowed,
>  but we can move data from A to B via some mechanism (CD, email, etc.).
>  We want to update R2 with development made on the branch master in R1.
Kristoffer Haugsbakk Nov. 10, 2024, 7:38 p.m. UTC | #2
On Fri, Nov 8, 2024, at 03:01, Junio C Hamano wrote:
> kristofferhaugsbakk@fastmail.com writes:
>
>> +We'll discuss two cases:
>> +
>> +1. Taking a full backup of a repository
>> +2. Transfer the history of a repository to another machine when the two
>> +   machines have no direct connection
>
> Contrasting (1) taking a backup and (2) extracting a backup later is
> a very useful way to frame the problem, but then, I'd say
>
>  1. taking a backup, either full or incremental, of a repository
>
>  2. using the backup, either full or incremental, to transfer the
>     history of the origin repository to any repository (including
>     itself) without needing any other connection between the two
>     repositories.
>
> Whether a full or an incremental, the resulting bundle file can be
> used as an offline medium and then later extracted elsewhere, even
> if there is no direct network connection between the origin
> repository and the destination repository.  But you can extract in
> the origin repository as well.
>
> But that would require a bit more surgery to the presentation order
> of the text, so I do not mind deferrring it to a later and separate
> series.  If we were to go that route, it would be helpful to have a
> paragraph to describe how you use your "full backup" bundle to recover
> lost data from, though.  To those of us who know what is happening,
> there is not much difference between the extraction side of the
> sneaker-net example, but as we framed the use in two distinct cases,
> it would be helpful to make each case stand on its own.

Sure.  I should be able to fit in a paragraph about using that
backup bundle.

>> +First let's consider a full backup of the repository.  The following
>> +command will take a full backup of the repository in the sense that all
>> +refs are included in the bundle (except `refs/stash`, i.e. the stash):
>
> Are you sure the "except" part is factually correct?

It was in my testing/to my recollection.  Hmm but I must have managed to
fool myself somehow. :P
Kristoffer Haugsbakk Nov. 12, 2024, 5:31 p.m. UTC | #3
On Sun, Nov 10, 2024, at 20:38, Kristoffer Haugsbakk wrote:
> On Fri, Nov 8, 2024, at 03:01, Junio C Hamano wrote:
>>> +First let's consider a full backup of the repository.  The following
>>> +command will take a full backup of the repository in the sense that all
>>> +refs are included in the bundle (except `refs/stash`, i.e. the stash):
>>
>> Are you sure the "except" part is factually correct?

Okay now I get it.  Your git-ls-remote(1) example is correct.  But I did
something like:

```
git clone backup.pack ./repo
```

And `clone` will not transfer `refs/stash`.  It’s there but it doesn’t
seem that convenient to get *out* with a porcelain like git-clone(1).
Maybe it’s possible but I kind of want to say “okay just pop your
stashes and make regular commits/branches”.

I’m not sure how to formulate that.  Seems clumsy:

     refs are included in the bundle (also `refs/stash` but that
     particular one won't be included in e.g. a clone):

Would it be too drastic to use a footnote?
Junio C Hamano Nov. 12, 2024, 10:58 p.m. UTC | #4
"Kristoffer Haugsbakk" <kristofferhaugsbakk@fastmail.com> writes:

> Maybe it’s possible but I kind of want to say “okay just pop your
> stashes and make regular commits/branches”.

That requires _more_ than recording the value of the ref for stash,
as data for the Nth stash is recorded as the Nth reflog entry for
that ref, and the reflog data is not what fetch/push/clone/bundle
commands make available.

> I’m not sure how to formulate that.  Seems clumsy:
>
>      refs are included in the bundle (also `refs/stash` but that
>      particular one won't be included in e.g. a clone):
>
> Would it be too drastic to use a footnote?

I am not sure what you want to refer to with "that particular one",
but the value of refs/stash does get recorded, and making a mirror
clone out of the resulting bundle does give refs/stash with the
value of the refs/stash in the original repository where the bundle
was taken from.  So refs/stash _does_ get included.  What is not
included is the reflog data for that ref (or any other ref, for that
matter).

Because the ref value is transferred via fetch/push/clone/bundle but
the reflog (i.e. past values of a ref) data is *not*, "git stash
show stash@{4}" is not something you can recreate in the copy of a
repository, whether you create the copy with "clone" or "bundle +
clone".  The story is the same for other refs, and stash is not that
special in this regard.  "git show master@{yesterday}" in a freshly
created copy would give something entirely different from what you
would get in the original repository you mirror-cloned or took a
bundle from.

You'd need "cp -r" for that.
diff mbox series

Patch

diff --git a/Documentation/git-bundle.txt b/Documentation/git-bundle.txt
index 3ab42a19cae..f39cafee927 100644
--- a/Documentation/git-bundle.txt
+++ b/Documentation/git-bundle.txt
@@ -23,8 +23,9 @@  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 (see the "full backup" example in "EXAMPLES"), and to relay
+the state of the references in one repository to another (see the second
+example).
 
 Git commands that fetch or otherwise "read" via protocols such as
 `ssh://` and `https://` can also operate on bundle files. It is
@@ -34,8 +35,6 @@  contained within it with linkgit:git-ls-remote[1]. There's no
 corresponding "write" support, i.e.a 'git push' into a bundle is not
 supported.
 
-See the "EXAMPLES" section below for examples of how to use bundles.
-
 BUNDLE FORMAT
 -------------
 
@@ -216,8 +215,27 @@  bundle.
 EXAMPLES
 --------
 
-Assume you want to transfer the history from a repository R1 on machine A
-to another repository R2 on machine B.
+We'll discuss two cases:
+
+1. Taking a full backup of a repository
+2. Transfer the history of a repository to another machine when the two
+   machines have no direct connection
+
+First let's consider a full backup of the repository.  The following
+command will take a full backup of the repository in the sense that all
+refs are included in the bundle (except `refs/stash`, i.e. the stash):
+
+----------------
+$ git bundle create <file> --all
+----------------
+
+But note again that this is only for the refs, i.e. you will only
+include refs and commits reachable from those refs.  You will not
+include other local state, such as the contents of the index, working
+tree, per-repository configuration, hooks, etc.
+
+For the next example, assume you want to transfer the history from a
+repository R1 on machine A to another repository R2 on machine B.
 For whatever reason, direct connection between A and B is not allowed,
 but we can move data from A to B via some mechanism (CD, email, etc.).
 We want to update R2 with development made on the branch master in R1.