Git Branches

Use this tutorial as an intuitive introduction. The go here and read more details.
(this post if part of the material I cover in my devops course)

Why Branches

  • Our repository from the previous example has 3 commits and 3 files.
  • Let's say that this is a software project, and our code (those 3 files) is good, and we know we now want to do 2 things, that may conflict later:
    1. We want to create a 4th file, with a new feature for our software.
    2. We want to work more on the current version (these 3 files) to see if it is ready.
    3. We want to save the last good version of 2., so that if anybody come back with a problem (bug?) we can recreate the source that this customer is using.
  • If we analyze what we want, it is 2 concurrent lines of development:
    • the project as it is today, just fixing small things
    • the next phase of the project, with 4 files
  • Both line should consider the path that we have already passed (these 3 commits) as a mutual history. They should both show it in the git log output

Making and using branches

  • If you read carefully the output of the git status command, you'll see that there is alreay a branch there, called master (or main)
1$> 
2$> git status
3On branch master
4nothing to commit, working tree clean
5$> 
  • I'm going to create a new branch called phase2
1$> 
2$> git branch 
3* master
4$> git branch phase2
5$> git branch 
6* master
7  phase2
8$> 
  • The git branch command display a list of all branches
    If you add a name, it will create a new branch with that name
  • To go to the new branch, use git checkout command:
1$> git branch 
2* master
3  phase2
4$> git checkout phase2 
5Switched to branch 'phase2'
6$> git branch 
7  master
8* phase2
9$> 
  • Note how the current branch is marked with an asterisk

Advancing in both branches

  • Adding a new file in phase2:
 1> 
 2$> ls
 3dir-A  file1  file2
 4$> echo "this is file 4" > file4
 5$> 
 6$> ls
 7dir-A  file1  file2  file4
 8$> git status
 9On branch phase2
10Untracked files:
11  (use "git add <file>..." to include in what will be committed)
12	file4
13
14nothing added to commit but untracked files present (use "git add" to track)
15$> git add file4 
16$> git commit -m "adding file4"
17[phase2 564453a] adding file4
18 1 file changed, 1 insertion(+)
19 create mode 100644 file4
20$> 
21$> ls
22dir-A  file1  file2  file4
23$> 
  • Checking back to master:
 1$> 
 2$> git status
 3On branch phase2
 4nothing to commit, working tree clean
 5$> ls
 6dir-A  file1  file2  file4
 7$> git checkout master 
 8Switched to branch 'master'
 9$> ls
10dir-A  file1  file2
11$> 
  • So git is managing out working directory to reflect the specified branch
  • Lets add a line to file2 in the master branch:
 1$> 
 2$> git status
 3On branch master
 4nothing to commit, working tree clean
 5$> ls
 6dir-A  file1  file2
 7$> echo "this is the last line" >> file2
 8$> git status
 9On branch master
10Changes not staged for commit:
11  (use "git add <file>..." to update what will be committed)
12  (use "git restore <file>..." to discard changes in working directory)
13	modified:   file2
14
15no changes added to commit (use "git add" and/or "git commit -a")
16$> git add file2 
17$> git commit -m "saving last line in file2"
18[master 5dfd919] saving last line in file2
19 1 file changed, 1 insertion(+)
20$> 
  • The change is only in master, not in phase2:
 1$> 
 2$> git checkout master 
 3Switched to branch 'master'
 4$> cat file2
 5world
 6this is the last line
 7$> 
 8$> git checkout phase2 
 9Switched to branch 'phase2'
10$> cat file2
11world
12$> 

Log for branches

  • Here's the log for master:
    • it include the mutual 3 commits
    • it includes adding the last line to file2
 1$> git checkout master 
 2Switched to branch 'master'
 3$> git log
 4commit 5dfd9196f10ab364b4cd456c42fe17e18ed9e719 (HEAD -> master)
 5Author: Yuval Shaul <yuval.shaul@gmail.com>
 6Date:   Tue Jan 23 06:51:35 2024 -0500
 7
 8    saving last line in file2
 9
10commit bc9e96bdd271ffea773de812a69689ff13ac2dab
11Author: Yuval Shaul <yuval.shaul@gmail.com>
12Date:   Tue Jan 23 03:26:58 2024 -0500
13
14    adding file3
15
16commit 1d84deaa1e6a0b6389ee8e50debfd3fbd4c5cd01
17Author: Yuval Shaul <yuval.shaul@gmail.com>
18Date:   Tue Jan 23 03:25:01 2024 -0500
19
20    adding file2
21
22commit 696c35e3aa1aef1df4e3aa26a50974732b97a560
23Author: Yuval Shaul <yuval.shaul@gmail.com>
24Date:   Tue Jan 23 02:26:58 2024 -0500
25
26    this is my first commit
27$> 
  • Here's the log for phase2:
    • It includes the first mutual 3 commits
    • it includes adding file4
    • NO LAST LINE in file2
 1$> git checkout phase2 
 2Switched to branch 'phase2'
 3$> git log
 4commit 4fee8ee2464a20758222dad57aeeab23489f96e9 (HEAD -> phase2)
 5Author: Yuval Shaul <yuval.shaul@gmail.com>
 6Date:   Tue Jan 23 06:48:43 2024 -0500
 7
 8    adding file4
 9
10commit bc9e96bdd271ffea773de812a69689ff13ac2dab
11Author: Yuval Shaul <yuval.shaul@gmail.com>
12Date:   Tue Jan 23 03:26:58 2024 -0500
13
14    adding file3
15
16commit 1d84deaa1e6a0b6389ee8e50debfd3fbd4c5cd01
17Author: Yuval Shaul <yuval.shaul@gmail.com>
18Date:   Tue Jan 23 03:25:01 2024 -0500
19
20    adding file2
21
22commit 696c35e3aa1aef1df4e3aa26a50974732b97a560
23Author: Yuval Shaul <yuval.shaul@gmail.com>
24Date:   Tue Jan 23 02:26:58 2024 -0500
25
26    this is my first commit
27$> cat file2
28world
29$>