# "git fetch --refetch" and multiple (separate/orphan) branches

3 messages from 2023-06-02 to 2023-08-10. Participants: Tao Klerks, Robert Coup.
Thread: https://gitlist.dev/t/59831

## Tao Klerks, 2023-06-02 21:22

Subject: "git fetch --refetch" and multiple (separate/orphan) branches
Message-ID: <CAPMMpoiJ4cNcAR9gO5d-749N3YW-88p1gMnX8ySGgz84Mr9coA@mail.gmail.com>
URL: https://gitlist.dev/e/CAPMMpoiJ4cNcAR9gO5d-749N3YW-88p1gMnX8ySGgz84Mr9coA%40mail.gmail.com

```
Hi folks,

I just recently noticed that "--refetch" was added in 2.36, and I got
pretty excited - the ability to "fill in" missing blobs after a
too-filtered clone is something that I've wanted a number of times, as
I mentioned in 2021 in thread
https://public-inbox.org/git/CAPMMpohOuXX-0YOjV46jFZFvx7mQdj0p7s8SDR4SQxj5hEhCgg@mail.gmail.com/
.

When I first ran "git fetch --refetch" today however (git 2.38.1,
against server git/2.38.4.gl1), with a configured blob filter of
"blob:1100M", a much higher size than any blob in the history, it only
got a *relatively* small number of objects - 3GB of data rather than
the 18GB that a new unfiltered fetch would have retrieved.

After some more testing I tried again, and got the expected outcome
that time. The relevant difference between the two attempts is that in
the first case, when I only got some of the objects I expected, there
was an updated tag as a result of the fetch. The second time, when I
got everything, there were no updated refs.

In this repository there are several "independent" sets of branches,
and the tag updated in that first fetch belongs to one of the
smaller-history branches.

What I believe is happening is that *if* there are refs to be updated
(or new refs, presumably), *then* the objects returned to the client
are only those required for those refs. If, on the other hand, there
are no updated refs, then you get what is advertised in the doc: "all
objects as a fresh clone would [...]".

I've tested a couple of different scenarios and the behavior seems
consistent with this explanation.

In a repo where all branches are derived from the same history, this
probably isn't very noticeable; in the repo I'm working on it makes a
huge difference, so the only way I can imagine getting "correct"
behavior would be to always to a "git fetch" right before the "git
fetch --refetch".

Is this a bug, or expected behavior that should be noted in the doc,
or do we consider the multiple-independent-branches usecase to be
edge-casey enough to be an easter egg for people like me?

Thanks,
Tao

```

## Robert Coup, 2023-06-03 08:18

Subject: Re: "git fetch --refetch" and multiple (separate/orphan) branches
Message-ID: <CACf-nVfUotaTYeCC9XMvnYYNhjX+EW89z7fhUX0Ok9TpsVTRTw@mail.gmail.com>
URL: https://gitlist.dev/e/CACf-nVfUotaTYeCC9XMvnYYNhjX%2BEW89z7fhUX0Ok9TpsVTRTw%40mail.gmail.com
In-Reply-To: <CAPMMpoiJ4cNcAR9gO5d-749N3YW-88p1gMnX8ySGgz84Mr9coA@mail.gmail.com>

```
Hi Tao

On Fri, 2 Jun 2023 at 22:23, Tao Klerks <tao@klerks.biz> wrote:

> What I believe is happening is that *if* there are refs to be updated
> (or new refs, presumably), *then* the objects returned to the client
> are only those required for those refs. If, on the other hand, there
> are no updated refs, then you get what is advertised in the doc: "all
> objects as a fresh clone would [...]".
>
> I've tested a couple of different scenarios and the behavior seems
> consistent with this explanation.

Do you have a repo & steps that could reproduce this easily? Otherwise
I can try and work up something.

> Is this a bug, or expected behavior that should be noted in the doc,
> or do we consider the multiple-independent-branches usecase to be
> edge-casey enough to be an easter egg for people like me?

At first glance it appears to be a bug.

Thanks,

Rob :)

```

## Tao Klerks, 2023-08-10 07:14

Subject: Re: "git fetch --refetch" and multiple (separate/orphan) branches
Message-ID: <CAPMMpoh9xP8PomAUTHGZfYAMAgHb_BF74EVgmo1C-DQh22-cUA@mail.gmail.com>
URL: https://gitlist.dev/e/CAPMMpoh9xP8PomAUTHGZfYAMAgHb_BF74EVgmo1C-DQh22-cUA%40mail.gmail.com
In-Reply-To: <CACf-nVfUotaTYeCC9XMvnYYNhjX+EW89z7fhUX0Ok9TpsVTRTw@mail.gmail.com>

```
Hi Robert,

Sorry about the extended delay, I haven't had a chance to do "git
hacking" in a while.

On Sat, Jun 3, 2023 at 10:18 AM Robert Coup <robert@coup.net.nz> wrote:
>
> On Fri, 2 Jun 2023 at 22:23, Tao Klerks <tao@klerks.biz> wrote:
>
> > What I believe is happening is that *if* there are refs to be updated
> > (or new refs, presumably), *then* the objects returned to the client
> > are only those required for those refs. If, on the other hand, there
> > are no updated refs, then you get what is advertised in the doc: "all
> > objects as a fresh clone would [...]".
> >
> > I've tested a couple of different scenarios and the behavior seems
> > consistent with this explanation.
>
> Do you have a repo & steps that could reproduce this easily? Otherwise
> I can try and work up something.
>

Does the following work? It shows that with a change to the orphan
branch from another client, a refetch in the original client gets
about half the objects (the ones for the orphan branch that was
updated), and in another fetch right after, with no new changes, the
refetch gets all 600-or-so objects.


create_n_commits() {
  for i in $(seq $2); do
    echo "another new line $RANDOM" >> "$1/datafile"
    git -C "$1" add datafile
    git -C "$1" commit -m anothercommit -q
  done
}

mkdir refetch-testing
SERVERFOLDER=refetch-testing/server
git init "$SERVERFOLDER" --bare

CLIENTFOLDER=refetch-testing/client
git init "$CLIENTFOLDER"
git -C "$CLIENTFOLDER" remote add origin "../server"

git -C "$CLIENTFOLDER" checkout -b main
create_n_commits "$CLIENTFOLDER" 100
git -C "$CLIENTFOLDER" push origin HEAD

git -C "$CLIENTFOLDER" checkout --orphan orphan
create_n_commits "$CLIENTFOLDER" 100
git -C "$CLIENTFOLDER" push origin HEAD

echo "---HERE IS A NORMAL FULL REFETCH---"
git -C "$CLIENTFOLDER" fetch --refetch
echo "---NORMAL FULL REFETCH ENDS---"

OTHERCLIENTFOLDER=refetch-testing/otherclient
git clone "$SERVERFOLDER" "$OTHERCLIENTFOLDER"
git -C "$OTHERCLIENTFOLDER" checkout orphan
create_n_commits "$OTHERCLIENTFOLDER" 5
git -C "$OTHERCLIENTFOLDER" push origin HEAD

echo "---HERE IS A WEIRD PARTIAL REFETCH OF ONE BRANCH ONLY---"
git -C "$CLIENTFOLDER" fetch --refetch
echo "---WEIRD PARTIAL REFETCH ENDS---"

echo "---HERE IS NORMAL REFETCH AGAIN---"
git -C "$CLIENTFOLDER" fetch --refetch
echo "---NORMAL REFETCH ENDS---"

rm -rf refetch-testing

```
