Skip to content

bobby_dreamer

Git Theory - 4 - Branching

notes, git7 min read

Here we are covering subjects related to branches.

# git branch

  • Branches allow us to work on different versions of the same file in parallel. Edits on one branch is independent of other branch.
  • At later point it can be decided whether to merge or not.
  • Default branch was called Master after BLM(BlackLivesMatter) protests in 2020 its been changed to 'main'
Always do remember
  • Head will always point to the tip of the branch(i.e., latest commit)
  • Branch is a lightweight movable pointer which will always point to latest commit
  • If head points to a different commit point, then head is in a state referred to as 'detached HEAD'

git branching

Detached HEAD

git branching

  • git checkout <sha1> \ git checkout <tag_name>
    • Switches the currently active branch to a specific commit
    • Updates the files in the working directory to reflect that commit point.
  • To get back to master branch
    • git checkout master

git detached

Branching concepts

git branch can tell you to which branch HEAD is pointing to.

git branch

  • git branch -v gives you more information about branches and commit points and messages (-v is verbose)

If you give git checkout –b feature

  • Creates a new branch
  • Checkout to new branch feature

git checkout

Now we are ready to merge feature with master.

You can also create a new branch like below, it creates a new feature12-test branch based on master branch.

1git checkout -b feature12-test master

Two steps of merging

  • Checkout into the branch you want merge INTO (ALREADY DONE)
  • Merge the branch you want to merge

git merge

Understanding merge graph

git merge graph

Make a note of the strategy in the above diagram recursive

Lets rewind a bit and do fast-forward merge

Remove a commit

git reset -hard

Fast-forward strategy This is a fast-forward merge

Fast-forward strategy

Going back to the Recursive Strategy (or) 3-way merge

“the commit on the branch you’re on isn’t a direct ancestor of the branch you’re merging in, Git has to do some work. In this case, Git does a simple three-way merge, using the two snapshots pointed to by the branch tips and the common ancestor of the two.”

Git uses 3 commits to generate a merge commit

  • Last commit of master
  • Last commit of feature
  • Common ancestor commit (base commit)

Recursive Strategy

Delete branch

Once the branches are merged they can be deleted

  • Git branch --merged
    • Show all the merged branches
  • git branch –d feature
    • Deletes the branch

NOTE:- Git will not allow a branch to be deleted if its not merged. Use the below command to forcibly delete the branch.

  • git branch –D feature

Create a new tracking branch based on a remote branch

1git branch --track <new-branch> <remote-branch>
Rename current branch to new branch name
1Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test4 (master)
2$ git branch
3* master
4
5Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test4 (master)
6$ git checkout -b name1
7Switched to a new branch 'name1'
8
9Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test4 (name1)
10$ git branch
11 master
12* name1
13
14Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test4 (name1)
15$ git branch -m name2
16
17Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test4 (name2)
18$ git branch
19 master
20* name2
Use of stash during branch jumps

If you have made some unstaged changes in the working directory and try to checkout to new branch. You will not be able to do it. During then use,

  • git stash
Tricks
  • Switching branches

    1git checkout master
    2git checkout dev
    3
    4# here - means master
    5git checkout -
    6
    7# here - means dev
    8git checkout -

# git reflog

Reflog is short for reference log, is a mechanism to record when the tip of branches are updated. Git tries really hard not to lose your data, so if for some reason you think it has, chances are you can dig it out using git reflog.

The most common usecase, you made some changes and committed those and did a git reset --hard to “undo” those changes, and then later realized, you want those changes back. Usecase for this would be any scenario where you move your HEAD. With reflog you can recover almost anything you’ve committed

Git refs are updated when below commands are executed

  • Git checkout
  • Git reset
  • Git merge

git reflog is similar to git log but shows list of times when HEAD is changed.

Things to remember

  • HEAD changes only, when you issue git checkout -- <filename>, HEAD does not change, so reflog cannot recover those.
  • git reflog does not last forever as git periodically cleans up objects which are unreachable. Its a global setting, by default it keeps for 90 days.

Common reflog commands are

  • git reflog / git reflog show HEAD
  • git reflog show <<branch>>
  • git reflog stash

