Ultimate Git Branches & Merging Cheatsheet [Live Doc]

Mohammed Ali - Aug 16 - - Dev Community
  • Need to master these concepts as they will be part of daily Git usage.
  • Become a well-informed developer by mastering essentials first and then going deep into each topic.

  • Each commit get a uniqie hash.

  • Each commit references atleast one parent commit. Only First commit i.e the initial one doesn't have a parent commit.

  • We are always working on a branch in Git. On running git status, we get the o/p as:

On branch master
nothing to commit, working tree clean
Enter fullscreen mode Exit fullscreen mode
  • Default branch name in Git is master whereas default branch name in Github is main. Just like a normal branch, nothing novel about it.
  • Although people put main copy of the project on it, but its not mandatory to do so.

Branches:

  • Alternative timeline for project.
  • Enable us to create separate context to try new features or even work on mutiple ideas in parallel. Ex. new-feature, color-scheme, layout-change, bug-fix etc. al happening on separate branches in their respective context.
  • If changes are made on one branch, they don't impact the other branch unless changes are merged via combining branches.
  • To build a new feature, create an experimental-branch from master branch. If the feature was approved, then merge the branch with the main branch else ignore the feature.

Understanding (HEAD -> master):

  • HEAD: pointer that refers to current 'location' in your repo. It points to a particular branch reference i.e name of the branch.
  • branch pointer is where the bookmark is.
  • HEAD: As of now HEAD points to the latest commit made on master branch. But gradually we will see that we can move it around.
  • Branches are like bookmark in a book. At one point of time, only on given bookmark can be accessed/opened/viewed/active. That is what HEAD refers to, the current location we are viewing or checking out.
  • Last commit made was the tip of the master branch. HEAD refers to this branch pointer.
  • If we switch the different branch, HEAD points to tip of that branch.
  • Branch pointer(i.e branch-name Ex. master) keeps moving as we keep making new commits pointing to new commit-hash. Whereas HEAD pointer still points to branch-pointer i.e. master.
  • Ex. To switch to a branch say dark-mode, HEAD should point to new branch-pointer i.e dark-mode. Now new commits will be made to this dark-mode branch. Master pointer won't move & will stay where it was earlier.
  • Whenever we want, we can switch back to the old state, we move the HEAD back to that branch-pointer.
  • We can have 100s of branches and each branch has a branch-reference(or name of branch) which is pointing to where we left off that branch.
- A branch is just a reference to some commit. As we make new changes, the branch-name which is branch-pointer updates to point to a new commit.
Enter fullscreen mode Exit fullscreen mode

View all existing branches in a repo:

git branch

  • Currently active branch i.e on which we are right now will have an asterisk on it.

Creating Branches:

git branch <branch-name> : Make a new branch based upon current HEAD

  • It only creates the branch, doesn't switch the HEAD to the newly created branch. HEAD still remains the same.
  • Two branches will be referring to same parent-commit if they were created from that commit.
git branch color-scheme
git log: HEAD-> master, color-scheme
Enter fullscreen mode Exit fullscreen mode

Switching Branches: [NEWER WAY using switch]

git switch <branch-name>

  • After the newly branch is created, use the above command to switch to the branch.
  • Its the HEAD which switches to newly created branch.
git switch color-scheme
git log: HEAD->color-scheme, master
Enter fullscreen mode Exit fullscreen mode
  • If a new commit is made on this branch, then master will be left behind and HEAD will move on with the tip of this color-scheme branch.
git log: (HEAD -> color-scheme)

commit 3829472394... (master)
Enter fullscreen mode Exit fullscreen mode
  • The location we are on, makes a huge difference when we branch out.
  • Both branches will refer to the same commit from where they were created.

Older Way to switch using checkout

  • git checkout
  • checkout does a lot of other things than just switching branches, hence it was decided to bring a standalone switch command to the table.

- Both achieve the desire result i.e checkout & switch.

Single step branch creation & switching:

-c : create flag
git switch -c [NEWER way]
git checkout -b [OLDER way]

Switching branches with unstaged/ uncommitted changes:

  • Changes made to file, but not staged or committed.
  • If we try to switch in such a state of uncommitted changes, then the changes made will be lost i.e overwritten by checkout.
  • Hence, either commit the changes or stash them before switching a branch.
  • A newly created file which is a single copy on this branch, hence not in any conflict with any other branches. Then in that case, even if its unstaged/uncommited, it will follow you even after you have switched the branch also. Hence, always add & commit changes before switching branches.

Deleting a branch:

git branch -d
git branch --delete 
Enter fullscreen mode Exit fullscreen mode
  • The branch must be fully merged in its upstream branch, or in HEAD if no upstream was set to --track or --set-upstream-to
  • Possible Error1: You can't delete the branch you're on. Hence, switch to another branch before deleting the branch.
  • Possible Error2: It should be fully merged,
  • Force deletion via -D deletes the branch irrespective of the merge status.
  • -D flag is short for --delete --force
  • -M is short for --move --force
  • -C is short for --copy --force

Rename a branch:

  • Switch to the branch which needs to be renamed.
git branch -m <new-name-for-this-branch>
Enter fullscreen mode Exit fullscreen mode

Knowing more about HEAD:

  • Inside .git directory, HEAD references a branch and each branch references a commit i.e

HEAD --(references)--> branch reference --(references)--> commit

  • ls -a
  • cd .git
  • ls
  • cat HEAD : shows ref: refs/heads/master i.e HEAD is pointing to master
  • If branch is switched, and we execute the above set of commands, then HEAD will point to different branch reference[i.e branch name] .......
  • cat HEAD : shows ref: refs/heads/color-scheme i.e HEAD is pointing to color-scheme
  • refs/heads/master, refs/heads/color-scheme etc. actually reference a particular commit.
  • There will be a file for every branch inside refs/heads directory. And in each of these file, there will be just one thing which is commit-hash
  • Hence, branch-reference[or branch-name] is a pointer to a particular commit.
  • So, HEAD was refs/heads/master. And refs/heads/master is actually a commit-hash. Thats where the bookmark for the branch is left off.
  • HEAD = is currently we are checked-out on.
  • HEAD points to one of those branch-references. And branch-references point to one of those commit-hash.
  • We switch HEAD from one location to another.

Merging:

  • One of the most critical aspect. Following topics to be mastered very well as they will be part of daily workflow.
  • Fast-forward Merge,
  • Git Merge & Merge commits
  • Merge conflicts

Merging:

  • Branching gives us an isolated context to work upon a feature, and when we are done with the it then we need to incorporate those changes into the main branch. This is done using git merge
  • If a feature didn't worked out as expected, branch is abandoned.
  • Merge back the feature branch into the master branch if feature worked out as expected.
  • Branches are defined by a branch-pointer.
  • Remember: Branches are merged, not specific commits. Also, we always merge to the current HEAD of the branch i.e where HEAD is now.
Fast-forward Merge Process:
[Main branch has no new commits, feature branch can be directly merged in it.]
1. Switch or checkout to receiving branch in which we need to merge.
`git switch main`
2. Use `git merge` to merge changes from a specific branch into current branch.
`git merge feature`

Enter fullscreen mode Exit fullscreen mode

git branch -v : branch name abbr-hash tip of branch with last commit

Official Docs for further reading:
https://git-scm.com/docs/git-branch
https://git-scm.com/docs/git-switch
https://git-scm.com/docs/git-checkout

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .