[GRASS-dev] git: how to switch between branches?

Hello Markus

I don’t have real-world experience with this, but I am not sure if changing branches and
distcleaning/recompiling is the most convenient workflow. I think I would prefer to have
multiple local repositories with different branches checked out. Thankfully git makes it
rather easy to have this. E.g.:

  1. You create two root directories. One for Python2 and one for Python3:

mkdir /home/user/git/grass-p{2,3}

  1. Create a virtualenv inside grass-p2 and grass-p3. E.g.:

cd /home/user/git/grass-p2
virtualenv -p python2 venv

cd /home/user/git/grass-p2
python3 -m venv venv

  1. Clone the remote GRASS repo and name the local repo dev. You will only do this for grass-p3:

cd /home/user/git/grass-p3
git clone https://github.com/neteler/grass dev

  1. For python 2 and for each release branch you will make a local git clone. This way
    you won’t be wasting disk space. Read more about this
    here.

cd /home/user/git/grass-p2
git clone …/grass-p3/dev dev
git clone …/grass-p3/dev r72
git clone …/grass-p3/dev r74
git clone …/grass-p3/dev r76

  1. The dir structure should look like this:

$ tree grass*

grass-p2
├── dev
├── r72
├── r74
├── r76
└── venv
grass-p3
├── dev
└── venv

  1. On each release clone you need to checkout the respective branch:

cd /home/user/git/grass-p2/r72 && git checkout releasebranch_7_2
cd /home/user/git/grass-p2/r74 && git checkout releasebranch_7_4
cd /home/user/git/grass-p2/r76 && git checkout releasebranch_7_6

  1. Each directory is a full blown git repo. It is only by convention that 7.6 backports
    will happen in r76 etc. If you want to directly pull/push from/to github from the release
    directories, you will probably need to setup remotes. Regardless, setting up remotes
    etc should only be done once.

  2. Obviously, when 7.8 gets released, two more directories will need to be added (one
    for python2 and one for python 3).

The benefit of this approach is that at least for trivial backports, you will not need
to recompile everything and, perhaps more importantly, you will not need to recompile
“master” in order to test a fix in 7.2.

all the best,
Panos

PS1. There are other ways to achieve something like this, e.g.
--singlebranch but I don’t see much
benefit.

PS2. You can optionally use something like direnv to
automatically activate the virtualenvs when you cd into the corresponding directory.
This way there is no confusion WRT which python is active. I use this and it works
marvellously.

Hi Panos,

thanks so much for writing up this guide which looks very good to me
(and saves disk space; and offers an approach more close to those
freshly coming from SVN)!

Some comments + questions inline:

On Mon, May 20, 2019 at 10:23 AM Panagiotis Mavrogiorgos
<pmav99@gmail.com> wrote:

Hello Markus

I don't have real-world experience with this, but I am not sure if changing branches and
distcleaning/recompiling is the most convenient workflow. I think I would prefer to have
multiple local repositories with different branches checked out. Thankfully git makes it
rather easy to have this. E.g.:

1. You create two root directories. One for Python2 and one for Python3:

    mkdir /home/user/git/grass-p{2,3}

2. Create a virtualenv inside grass-p2 and grass-p3. E.g.:

    cd /home/user/git/grass-p2
    virtualenv -p python2 venv

    cd /home/user/git/grass-p2

... I suppose, it should be
     cd /home/user/git/grass-p3

    python3 -m venv venv

3. Clone the remote GRASS repo and name the local repo `dev`. You will only do this for `grass-p3`:

    cd /home/user/git/grass-p3
    git clone https://github.com/neteler/grass dev

5. For python 2 and for each release branch you will make a local git clone. This way
   you won't be wasting disk space. Read more about this
   [here](https://stackoverflow.com/questions/7187088/git-how-to-create-local-repo-with-symbolic-links-to-the-git-main-repo).

    cd /home/user/git/grass-p2
    git clone ../grass-p3/dev dev
    git clone ../grass-p3/dev r72
    git clone ../grass-p3/dev r74
    git clone ../grass-p3/dev r76

6. The dir structure should look like this:

    $ tree grass*

    grass-p2
    ├── dev
    ├── r72
    ├── r74
    ├── r76
    └── venv
    grass-p3
    ├── dev
    └── venv

So far, so nice (locally, I used "master" instead of "dev" but that's
cosmetics).

7. On each release clone you need to checkout the respective branch:

    cd /home/user/git/grass-p2/r72 && git checkout releasebranch_7_2

Now, here I cannot proceed:

cd $REPOPATH/grass-p2/r72 && git checkout releasebranch_7_2
error: pathspec 'releasebranch_7_2' did not match any file(s) known to git

git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master

Any ideas?

    cd /home/user/git/grass-p2/r74 && git checkout releasebranch_7_4
    cd /home/user/git/grass-p2/r76 && git checkout releasebranch_7_6

7. Each directory is a full blown git repo. It is only by convention that 7.6 backports
   will happen in `r76` etc. If you want to directly pull/push from/to github from the release
   directories, you will probably need to setup remotes. Regardless, setting up remotes
   etc should only be done once.

Yes.

8. Obviously, when 7.8 gets released, two more directories will need to be added (one
   for python2 and one for python 3).

(...looking fwd to dropping Python-2 support)

The benefit of this approach is that at least for trivial backports, you will not need
to recompile everything and, perhaps more importantly, you will not need to recompile
"master" in order to test a fix in 7.2.

Yes, that's pretty cool.

all the best,
Panos

PS1. There are other ways to achieve something like this, e.g.
[`--singlebranch`](https://stackoverflow.com/a/1911126/592289) but I don't see much
benefit.

PS2. You can optionally use something like [direnv](https://github.com/direnv/direnv) to
automatically activate the virtualenvs when you cd into the corresponding directory.
This way there is no confusion WRT which python is active. I use this and it works
marvellously.

Wow, didn't know about that so far. As soon as I get the problem
mentioned above sorted out I'll try.

Best,
Markus