git reflog

Scenario above

  • We have added 3 files in 3 commits and did a reset—hard to second commit.
  • After looking at hash from reflog, we did again a reset—hard to third commit.

# git rebase

Rebasing is changing the base of your branch from one commit to another making it appear as if you’d created your branch from a different commit. Internally, Git accomplishes this by creating new commits and applying them to the specified base. It’s very important to understand that even though the branch looks the same, it’s composed of entirely new commits.

  • In Simple words, rebase reapplies commits on top of another base tip.
  • Other git command that capable of intergrating two branches is get merge.
  • Prefer to use rebase only on locally unpublished commits.
Usecase
  • You are working on a feature branch that is out of date with a master branch, rebasing the feature branch onto master will allow all the new commits from master to be included in feature.
  • This helps in keeping branch's history clean so it appears as if you've been working off the latest master branch
  • Cleaner history meaning it appears that all the work happened in series, even when it originally happened in parallel.
Rebase step-by-step
  • Upstream : master
  • Branch : feature

Before rebase

1A---B---C feature(head)
2 /
3 D---E---F---G master

Assuming here you are currently on your feature branch(git checkout feature) and when you enter (git rebase master) following happens,

  1. Git checks whats the common commit point(ancestor) in both branches.
  2. Git looks at the current branch and see's all changes made by commits that are not in 'master' and are saved to a temporary area.
  3. Current branch is reset to 'master' or 'newbase'. Eg:git reset --hard <master>
  4. The commits that were previously saved into the temporary area are then reapplied to the current branch, one by one, in order.

During rebase (step 3)

1feature(head)
2 /
3 D---E---F---G master

