Rocket Academy Bootcamp
  • 🚀Welcome to Bootcamp!
  • 🛠️Logistics
    • Course Schedules
    • Course Methodology
    • Required Software
    • LinkedIn Education Badge
  • 📚General Reference
    • Naming, Casing, and Commenting Conventions
    • VS Code Tips
    • Recommended Resources
  • 🪨0: Foundations
    • 0.1: Command Line
    • 0.2: Git
      • 0.2.1: Branches
    • 0.3: GitHub
      • 0.3.1: Pull Requests
    • 0.4: JavaScript
      • 0.4.1: ES6
      • 0.4.2: Common Syntax
      • 0.4.3: Reference vs Value
      • 0.4.4: Classes
      • 0.4.5: Destructuring and Spread Operator
      • 0.4.6: Promises
        • 0.4.6.1: Async Await
    • 0.5: Node.js
      • 0.5.1: Node Modules
      • 0.5.2: NPM
      • 0.5.3: Nodemon
  • 🖼️1: Frontend
    • 1.1: HTML
    • 1.2: CSS
      • 1.2.1: Layout
    • 1.3: React
      • Styling in ReactJs
      • Using Styling Libraries with React
      • React Deployment
    • 1.E: Exercises
      • 1.E.1: Recipe Site
      • 1.E.2: Portfolio Page
      • 1.E.3: World Clock
      • 1.E.4: High Card
      • 1.E.5: Guess The Word
    • 1.P: Frontend App
  • 🏭2: Full Stack
    • 2.1: Internet 101
      • 2.1.1: Chrome DevTools Network Panel
      • 2.1.2: HTTP Requests and Responses
    • 2.2: Advanced React
      • 2.2.1: AJAX
      • 2.2.2: React Router
      • 2.2.3: useContext
      • 2.2.4: useReducer
      • 2.2.5: Environmental Variables
      • 2.2.6: React useMemo - useCallback
    • 2.3: Firebase
      • 2.3.1: Firebase Realtime Database
      • 2.3.2: Firebase Storage
      • 2.3.3: Firebase Authentication
      • 2.3.4: Firebase Hosting
      • 2.3.5: Firebase Techniques
    • 2.E: Exercises
      • 2.E.1: Weather App
      • 2.E.2: Instagram Chat
      • 2.E.3: Instagram Posts
      • 2.E.4: Instagram Auth
      • 2.E.5: Instagram Routes
    • 2.P: Full-Stack App (Firebase)
  • 🤖3: Backend
    • 3.1: Express.js
      • 3.1.1 : MVC
    • 3.2: SQL
      • 3.2.1: SQL 1-M Relationships
      • 3.2.2: SQL M-M Relationships
      • 3.2.3: SQL Schema Design
      • 3.2.4: Advanced SQL Concepts
      • 3.2.5: SQL - Express
      • 3.2.6: DBeaver
    • 3.3: Sequelize
      • 3.3.1: Sequelize One-To-Many (1-M) Relationships
      • 3.3.2: Sequelize Many-To-Many (M-M) Relationships
      • 3.3.3: Advanced Sequelize Concepts
      • 3.3.4 Database Design
    • 3.4: Authentication
      • 3.4.1: JWT App
    • 3.5: Application Deployment
    • 3.E: Exercises
      • 3.E.1: Bigfoot JSON
      • 3.E.2: Bigfoot SQL
      • 3.E.3: Bigfoot SQL 1-M
      • 3.E.4: Bigfoot SQL M-M
      • 3.E.5: Carousell Schema Design
      • 3.E.6: Carousell Auth
    • 3.P: Full-Stack App (Express)
  • 🏞️4: Capstone
    • 4.1: Testing
      • 4.1.1: Frontend React Testing
      • 4.1.2: Backend Expressjs Testing
    • 4.2: Continuous Integration
      • 4.2.1 Continuous Deployment (Fly.io)
      • 4.2.2: Circle Ci
    • 4.3: TypeScript
    • 4.4: Security
    • 4.5: ChatGPT for SWE
    • 4.6: Soft Skills for SWE
    • 4.P: Capstone
  • 🧮Algorithms
    • A.1: Data Structures
      • A.1.1: Arrays
        • A.1.1.1: Binary Search
        • A.1.1.2: Sliding Windows
      • A.1.2: Hash Tables
      • A.1.3: Stacks
      • A.1.4: Queues
      • A.1.5: Linked Lists
      • A.1.6: Trees
      • A.1.7: Graphs
      • A.1.8: Heaps
    • A.2: Complexity Analysis
    • A.3: Object-Oriented Programming
    • A.4: Recursion
    • A.5: Dynamic Programming
    • A.6: Bit Manipulation
    • A.7: Python
  • 💼Interview Prep
    • IP.1: Job Application Strategy
    • IP.2: Resume
    • IP.3: Portfolio
