- 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
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.
Every repo starts with the main branch by default
Using multiple branches allows software engineers to develop new features based on production code in
main, even after pushing to GitHub. We typically refer to non-
mainbranches 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
mainafter we have completed and tested the new feature.
Create and work on a feature branch when working on a new feature
We can delete feature branches after merging them to
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.
At large tech companies, 1000s of engineers can be working on independent feature branches that branch from
mainand merge back to
mainat different points in time.
Create new branches with
git checkout -b.
git checkoutis the command to switch, or "checkout" branches, and the
-bflag 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-featureas our example branch name.
git checkout -b my-feature
Verify we are on the new
react % git checkout -b my-feature
Switched to a new branch 'my-feature'
react % git branch
Now we can make commits on
my-featurethat build on the state of
mainwhen we created
my-feature. Changes on
my-featurewill not affect any other branch in our repo.
While working on feature branches we may wish to periodically checkout other branches such as
mainto verify our changes are still compatible with theirs. To change back to the
git checkout main. We may also wish to
git pullwhen on
mainto pull any new changes from GitHub to
git checkout my-featureto go back to the
Once done with our feature on our feature branch, we can merge our changes to
mainfor 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".
- 1.Checkout the branch we want to merge into. For example, if we want to merge changes on our feature branch to
git mergefollowed 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 logto view the merge commit and verify merge success.
- 4.Delete the feature branch locally with
git branch -dfollowed by the feature branch name, e.g.
git branch -d my-feature.
- 5.Once ready, push latest changes in
- 1.Checkout and verify we are on our feature branch with
git pushto 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 originfollowed 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-featureis 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: Create a pull request for 'my-feature' on GitHub by visiting:
* [new branch] my-feature -> my-feature
Branch 'my-feature' set up to track remote branch 'my-feature' from 'origin'.
upstreamrefers to where our code should be hosted.
originrefers to our GitHub repo or where we cloned our repo from.
my-featuretells Git to create a new branch called
my-featurein GitHub and by default push changes from the local
my-featurebranch to the GitHub
After setting upstream once for a branch, we can run
git pushwithout arguments for subsequent pushes from this branch.
In addition to merging feature branches to
main, another common workflow is to merge latest changes from
maininto 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
mainsince we started our feature.
git checkout mainand pull latest changes from GitHub with
- 2.Checkout our feature branch, e.g.
git checkout my-feature.
git merge mainto merge
maininto our feature branch. If we're lucky Git will merge the changes automatically. If not we will need to resolve merge conflicts manually.
Demo of how merge conflicts happen and how to resolve them
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
=======are changes from the branch we are on, and the lines surrounded by
>>>>>>> mainare changes from the incoming branch.
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.
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
After Git tells us we have merge conflicts, use
git statusto confirm which files have conflicts.
Open each file with conflicts and resolve conflicts in each file by removing lines starting with
>>>>>>>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.
VS Code gives us buttons above each conflict to conveniently resolve each conflict.
Once we have resolved all conflicts, verify our app still works as expected. Once satisfied with our changes,
git addthe resolved files to add them to staging area for commit.
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.
Commit changes to finalise Git's merge commit and complete merge.
Entering git commit after adding resolved files to staging area will open a commit message window. Save and close the file to complete commit.
git statusshould no longer mention conflicts.
Once we save the commit message file, we should see the commit completed.
We can verify merge success by checking commit history in Git Logs with
We can verify successful merge by looking at Git Logs.
- 1.Create a new repo.mkdir poemscd poemsgit 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
main.git checkout main
water-poem.txthas reverted to the version on
- 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.
mainand merge the water poem edits from the water poem branch.
water-poem.txtcontains changes from the water poem branch.
- 13.Delete the water poem branch with
git branch -d water-poem-edits.
- 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.
main. To create a merge conflict we will commit new changes to the same lines on the
- 6.Make a change to the sandwich poem and commit it.
- 7.Merge the sandwich branch into
- 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.