After rebase command completion(A', B' and C' will have new SHA1-hashes)

1A'--B'--C' feature(head)
2 /
3 D---E---F---G master

Command git rebase master feature combines above two command into a single command, what it does is,

  • Checks out the feature branch for you
  • Replays it onto the master branch

At this point, you can go back to the master branch and do a fast-forward merge as well.

1git checkout master
2git merge feature
3
4# Visual Output
5 feature
6 |
7 D---E---F---G---A'---B'---C' master(head)

You can remove the feature branche because all the work is integrated into master you don’t need it anymore.

1git branch -d feature

git rebase practical

  • (feature) branch has two additional commits D & E
  • (master) branch has one additional commit F
  • git checkout to feature
  • Git rebase replays feature commits D & E on top of master commit(F) with new SHA1 commit values
  • Now you can merge feature branch into master. It will be a fast-forward merge.
1git checkout master
2git merge feature

Note : Its not recommended to rebase master onto a feature branch as it would create confusing history when working with multiple people in a team. Dont do something like the following,

1git checkout master
2git rebase feature

Other options

  • Abort : git rebase --abort
Squashing commits using rebase

Plan is to squash last two commits(260b361, 25bde47) into one

Latest 10 commits

1Sushanth@Sushanth-VAIO MINGW64 /d/GITs/git (master)
2$ git lol -n10
3* 260b361 - (HEAD -> master) Deleting a c d e text files (1 year, 10 months ago) <Sushanth Bobby Lloyds>
4* 25bde47 - (tag: V4, stash/start) Updated readme.txt & adding back c d e (1 year, 10 months ago) <Sushanth Bobby Lloyds>
5* d4bff73 - (tag: V3) Merge reset/finished into master (1 year, 10 months ago) <Sushanth Bobby Lloyds>
6|\
7| * 1ab856b - (reset/finished) Adding a.txt (1 year, 10 months ago) <Sushanth Bobby Lloyds>
8|/
9* b77ca73 - (reset/start) Updated readme.txt for RESET (1 year, 10 months ago) <Sushanth Bobby Lloyds>
10* 85e7f70 - (tag: V2) Merge undo/finished into master (1 year, 10 months ago) <Sushanth Bobby Lloyds>
11|\
12| * db8427c - (undo/finished) Revert "Updated OneTwoThreeFour.txt line 2 from Two to number 2" (1 year, 10 months ago) <Sushanth Bobby Lloyds>
13| * 178a3ca - Updated OneTwoThreeFour.txt line 4 from Four to number 4 (1 year, 10 months ago) <Sushanth Bobby Lloyds>
14| * 6405ecb - Updated OneTwoThreeFour.txt line 2 from Two to number 2 (1 year, 10 months ago) <Sushanth Bobby Lloyds>
15| * 3ebe1db - Adding OneTwoThreeFour.txt (1 year, 10 months ago) <Sushanth Bobby Lloyds>

Squashing latest two commits git rebase -i HEAD~2. As soon as i entered the command, vim editor window poped up and listed the two commits in chronological order with command pick and manually changed second commit command to squash.

1pick 25bde47 Updated readme.txt & adding back c d e
2squash 260b361 Deleting a c d e text files
3
4# Rebase d4bff73..260b361 onto d4bff73 (2 commands)
5#
6# Commands:
7# p, pick = use commit
8# r, reword = use commit, but edit the commit message
9# e, edit = use commit, but stop for amending
10# s, squash = use commit, but meld into previous commit
11# f, fixup = like "squash", but discard this commit's log message
12# x, exec = run command (the rest of the line) using shell
13# d, drop = remove commit
14#
15# These lines can be re-ordered; they are executed from top to bottom.
16#
17# If you remove a line here THAT COMMIT WILL BE LOST.
18#
19# However, if you remove everything, the rebase will be aborted.
20#
21# Note that empty commits are commented out

After Esc -> :wq(save & exit), another editor pops up like below, this is for rewriting the comment message.

1# This is a combination of 2 commits.
2# This is the 1st commit message:
3
4Updated readme.txt & adding back c d e
5
6# This is the commit message #2:
7
8Deleting a c d e text files
9
10# Please enter the commit message for your changes. Lines starting
11# with '#' will be ignored, and an empty message aborts the commit.
12#
13# Date: Mon Dec 10 19:48:44 2018 +0530
14#
15# interactive rebase in progress; onto d4bff73
16# Last commands done (2 commands done):
17# pick 25bde47 Updated readme.txt & adding back c d e
18# squash 260b361 Deleting a c d e text files
19# No commands remaining.
20# You are currently rebasing branch 'master' on 'd4bff73'.
21#
22# Changes to be committed:
23# deleted: a.txt
24# modified: readme.txt
25#
26# Untracked files:
27# Branching.txt
28#

Commented existing comments by insert # symbol and added inserted message squashing two commits (Updated readme.txt & adding back c d e, Deleting a c d e text files) then save & exit.

This is the final output

1$ git rebase -i HEAD~2
2[detached HEAD 745f48c] squashing two commits (Updated readme.txt & adding back c d e, Deleting a c d e text files)
3 Date: Mon Dec 10 19:48:44 2018 +0530
4 2 files changed, 64 insertions(+), 1 deletion(-)
5 delete mode 100644 a.txt
6Successfully rebased and updated refs/heads/master.
7
8Sushanth@Sushanth-VAIO MINGW64 /d/GITs/git (master)
9$ git lol -n 5
10* 745f48c - (HEAD -> master) squashing two commits (Updated readme.txt & adding back c d e, Deleting a c d e text files) (6 minutes ago) <Sushanth Bobby Lloyds>
11* d4bff73 - (tag: V3) Merge reset/finished into master (1 year, 10 months ago) <Sushanth Bobby Lloyds>
12|\
13| * 1ab856b - (reset/finished) Adding a.txt (1 year, 10 months ago) <Sushanth Bobby Lloyds>
14|/
15* b77ca73 - (reset/start) Updated readme.txt for RESET (1 year, 10 months ago) <Sushanth Bobby Lloyds>
16* 85e7f70 - (tag: V2) Merge undo/finished into master (1 year, 10 months ago) <Sushanth Bobby Lloyds>
17|\

If this is what you had expected, then this is fine otherwise you can undo the above action by doing.

  1. git reflog -n 10 : Show the last 10 reflog lists
  2. Find the sha-value of the latest commit you had before (260b361)
  3. git reset --hard "HEAD@{n}"
1$ git reflog -n 10
2745f48c (HEAD -> master) HEAD@{0}: rebase -i (finish): returning to refs/heads/master
3745f48c (HEAD -> master) HEAD@{1}: rebase -i (squash): squashing two commits (Updated readme.txt & adding back c d e, Deleting a c d e text files)
425bde47 (tag: V4, stash/start) HEAD@{2}: rebase -i (start): checkout HEAD~2
5260b361 HEAD@{3}: rebase -i (abort): updating HEAD
6260b361 HEAD@{4}: rebase: aborting
7d4bff73 (tag: V3) HEAD@{5}: rebase -i (start): checkout HEAD~2
8260b361 HEAD@{6}: reset: moving to ORIG_HEAD
9be43d59 HEAD@{7}: rebase -i (finish): returning to refs/heads/master
10be43d59 HEAD@{8}: rebase -i (squash): Updated readme.txt & adding back c d e
117ac6472 HEAD@{9}: rebase -i (reword): Updated readme.txt & adding back c d e
12
13Sushanth@Sushanth-VAIO MINGW64 /d/GITs/git (master)
14$ git reset --hard "HEAD@{3}"
15HEAD is now at 260b361 Deleting a c d e text files
16
17Sushanth@Sushanth-VAIO MINGW64 /d/GITs/git (master)
18$ git lol -n 10
19* 260b361 - (HEAD -> master) Deleting a c d e text files (1 year, 10 months ago) <Sushanth Bobby Lloyds>
20* 25bde47 - (tag: V4, stash/start) Updated readme.txt & adding back c d e (1 year, 10 months ago) <Sushanth Bobby Lloyds>
21* d4bff73 - (tag: V3) Merge reset/finished into master (1 year, 10 months ago) <Sushanth Bobby Lloyds>
22|\
23| * 1ab856b - (reset/finished) Adding a.txt (1 year, 10 months ago) <Sushanth Bobby Lloyds>
24|/
25* b77ca73 - (reset/start) Updated readme.txt for RESET (1 year, 10 months ago) <Sushanth Bobby Lloyds>
26* 85e7f70 - (tag: V2) Merge undo/finished into master (1 year, 10 months ago) <Sushanth Bobby Lloyds>
27|\
28| * db8427c - (undo/finished) Revert "Updated OneTwoThreeFour.txt line 2 from Two to number 2" (1 year, 10 months ago) <Sushanth Bobby Lloyds>
29| * 178a3ca - Updated OneTwoThreeFour.txt line 4 from Four to number 4 (1 year, 10 months ago) <Sushanth Bobby Lloyds>
30| * 6405ecb - Updated OneTwoThreeFour.txt line 2 from Two to number 2 (1 year, 10 months ago) <Sushanth Bobby Lloyds>
31| * 3ebe1db - Adding OneTwoThreeFour.txt (1 year, 10 months ago) <Sushanth Bobby Lloyds>

Instead of git reflog, git reset --hard "HEAD@{n}" and all the detective stuff above, you can just enter this command as well git reset --hard ORIG_HEAD.

Any other issues with rebase, you can do

  • If conflict, fix the conflict, git add then 'git rebase --continue`
  • Any issues that couldn't be resolved git rebase --abort
  • Any other issues you can do git reset --hard
Merge Vs. Rebase

This is a big topic has its own pro and con and decision needs to be based on collaborators and team,

  • git merge is run, an extra merge commit is created, so there might be too many merge commits.
  • git rebase is risky insense, it rewrites history
  • git rebase can be used to squash commits locally

# Handling Conflicts

Conflicts occur when there are changes to the same position/line of the file at different commits or branches Usually conflicts occur during

  • Reverting changes
  • Merging branches
  • Rebasing

Test Setup

1rm -rf .git *.*
2git init
3
4echo "Big bang" > universe.txt
5git add .
6git commit -m "Initial Commit"
7echo "Sun" >> universe.txt && git commit -am "Added Sun"
8echo "Mercury" >> universe.txt && git commit -am "Added mercury"
9echo "Venus" >> universe.txt && git commit -am "Added venus"
10echo "Earth" >> universe.txt && git commit -am "Added earth"
11echo "Mars" >> universe.txt && git commit -am "Added mars"
12echo "Jupiter" >> universe.txt && git commit -am "Added jupiter"
13echo "Saturn" >> universe.txt && git commit -am "Added saturn"
14echo "Uranus" >> universe.txt && git commit -am "Added uranus"
15echo "Neptune" >> universe.txt && git commit -am "Added neptune"

Content of file and commits

1Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master)
2$ cat universe.txt
3Big bang
4Sun
5Mercury
6Venus
7Earth
8Mars
9Jupiter
10Saturn
11Uranus
12Neptune
13
14Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master)
15$ git lol
16* bc3b214 - (HEAD -> master) Added neptune (9 seconds ago) <Sushanth Bobby Lloyds>
17* 1bc7ec8 - Added uranus (11 seconds ago) <Sushanth Bobby Lloyds>
18* 1cb6a2c - Added saturn (11 seconds ago) <Sushanth Bobby Lloyds>
19* 479fc63 - Added jupiter (11 seconds ago) <Sushanth Bobby Lloyds>
20* 762ee6e - Added mars (11 seconds ago) <Sushanth Bobby Lloyds>
21* ff9623a - Added earth (12 seconds ago) <Sushanth Bobby Lloyds>
22* 8dd1b51 - Added venus (12 seconds ago) <Sushanth Bobby Lloyds>
23* 4790be6 - Added mercury (3 minutes ago) <Sushanth Bobby Lloyds>
24* 56f3e34 - Added Sun (3 minutes ago) <Sushanth Bobby Lloyds>
25* e1d1d72 - Initial Commit (4 minutes ago) <Sushanth Bobby Lloyds>
Conflicts during reverts

