Git Peaks #3 Branches

Git branches

One of the strengths of Git is to allow us to create, modify and travel between different parallel versions of a project, like the Quinn Mallory of IT (if you don't have this reference, shame on you). In order to avoid getting lost in the cosmos, let's see how to manipulate the space-time continuum to travel through different versions of a project.

After the last Git Peaks #2 devoted to commits, and particularly on how to create a clean and understandable history, let's take a little height by focusing on the case of branches!

Why branches?

Branches in Git make it possible to evolve several versions of a project in parallel, without one having an impact on the others. It is then possible to merge different versions, to update a version compared to another, or to drop a version, definitively or not (the famous effect Sandbox of Git).

For example, the branch master often represents the stable version of the project, which will be distributed to users. Then, several strategies exist, where new branches will make it possible to work on a new feature, fix a bug or improve the beta version, without touching the stable version of the project. So, master remains stable and available at all times. When work on a parallel branch is complete, tested, and approved, it can be merged into the branch master. The stable version of the project now contains the new additions developed in the parallel branch.

Manipulate Git branches

A few Git commands allow you to manipulate branches and move through the different versions of the project. The main actions are to create a branch and to change the current branch. But first, a little scouting.

Find your way around the multiverse

We no longer present git status which allows to have a general state of the repository, and precisely in the first place the current branch.

$ gitstatus
On branch master Your branch is up to date with 'origin/master'. nothing to commit, working tree clean

To have a more precise vision of the existing branches, git branch allows them to be listed, along with the "distance" branches (present on the server) using the option -a. The current branch is always preceded by a star.

$git branch
* Master

$ git branch -a
* master remotes/origin/HEAD -> origin/master remotes/origin/cpp-hello-world remotes/origin/master

Create a Git branch and move

To create a new branch, we use again branch followed by the name you wish to give. The new branch will be at its creation identical to the current branch.

$ git branch new-feature

$git branch
* master new-feature

$ gitlog
480b8fd (HEAD -> master, origin/master, origin/HEAD, new-feature) Merge branch 'python-hello-world' Wed Oct 14 15:27:22 2020 +0200 Jules Chevalier

We notice that we are still on the branch master. To change branch and switch to the new branch, we will use git checkout.

$ gitstatus
On branch master Your branch is up to date with 'origin/master'. nothing to commit, working tree clean

$ git checkout new-feature 
Switched to branch 'new-feature'

$ gitstatus
On branch new-feature nothing to commit, working tree clean

To perform the creation of a branch and the switch to the new branch in a single command, you can use the option -b from Git.

$ git checkout -b new-feature
Switched to a new branch 'new-feature'

The new branch will therefore evolve independently of master and new changes will only be made to that branch. Thanks to this system, we can therefore change versions on the fly, by putting the work in progress on hold, then later return to this version without losing anything, and without complex manipulation.

To illustrate all this, a small example of work on two independent branches.

$ gitstatus
On branch new-feature nothing to commit, working tree clean # Add new file and commit on new-feature $ touch new-feature.txt

$ gitstatus
On branch new-feature Untracked files: (use "git add ..." to include in what will be committed) new-feature.txt nothing added to commit but untracked files present (use "git add" to track)

$ git add new-feature.txt 

$ git commit -m'chore: add test file'
[new-feature 23a538e] chore: add test file 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 new-feature.txt

# The new commit is present
$ gitlog
23a538e (HEAD -> new-feature) chore: add test file Tue Feb 2 16:10:55 2021 +0100 Jules Chevalier 480b8fd (origin/master, origin/HEAD, new-feature, master) Merge branch 'python-hello-world' Wed Oct 14 15:27:22 2020 +0200 Jules Chevalier

# But does not appear on the master branch, which remained intact
$ git checkout master 
Switched to branch 'master' $ git log 480b8fd (HEAD -> master, origin/master, origin/HEAD, new-feature) Merge branch 'python-hello-world' Wed Oct 14 15:27:22 2020 +0200 Jules Chevalier

Pushing his new branch

As always, Git's primary purpose is to save and share your work. To do this, pushing a branch on a Git server (Gitlab, Github, etc.) makes it possible to secure the modifications before any additional operation. Once again it is towards git push that we turn, except for a few details.

If we are satisfied with git push our new branch, git warns us that it does not know the destination of the branch, and is therefore unable to complete the operation.

Why hasn't the question come up before with master ? Because the master branch was fetched directly from the server, when git clone, and has been associated with its server counterpart, called origin/masterCalled upstream branch.

$ git checkout new-feature 
Switched to branch 'new-feature'
$git push fatal: The current branch new-feature has no upstream branch. To push the current branch and set the remote as upstream, use git push --set-upstream origin new-feature

To overcome this situation, you must directly indicate to Git the name of the branch to push on the server with git push origin new-feature. We can, with the option -u indicate to Git that we now want to link the local branch to its remote counterpart, avoiding having to repeat this precision each time push.

$ git push -u origin new-feature 
[...] To git.peaks.fr:jchevalier/git-example.git * [new branch] new-feature -> new-feature Branch 'new-feature' set up to track remote branch 'new-feature' from 'origin'.

Now that the new branch is saved, let's see how to repatriate its modifications in the main branch master.

Fusiooooooon /o/\o\

Obviously, the use of separate branches takes on its full meaning by merging them. When the work on a branch is finished, it is time to merge it with a main branch, in order to repatriate the work done "in parallel" in this new branch. This merge is done in two steps: switching to the target branch, and merging the changes from the source to the target. The changeover is always done with git checkout, and the merge is done with git merge followed by the name of the branch source.

$ git checkout master 
Switched to branch 'master' Your branch is up to date with 'origin/master'.

$ git merge new-feature 
Updating 480b8fd..23a538e Fast-forward new-feature.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 new-feature.txt
 
$ gitlog
23a538e (HEAD -> master, origin/new-feature, new-feature) chore: add test file Tue Feb 2 16:10:55 2021 +0100 Jules Chevalier 480b8fd (origin/new-feature, origin/master, origin/HEAD, new-feature) Merge branch 'python-hello-world' Wed Oct 14 15:27:22 2020 +0200 Jules Chevalier

We can see following the merger of the branches that master successfully retrieved the commit created in new-feature.

Conclusion

Branches clearly give Git its full power. Thanks to them, it is possible to work in parallel on several versions of the project, without interference, while benefiting from the saving and sharing of the work carried out. A project release remains stable under all circumstances, while new features and bugs are addressed in parallel releases simultaneously.

There is obviously a lot to add to sweep the extent of the possibilities but also the difficulties brought by the use of the branches. An entire article would be needed to talk about conflict management, when you want to merge branches whose modifications are not compatible, or even on the different models for using branches, famous Git Workflow so GitFlow is the best known …

Marine

Check all
Career area
Subscribe to the newsletter :
These articles may interest you