Powered by GitBook
On this page
  • Learning Objectives
  • Introduction
  • Create a branch
  • Change branch
  • Merge feature branch to main
  • Merge locally
  • Merge on GitHub
  • Merge main to feature branch
  • Merge Conflicts
  • What are merge conflicts and why do they happen?
  • How to resolve merge conflicts
  • Exercises
  • Create feature branch and merge to main without merge conflicts
  • Resolve Merge Conflicts
  1. 0: Foundations
  2. 0.2: Git

0.2.1: Branches

Previous0.2: GitNext0.3: GitHub

Learning Objectives

  1. Git Branches allow us to develop features independently of "production" code to avoid affecting what our teammates and users see before we are ready.

  2. How to create a new branch

  3. How to move between branches

  4. How to merge 1 branch to another and resolve merge conflicts

Introduction

A Git Branch is an independent series of commits. Every Git repo starts with a single branch, typically main, which we can imagine to be a linear series of commits.

Using multiple branches allows software engineers to develop new features based on production code in main without affecting main, even after pushing to GitHub. We typically refer to non-main branches as "feature branches". Feature branches can be for changes as small as a typo and as large as new products.

Feature branches are independent series of commits that typically "branch" from main , and merge back into main after we have completed and tested the new feature.

We can delete feature branches after merging them to main.

At large tech companies, 1000s of engineers can be working on independent feature branches that branch from main and merge back to main at different points in time.

Create a branch

Create new branches with git checkout -b. git checkout is the command to switch, or "checkout" branches, and the -b flag creates a new branch and checks it out. Branch names use kebab-case (lowercase with hyphens between words) by default, and we will use my-feature as our example branch name.

git checkout -b my-feature

Verify we are on the new my-feature branch with git branch.

react % git checkout -b my-feature
Switched to a new branch 'my-feature'
react % git branch
  main
* my-feature
react %

Now we can make commits on my-feature that build on the state of main when we created my-feature. Changes on my-feature will not affect any other branch in our repo.

Change branch

While working on feature branches we may wish to periodically checkout other branches such as main to verify our changes are still compatible with theirs. To change back to the main branch, run git checkout main. We may also wish to git pull when on main to pull any new changes from GitHub to main. Run git checkout my-feature to go back to the my-feature branch.

Merge feature branch to main

Once done with our feature on our feature branch, we can merge our changes to main for teammates and users to use. When working independently we can perform the merge locally, but when working in a team we typically perform the merge via GitHub to give teammates a chance to review our changes through a "pull request".

Merge locally

  1. Checkout the branch we want to merge into. For example, if we want to merge changes on our feature branch to main, checkout main.

  2. Run git merge followed by the source branch name, e.g. git merge my-feature.

  3. Git will combine commits from both branches and create a "merge commit" to resolve any differences. Run git log to view the merge commit and verify merge success.

  4. Delete the feature branch locally with git branch -d followed by the feature branch name, e.g. git branch -d my-feature.

  5. Once ready, push latest changes in main to GitHub.

Merge on GitHub

  1. Checkout and verify we are on our feature branch with git branch

  2. Run git push to push latest commits from our feature branch to GitHub. If this is our first time pushing this feature branch to GitHub, we may have to run git push --set-upstream origin followed by our feature branch name, e.g. git push --set-upstream origin my-feature.

We may see the following output when pushing a feature branch to GitHub for the first time with git push. To resolve, enter the command Git suggests: git push --set upstream origin my-feature, where my-feature is the name of our feature branch.

Git Push failure first time pushing feature branch to GitHub
react % git push
fatal: The current branch my-feature has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin my-feature

react % git push --set-upstream origin my-feature
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
remote:
remote: Create a pull request for 'my-feature' on GitHub by visiting:
remote:      https://github.com/kai-rocket/react/pull/new/my-feature
remote:
To https://github.com/kai-rocket/react.git
 * [new branch]          my-feature -> my-feature
Branch 'my-feature' set up to track remote branch 'my-feature' from 'origin'.
react %

upstream refers to where our code should be hosted. origin refers to our GitHub repo or where we cloned our repo from. my-feature tells Git to create a new branch called my-feature in GitHub and by default push changes from the local my-feature branch to the GitHub my-feature branch.