As part of test, i am going to remove commit related to Earth

1Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master)
2$ git revert ff9623a
3error: could not revert ff9623a... Added earth
4hint: after resolving the conflicts, mark the corrected paths
5hint: with 'git add <paths>' or 'git rm <paths>'
6hint: and commit the result with 'git commit'
7
8Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master|REVERTING)
9$ cat universe.txt
10Big bang
11Sun
12Mercury
13Venus
14 <<<<<<< HEAD
15Earth
16Mars
17Jupiter
18Saturn
19Uranus
20Neptune
21=======
22 >>>>>>> parent of ff9623a... Added earth

Git adds below markers(seven <,> & = symbols) when a conflict is found and its the developers responsibility to remove the markers after manually reviewing the program

  • <<<<<<< HEAD
    • All the content between HEAD and DIVIDER, exists in the current branch master which the HEAD ref is pointing to.
  • =======
  • >>>>>>> parent of ff9623a... Added earth

Manually markers and Earth needs to be removed.

1Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master|REVERTING)
2$ git status
3On branch master
4You are currently reverting commit ff9623a.
5 (fix conflicts and run "git revert --continue")
6 (use "git revert --abort" to cancel the revert operation)
7
8Unmerged paths:
9 (use "git reset HEAD <file>..." to unstage)
10 (use "git add <file>..." to mark resolution)
11
12 both modified: universe.txt
13
14no changes added to commit (use "git add" and/or "git commit -a")
15
16Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master|REVERTING)
17$ cat universe.txt
18Big bang
19Sun
20Mercury
21Venus
22Mars
23Jupiter
24Saturn
25Uranus
26Neptune
27
28Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master|REVERTING)
29$ git add .
30
31Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master|REVERTING)
32$ git status
33On branch master
34You are currently reverting commit ff9623a.
35 (all conflicts fixed: run "git revert --continue")
36 (use "git revert --abort" to cancel the revert operation)
37
38Changes to be committed:
39 (use "git reset HEAD <file>..." to unstage)
40
41 modified: universe.txt
42
43Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master|REVERTING)
44$ git revert --continue
45[master 6e6cfa5] Revert "Added earth"
46 1 file changed, 1 deletion(-)
47
48Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master)
49$ git lol
50* 6e6cfa5 - (HEAD -> master) Revert "Added earth" (13 seconds ago) <Sushanth Bobby Lloyds>
51* bc3b214 - Added neptune (42 minutes ago) <Sushanth Bobby Lloyds>
52* 1bc7ec8 - Added uranus (42 minutes ago) <Sushanth Bobby Lloyds>
53* 1cb6a2c - Added saturn (42 minutes ago) <Sushanth Bobby Lloyds>
54* 479fc63 - Added jupiter (42 minutes ago) <Sushanth Bobby Lloyds>
55* 762ee6e - Added mars (42 minutes ago) <Sushanth Bobby Lloyds>
56* ff9623a - Added earth (42 minutes ago) <Sushanth Bobby Lloyds>
57* 8dd1b51 - Added venus (42 minutes ago) <Sushanth Bobby Lloyds>
58* 4790be6 - Added mercury (44 minutes ago) <Sushanth Bobby Lloyds>
59* 56f3e34 - Added Sun (44 minutes ago) <Sushanth Bobby Lloyds>
60* e1d1d72 - Initial Commit (45 minutes ago) <Sushanth Bobby Lloyds>

