Branches

Branches

Cite

"When we think of branches, two things spring into mind. One is divergence. It even shows in natural language. “The road branched” refers to a road splitting into multiple directions. Secondly, our intuition of a branch is something that has some length – not just a single point. In terms of version control, we would then expect that we have branches when we have separate chains of commits" [1]

As mentioned above, a branch is just a link between different commits, or a pathway through the commits[2]. When you make a commit, Git stores a commit object that contains a pointer (in others word SHA1 hash to the snapshot of the content you staged.

When we create a new repository with git init, behind the scenes, Git creates a default branch called master (at this point it is the current or the active branch).
Historically, this term came from Bitkeeper, a predecessor to Git. Bitkeeper referred to the source of truth as the master repository and other copies as “slave repositories”[4].
Recently, master was not considered an inclusive terminology, so the community decided to substitute this term with main.

If you want to experiment with your code but you do not want to disrupt the current flow?
 Create a new branch! Let's do it

Create a new Branch

The usual way to make a new branch featurexxx is

Create a new branch

git checkout -b <branch-name> <hash-commit> This creates the branch featurexxx pointing at the current commit, and switches to it. You can also specify a commit at which to start the new branch, rather than the current one

git checkout -b featurexxx
git checkout -b featurexxx 4e26ab

It's possible to create a new branch featurezzz without changing the current one.

Create a new branch

git branch <branch-name> Create a new branch
git branch <branch-name> <hash-commit>

git branch featurexxx

If you execute the git branch and it acts like vi or a less command, this is normal behaviour. You can change the global configuration with this command.

Changing the global configuration
git config --global pager.branch false

If you have the intention to rename a Git repository’s branch name while preserving the repository’s commit history, you can easily do so like this:

Rename a branch
git branch -m <old-branch-name> <new-branch-name>

Multiples branches can co-exist in the same repository even pointing to the same commit. They are located in the subfolder ./git/refs/heads. The heads directory stores a file for each local branch in your local repository. Obviously, there must be only one current branch

Another significant point to know is that Git automatically moves forward the branch to the latest commit. A branch is essentially a pointer to a commit, which has a parent commit, a grandparent commit, and so on[2:1].

Tip

A typical utilization of a branch is to work on a new software feature in isolation of the main line of development. When you create a branch, you are creating a fork from a specific state of the project’s timeline. Git’s branches enable you to separate experimentation from production-ready code.

Periodically, It’s recommended to merge master into your feature branch, to ensure you’re working on up-to-date code and notice and resolve any conflicts. When the feature is ready, you do the opposite: merge the feature branch into master, adding the new code to the main version of the project. Another use for multiple branches is to continue maintenance on older versions of software[5].

Delete a branch

To delete a branch, run the following command:

git branch -D new_test_branch

Change the current branch

Change the current branch with the following command:

Change the current branch

git checkout – check out the previous branch

git checkout <branch>

The only thing that has to happen to switch branches is to change the HEAD symbolic ref to point to the new branch name.
Remember, after executing git checkout the current branch will be the one that you inform.

Shows the content of your current branch (HEAD)
git symbolic-ref HEAD

If any moment you receive this message on output, it means you are using git in a detached mode state. Get additional information in the next chapter, in the section where we treat git detached state. But in simply words, to exit this state, just type git checkout <branch-name>

git symbolic-ref HEAD
fatal: ref HEAD is not a symbolic ref
Tip

It's good practice, create a hierarchical branch name that resembles a Unix pathname. You may easily identify, via branch name, various feature implementations and bug fixes or representing its changes contributed by you as an individual.​
For example, you can split into separated branches such as features/feature-XXXbug/ticket-number, or ppremk/feature-B. (but you cannot end with a slash). Another advantage when using hierarchical branch names is that Git, just like the Unix shell, supports wildcards.

Selecting all features or bug branches
git show-branch 'features/*'
git show-branch 'bug/*'

When we execute a git checkout to the specific commit, we enter a state called DETACHED STATE. This means that everything that comes after the commit that we check will not be visible with the command git log. This means because we see our working directory at the perspective of the new HEAD, in other words, the commit.

For this reason, if your intention is to list all commits in the repository. You must execute the following command.

git log --all
Important

It's important repeat that your working directory may contain only a single version of your project at any moment of time.

Comparing branches

Comparing branches

git diff <other_branch> <path>
HEAD~1 parent commit
HEAD current commit
HEAD~ is an alias for HEAD~1
--staged to see the difference between our workspace, stage, and repository

git diff HEAD~1 HEAD

Some words about HEAD~ and HEAD^.
HEAD~<number> means finder the <number>-th parent in a single line of parents referenced by HEAD, on the other hand,
HEAD^<number>-th allows navigating into commits with multiple parents. For example:

Git Advanced - part 4 2024-01-21 19.49.51.excalidraw.png

HEAD^1 is B (Is the same as HEAD~1)
HEAD^2 is C the second parent when you have a fork.
HEAD^3 is D, the third parent when you have multiples fork.
HEAD~1^2 is ERROR. fatal: ambiguous argument: unknown revision or path not in the working tree error. It references a commit that does not exist.

You can even combine ~ and ^ in a single command as HEAD^1~1
HEAD^1~1 is E
HEAD^1^1 is E
HEAD^2~1 is E
HEAD^3~^1 is E

Git Advanced - part 4 2024-01-21 20.00.19.excalidraw.png

Try to solve this example

Git Advanced - part 4 2024-01-21 19.11.35.excalidraw.png

Exercise

A^1 = _______
A~1 = _______
A~2 = _______
A^2= _______
A~5 = _______
A~1^2 = _______
A~1^3 = _______
A^1^1= _______
A~2~1= _______
A~1^1= _______
A~1^2= _______
A^5= _______
A^1^1^1 = _______
A^1^1~2 = _______
A^1^2 = _______
A^1^2~1 = _______

There is also a special case HEAD^0 that means the commit itself.

List branch's files or show branch's content

git show <name>:<path> Where branch can be any ref (branch, tag, HEAD, etc.)
git show <name>:<path> > output redirect output to a new file

git show <name>:<path>
git show isabela:./
git show featurexxx:file1.txt > file1_test.txt
Print the lates version in every branch
git branch -v 
Output

$ git branch -v
isabela 69074dc branch isabela
*master fc9efdd first comit

Git Advanced - part 4 2024-01-21 14.59.40.excalidraw.png

Bug fix and developing a new feature

This is a sequence of steps to create a new branch for developing a new feature or fixing a bug isolated from the core line development.

Create a new branch
git branch bug/fix-ticketid-001
git branch

bug/fix-ticketid-001
bug/fix-ticketid-002
bug/fix-ticketid-003

Show the current HEAD
git log -1 bug/fix-ticketid-001 --format=format:%H

fc9efdd155d809f6614cba94c80a40bbd7c4ffa2

Adding a description to the branch

--edit-description This parameter will open an editor. Close and the message will be saved.

git branch --edit-description bug/fix-ticketid-001
Shows the branch's description

git config --get branch.<branch-name>.description To retrieve the description for the branch

git config --get branch.bug/fix-ticketid-001.description 

Branch was created to resolve ticket-id #20320303021

The other steps you do as usual.

Further ahead, we will see using remote repositories as well.

Got to next part

Branches


  1. Abildskov, Johan. Practical Git: Confident Git through Practice. New York: Apress, 2020. ↩︎

  2. Daityari, Shaumik. Jump Start Git. Vic, Australia: SitePoint Pty. Ltd., 2015. ↩︎ ↩︎

  3. ‘Git - Basic Branching and Merging’. Accessed 20 January 2024. https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging ↩︎

  4. ‘The New Git Default Branch Name’. Accessed 20 January 2024. https://about.gitlab.com/blog/2021/03/10/new-git-default-branch-name. ↩︎

  5. Silverman, Richard E. Git Pocket Guide. Sebastopol, CA: O’Reilly Media, 2013. ↩︎