Working with branches helps a lot in maintaining an organized workflow. When collaborating with others, it’s a common practice for each developer to operate within their designated branch. Branches can be used for distinct features or versions, and they also enable the establishment of a hierarchical structure within the project (with the main branch typically holding greater importance).

As in the previous tutorial in this series, we will go straight to the code, and learn by doing. Let’s start by checking the status of the repository.

$ git status
On branch main
Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean

We are in the main branch, and our branch is up to date with the remote repository. Sometimes, to be sure is good to do git pull to make sure all the changes from the remote repository are in our machine.

$ git pull
Already up to date.

Confirmed. We are up to date. Let’s now use git branch to check the branches in this repository.

$ git branch
* main

The command output only lists one branch, called main. The * next to the branch name means that we are currently in that branch. Before creating a new branch, let’s review what is the files that we have in the repository.

$ ls
newfile.txt  README.md
$ cat newfile.txt 
this is a new text
$ cat README.md 
# aits-git
Git example
newline

We have two text files, README.md and newfile.txt, with a few lines of text in each. Let’s continue by creating a new branch using git branch <branch_name>.

$ git branch branch-one
$ git branch
  branch-one
* main

After creating the new branch called branch-one I used the git branch command to list all branches, and now I can clearly see that there are two branches, and the * tells me I am working in the main branch. Let’s use git switch to start working in the branch-one.

$ git switch branch-one 
Switched to branch 'branch-one'
$ git branch
* branch-one
  main

After switching I used git branch to see the list of branches again - now we can see that the * indicates I am working in the branch-one. Let’s take a look at the files again in this new branch:

$ ls
newfile.txt  README.md
$ cat newfile.txt 
this is a new text
$ cat README.md 
# aits-git
Git example
newline

Same files, and same content as before. Yes, creating a branch is not going backwards - it’s like stepping to the side: we keep the changes recorded so far. If we add more changes to this new branch, those new changes will not affect the main branch. Let’s add some changes:

echo "line added in new branch" >> newfile.txt 
$ cat newfile.txt 
this is a new text
line added in new branch

The newfile.txt has one more line of text. Let’s commit this change. It’s worth noting that since we have created this branch in our local repository we’ll have to push the changes using the -u option to set the tracking between the local branch and the remote branch (we only add -u the first time we push changes).

$ git status
On branch branch-one
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   newfile.txt

no changes added to commit (use "git add" and/or "git commit -a")
$ git add newfile.txt 
$ git commit -m "add change in branch"
[branch-one 4c48820] add change in branch
 1 file changed, 1 insertion(+)
$ git push -u origin branch-one
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 12 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 317 bytes | 317.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: 
remote: Create a pull request for 'branch-one' on GitHub by visiting:
remote:      https://github.com/lmponcio/aits-git/pull/new/branch-one
remote: 
To https://github.com/lmponcio/aits-git.git
 * [new branch]      branch-one -> branch-one
Branch 'branch-one' set up to track remote branch 'branch-one' from 'origin'.

Above I added, committed and pushed the changes. The most important thing to notice is the last phrase of the output: Branch 'branch-one' set up to track remote branch 'branch-one' from 'origin'. This means that next time we can simply do git push, without the -u option.

Let’s go back to the main branch.

$ git switch main 
Switched to branch 'main'
Your branch is up to date with 'origin/main'.

Let’s take a look at the file we previously modified in the branch-one.

$ cat newfile.txt 
this is a new text

The file only has one line of text. The second one saying "line added in new branch" is not present. It makes sense, because we added that line in the branch-one branch, and now we are in main. Here is a good point to stop and take in this concept: when we use git switch <branch_name> the files in our computer will change to match what is the branch we are going to. To reinforce the idea, let’s go back to our branch and check on that file again:

$ git switch branch-one 
Switched to branch 'branch-one'
Your branch is up to date with 'origin/branch-one'.
$ cat newfile.txt 
this is a new text
line added in new branch

And there it is - the line we added in the branch, which can only be seen when we switch to that branch. Using this basic knowledge on branches now you will be able to work in multiple branches and work in multiple features separately.

As a last exercise, I will add one more change in the branch-one and this time push it using git push without the -u option, so it is more clear how future commits are pushed:

$ echo "second line added in new branch" >> newfile.txt 
$ git add newfile.txt 
$ git commit -m "add another change in the branch"
[branch-one 7af20b8] add another change in the branch
 1 file changed, 1 insertion(+)
$ git push
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 12 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 333 bytes | 333.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/lmponcio/aits-git.git
   4c48820..7af20b8  branch-one -> branch-one

The command used for pushing the changes this time was git push, and as can be seen here, the commit reached the remote repository successfully.