As soon as you hit git revert --continue, vim editor pops up for comment message which is auto-filled, you can go with it. Save, Exit and you have completed the reverting process.

Note : Read git status messages, they will give you options and commands on how to proceed. Above, it gave two options

  • (all conflicts fixed: run "git revert --continue")
  • (use "git revert --abort" to cancel the revert operation)

Conflicts during merging branches

Scenario : Developer wants to write a calculator program in rexx and basically wants two features add() and sub() initially and quickly writes the below main logic and each feature is added in separate branch.

1# calc.txt contains below code
2/*** rexx ***/
3a = 10
4b = 5
5c = add(a, b)
6d = sub(a, b)
7say 'Addition : 'c
8say 'Subractiion : 'd
9exit

Creating branches

1git init
2git add .
3git commit -m 'Initial commit'
4git checkout -b add
5# Add add()
6git add . && git commit -m "Added add feature"
7
8git checkout master
9git checkout -b sub
10# Add sub()
11git add . && git commit -m "Added sub feature"

Add feature

1Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master)
2$ git checkout add
3Switched to branch 'add'
4
5Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (add)
6$ cat calc.txt
7/*** rexx ***/
8a = 10
9b = 5
10c = add(a, b)
11d = sub(a, b)
12say 'Addition : 'c
13say 'Subractiion : 'd
14exit
15
16add:procedure
17get argument a
18get argument b
19say 'Adding a + b'
20return 0

