On Sat, Apr 15, 2023 at 2:35 AM Uwe Brauer <o...@mat.ucm.es> wrote:
> > On Fri, Apr 14, 2023 at 04:38:34PM +0200, Uwe Brauer wrote:
> > Well, your approach is incorrect. ;-)
> > A correct one is going to be quicker, too.
> > As I've explained in this list in the past, _by default_ Git implements
> > asymmetric approach to handling remote repositories and branches they
> > contain - you might want to re-read [1] and may be the whole thread; may be
> > this idea will now have greater chances to really sink in as you will be
> > able to compare and contrast "normal" clone and "mirror" clone.
> So let me see whether I understood git's philosophy correctly:
>     1. A «normal» clone results in:
>        1. All data (I say data not files) are downloaded
>        2. But not necessarily all references (branches):
>           1. References to remote branches are available and
>           2. The reference to the main (the branch that points to HEAD
>              on remote) is also available, might be: master/main/stable
>              or whatsoever

Not all references are branches, but all the ones that are branches
are fetched, except in a different namespace: /refs/remotes.

Local branches are /refs/heads, and that's what `git branch` shows.
Remote branches are in /refs/remotes, and that's what `git branch
--remotes` shows.

But the remote branches are not always up-to-date, that's why they are
called "remote tracking branches", that is: they track remote
branches, but they aren't always necessarily the same.

>        3. If I want to checkout a branch that corresponds to remote
>           branch the correct way (without shortcuts would be)
>   git branch feature origin/feature # create local branch off a remote one
>   git checkout feature              # check local branch out

This is OK, but you can create a branch and check it out at the same time with:

    git checkout -b feature origin/feature

Except, for new users `git switch` may be easier:

    git switch -c feature origin/feature

A more recommended way is to "track" the original branch:

    git switch -c feature -t origin/feature

To understand what this does you would need to learn about the concept
of "upstream tracking branch" [1], but you don't have to, just know
that it's generally better if you set it up.

You don't have to type that, because `git switch` can guess what you
want to do, so just:

    git switch --guess feature

This will create a local branch "feature" that will track the remote
tracking branch "origin/feature" that tracks the remote "feature"

But since by default the "guess" functionality is enabled, just do:

    git switch feature

>   git branch -u origin/feature      # make current branch track origin/feature

No need to do that, -t (--track) does that already, and so does --guess.

> This would syntax would also work if I set  a new remote
> gitlab  g...@gitlab.com:kalthad/matlab-emacs.git (fetch)
> Then that would be:
>   git branch feature gitlab/feature # create local branch off a remote one
>   git checkout feature              # check local branch out
>   git branch -u gitlab/feature      # make current branch track gitlab/feature

Or just:

    git switch -c feature -t gitlab/feature

> * Mirrors and bare repositories
> A more mercurial like clone would be using the mirror option.
> Such a repository has *no* remote  branch tracking, but  all branches are 
> available.

That depends on your conception of "branch".

Git branches are not like Mercurial branches, they are pointers to
head commits, not labels.

A more appropriate analogy are Mercurial bookmarks, which as far as I
understand are local, and I think they added support for remote
bookmarks, which have a different namespace.

New users shouldn't use --mirror, as that requires them to know what
they are doing.

> However the repository is bare, no commits are displayed.

Commits are displayed, "bare" means no workspace is created, so no
files are checked out.

> I can change a bare repository to a normal one
>     1) mkdir .git
>     2) mv all stuff in the .git directory

Just clone in that directory:

    git clone --mirror $url foo/.git

>     3) git config --local --bool core.bare false

Or just:

    git config core.bare false

(--local is the default)

>     4) git reset --hard

`git checkout` is more appropriate here.

> However it seems that there is no remote branch tracking and that is why
> it seems not wise to use such a repository for development
> pushing/fetching.

There are remote tracking branches, but they are not in the
/refs/remotes namespace, they are in the /refs/heads namespace, so
your local branches are remote tracking branches.

If you do changes on a "feature" branch, they will be overridden when
you do `git fetch`.

Once a mirror, always a mirror.

> Is this so far correct?

Yes, but I think you should forget about using a mirror, that's not
what you want.

I think what you want is to mirror all the remote branches only once,
and otherwise have a normal repository (not a mirror).

You can do that with this command:

    git fetch origin refs/heads/*:refs/heads/*

This will create local branches for all the remote branches (the
remote refs/heads/foo will become a local refs/heads/foo). The problem
with this approach is that the local branches will not track the
remote branches.

At the end of the day I think what you should do is do `git switch`
for every remote branch, which git can help:

    git for-each-ref --format='git switch %(refname:lstrip=3)'

Just remove HEAD and "master", or whatever branches you have already tracked.



Felipe Contreras

You received this message because you are subscribed to the Google Groups "Git 
for human beings" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to git-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 

Reply via email to