After setting upstream once for a branch, we can run git push without arguments for subsequent pushes from this branch.

Merge main to feature branch

In addition to merging feature branches to main, another common workflow is to merge latest changes from main into our feature branch. This minimises chances of merge conflicts when we merge our feature branch to main, especially if there have been big changes to main since we started our feature.

  1. Checkout main with git checkout main and pull latest changes from GitHub with git pull.

  2. Checkout our feature branch, e.g. git checkout my-feature.

  3. Run git merge main to merge main into our feature branch. If we're lucky Git will merge the changes automatically. If not we will need to resolve merge conflicts manually.

Merge Conflicts

What are merge conflicts and why do they happen?

Merge conflicts are situations when Git cannot automatically merge changes from 2 branches, for example if 2 branches change the same line of code differently. We can minimise merge conflicts by actively communicating with teammates to work on different files or functions, but generally merge conflicts are a standard feature of software engineering.

VS Code highlights differences in files with conflicts. The lines surrounded by <<<<<<< HEAD and ======= are changes from the branch we are on, and the lines surrounded by ======= and >>>>>>> main are changes from the incoming branch.

How to resolve merge conflicts

Once we have a merge conflict we must resolve it before writing new code, such that each commit in our commit history continues to describe a specific change. If we are unable to resolve conflicts now or merged by accident, we can abort merge with git merge --abort, which will revert our repo state to just before we ran git merge.

After Git tells us we have merge conflicts, use git status to confirm which files have conflicts.

Open each file with conflicts and resolve conflicts in each file by removing lines starting with <<<<<<<, ======= and >>>>>>> and updating the code to what it should be. We can use VS Code's Accept Current/Incoming/Both Changes buttons and/or manually edit the files.

Once we have resolved all conflicts, verify our app still works as expected. Once satisfied with our changes, git add the resolved files to add them to staging area for commit.

Commit changes to finalise Git's merge commit and complete merge.

After committing, git status should no longer mention conflicts.

We can verify merge success by checking commit history in Git Logs with git log.

Exercises

Create feature branch and merge to main without merge conflicts

  1. Create a new repo.

    mkdir poems
    cd poems
    git init
  2. Create a poem about water in water-poem.txt. Commit this file to the repo.

  3. Create and checkout a new branch to edit the water poem.

    git checkout -b water-poem-edits
  4. Edit the water poem and commit it to the new branch you just created.

  5. List all branches.

    git branch
  6. Checkout main.

    git checkout main
  7. Verify water-poem.txt has reverted to the version on main.

  8. Create a new poem about sandwiches in a new file and commit it.

  9. Checkout the water poem branch.

    git checkout water-poem-edits
  10. Verify the sandwich poem does not exist in the water poem branch.

  11. Checkout main and merge the water poem edits from the water poem branch.

  12. Verify water-poem.txt contains changes from the water poem branch.

  13. Delete the water poem branch with git branch -d water-poem-edits.

Resolve Merge Conflicts

  1. Start from the same repo as the previous exercise.

  2. Make a new branch for edits to the sandwich poem.

    git checkout -b sandwich-poem-edits
  3. While on the sandwich branch, add a line to the poem and change the line that's currently there.

  4. Commit the changes on the sandwich branch.

  5. Checkout main. To create a merge conflict we will commit new changes to the same lines on the main branch.

  6. Make a change to the sandwich poem and commit it.

  7. Merge the sandwich branch into main.

  8. We should observe a merge conflict.

  9. Open the sandwich poem file to see merge conflict symbols from Git.

  10. Resolve the merge conflict as per instructions above.

See instructions in for how to create and merge a pull request in GitHub.

🪨
0.3.1: Pull Requests
Every repo starts with the main branch by default
Create and work on a feature branch when working on a new feature
Git state after merging feature branch to main. All commits from feature branch are copied to main, and Git adds an extra "merge commit" to resolve differences.
Git will tell us where we have merge conflicts when we enter git status after merging. Within those files, VS Code will tell us which lines are in conflict, and we can click buttons above the conflict to resolve the conflicts.
VS Code gives us buttons above each conflict to conveniently resolve each conflict.
Once we have resolved the conflict in the file we can git add to stage the file with conflicts for commit. We need to make a new commit to mark the conflict resolved.
Entering git commit after adding resolved files to staging area will open a commit message window. Save and close the file to complete commit.
Once we save the commit message file, we should see the commit completed.
We can verify successful merge by looking at Git Logs.
Demo of how merge conflicts happen and how to resolve them