Sub feature

1Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (add)
2$ git checkout sub
3Switched to branch 'sub'
4
5Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (sub)
6$ cat calc.txt
7/*** rexx ***/
8a = 10
9b = 5
10c = add(a, b)
11d = sub(a, b)
12say 'Addition : 'c
13say 'Subractiion : 'd
14exit
15
16sub:procedure
17get argument a
18get argument b
19say ‘Subracting a - b'
20return 0

Merging add and sub features

1Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (sub)
2$ git checkout master
3Switched to branch 'master'
4
5Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master)
6$ git merge add sub
7Fast-forwarding to: add
8Trying simple merge with sub
9Simple merge did not work, trying automatic merge.
10Auto-merging calc.txt
11ERROR: content conflict in calc.txt
12fatal: merge program failed
13Automatic merge failed; fix conflicts and then commit the result.
14
15$ cat calc.txt
16/*** rexx ***/
17a = 10
18b = 5
19c = add(a, b)
20d = sub(a, b)
21say 'Addition : 'c
22say 'Subractiion : 'd
23exit
24
25<<<<<<< .merge_file_a14136
26add:procedure
27get argument a
28get argument b
29say 'Adding a + b'
30=======
31sub:procedure
32get argument a
33get argument b
34say ‘Subracting a - b'
35>>>>>>> .merge_file_a13400
36return 0

Removed the markers and proceeded to stage and commit

1Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master|MERGING)
2$ git status
3On branch master
4You have unmerged paths.
5 (fix conflicts and run "git commit")
6 (use "git merge --abort" to abort the merge)
7
8Unmerged paths:
9 (use "git add <file>..." to mark resolution)
10
11 both modified: calc.txt
12
13no changes added to commit (use "git add" and/or "git commit -a")
14
15Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master|MERGING)
16$ git add .
17warning: LF will be replaced by CRLF in calc.txt.
18The file will have its original line endings in your working directory.
19
20Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master|MERGING)
21$ git commit -m 'Added both add and sub'
22[master c35ab3e] Added both add and sub
23
24Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master)
25$
26
27Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master)
28$ git lol
29* c35ab3e - (HEAD -> master) Added both add and sub (32 seconds ago) <Sushanth Bobby Lloyds>
30|\
31| * 447bd6a - (sub) Added sub feature (9 minutes ago) <Sushanth Bobby Lloyds>
32* | 8671031 - (add) Added add feature (11 minutes ago) <Sushanth Bobby Lloyds>
33|/
34* 216acda - Initial commit (13 minutes ago) <Sushanth Bobby Lloyds>
35
36# Deleted the branches as they are no longer required.
37git branch -D add
38git branch -D sub

More changes & conflicts

Adding proper code to add function

1git checkout -b add
2
3# add function in the current code is replaced with below
4add:procedure
5a = arg(1)
6b = arg(2)
7say 'Adding a + b'
8return a + b
9
10git add .
11git commit -m 'Updated add()'
12
13git checkout master

Adding proper code to add function

1git checkout -b sub
2
3# sub function in the current code is replaced with below
4sub:procedure
5a = arg(1)
6b = arg(2)
7say 'Subracting a - b'
8return a - b
9
10git add .
11git commit -m 'Updated add()'
12
13git checkout master

Merging calc.txt with master

1Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master)
2$ git merge add sub
3Fast-forwarding to: add
4Trying simple merge with sub
5Simple merge did not work, trying automatic merge.
6Auto-merging calc.txt
7warning: LF will be replaced by CRLF in calc.txt.
8The file will have its original line endings in your working directory.
9Merge made by the 'octopus' strategy.
10 calc.txt | 14 +++++++-------
11 1 file changed, 7 insertions(+), 7 deletions(-)
12
13Sushanth@Sushanth-VAIO MINGW64 /d/GITs/test3 (master)
14$ git status
15On branch master
16nothing to commit, working tree clean

No conflicts this time as each of the developers updated different part of the code, different lines. Additionally if you notice here we have been merging two branches to master in a single command and strategy we are using in ‘octopus’

“This resolves cases with more than two heads, but refuses to do a complex merge that needs manual resolution. It is primarily meant to be used for bundling topic branch heads together. This is the default merge strategy when pulling or merging more than one branch. “

git switch

This is experimental, its sort of similar to git checkout <branch-name> as it does switch to a specified branch. The working tree and the index are updated to match the branch. All new commits will be added to the tip of this branch.

Most common operations are

  • git switch feature-v1 : Switching to feature-v1 branch
  • git switch -c feature-v1 : (caps-off)Creating a new branch
  • git switch -C feature-v1 : (caps-on)If a branch already exists, it will reset the start point.
  • git switch - : Switches to last branch
  • git switch -m feature-v1 : Does a 3-way merge
What else

Creating a branch from old commit

There are multiple ways to do like

  1. Using checkout : git checkout -b feature-pre-v1 a9c146a09505837ec03b

  2. Using branch but without checking out git branch feature-pre-v1 a9c146a09505837ec03b

  3. Via detached HEAD

    1git checkout a9c146a09505837ec03b
    2git branch feature-pre-v1
    3# or
    4git checkout -b feature-pre-v1

# Things to remember

  • Don't add large files to git, even if you git rm or git reset they will be in there dangling. Its not easy to find them.
  • Don't use master/main branch for development purposes, they should have only production ready, releasable code.
  • Destructive commands in git
    1git checkout HEAD -- fn.ext
    2git checkout -- .
    3git reset --hard
    4git clean -f

# Next steps

  • Internals : Git Internals
  • Collaboration : Git remote repository
  • Git Everyday : Git flowchart, shortcuts and references
  • Origin : How it all began. What is git ? and Terminologies used in this series.
  • Basics : config, init, add, rm, .gitignore, commit, log, blame, diff, tag, describe, show and stash
  • Undos : checkout, reset, revert and restore