Context
On large projects, we often work in multiple contexts:
You're working on 2 different color scheme variations for your website at the same time, unsure of which you like best
You're also trying to fix a horrible bug, but it's proving tough to solve. You need to really hunt around and toggle some code on and off to figure it out.
A teammate is also working on adding a new chat widget to present at the next meeting. It's unclear if your company will end up using it.
Another coworker is updating the search bar autocomplete.
Another developer is doing an experimental radical design overhaul of the entire layout to present next month.
If they all work in a linear fashion(one commit after the next) this would be impossible and break other people’s code
Branches
Branches are an essential part of Git!
Think of branches as alternative timelines for a project.
They enable us to create separate contexts where we can try new things, or even work on multiple ideas in parallel.
If we make changes on one branch(files,folders,code), they do not impact the other branches (unless we merge the changes)
The Master Branch
In git, we are always working on a branch. The default branch name is master when we are working on a new git repository.
It doesn't do anything special or have fancy powers. It's just like any other branch.
Many people designate the master branch as their "source of truth" or the "official branch" for their codebase, but that is left to you to decide.
From Git's perspective, the master branch is just like any other branch. It does not have to hold the "master copy" of your project.
In 2020, Github renamed the default branch from master to main. The default Git branch name is still master, though the Git team is exploring a potential change.
Head
We'll often come across the term HEAD in Git.
HEAD is simply a pointer that refers to the current "location" in your repository. It points to a particular branch reference.
So far, HEAD always points to the latest commit you made on the master branch, but soon we'll see that we can move around and HEAD will change!
The most recent commit on our master branch is always referred to as head → master which means that the HEAD is pointing to the master branch
Each branch has a branch pointer and the HEAD is a pointer to a branch pointer which points to where the branch currently is.
Viewing Branches
Use
git branch
to view your existing branches. The default branch in every git repo is master, though you can configure this.You can also use -v option to view branches with last commits
Look for the * which indicates the branch you are currently on.
git branch git branch -v
Creating and Switching Branches
Use
git branch <branch-name>
to make a new branch based upon the current HEAD so where you make the branch, mattersThe branch name should not include spaces, separated by a colon and should be informative
This just creates the branch. It does not switch you to that branch (the HEAD stays the same)
You should always add and commit changes before switching branches
Once you have created a new branch, use
git switch <branch-name>
to switch to it. If you have unstaged changes, they may come with you or git may abort the changeThen HEAD will point to the <branch-name> and the master branch will be left behind
We can also use
git switch
with the -c flag to create a new branch AND switch to it all in one go. Remember -c as short for "create"git branch <branch-name> git switch <branch-name> git switch -c <branch-name>
Historically, we used
git checkout <branch-name>
to switch branches. This still works.The checkout command does a million additional things, so the decision was made to add a standalone switch command which is much simpler
Deleting and Renaming Branches
You can use the -d option with git branch to delete a branch. You cannot delete a branch you are currently on.
To forcefully delete a branch use the -D option
You can rename a branch using the -m option and you have to be on the branch that you want to rename.
git branch -d deleteMe git branch -D deleteMe git branch -m deleteIt
Merging Branches
Branching makes it super easy to work within self-contained contexts, but often we want to incorporate changes from one branch into another!
We treat the master branch as the most stable build of an application where you don’t want to screw anythings up so people work on a feature branch and then that work is incorporated back into the master branch if it is useful
We can do this using the
git merge
commandWe merge branches, not specific commits
We always merge to the current HEAD branch
Both branches will still remain separate after merging
To merge, follow these basic steps:
Switch to or checkout the branch you want to merge the changes into (the receiving branch)
Use the
git merge
command to merge changes from a specific branch into the current branch.git switch master git merge bugfix
This Is Called A Fast-Forward. The Master branch simply caught up/fast-forwarded on the commits from Bugfix
Not All Merges Are Fast Forwards! What if we add a commit on master?
- Rather than performing a simple fast forward, git performs a "merge commit" We end up with a new commit on the master branch. Git will prompt you for a message. The new commit will have two parents
Resolving Merge Conflicts
Depending on the specific changes you are trying to merge, Git may not be able to automatically merge.
This results in merge conflicts, which you need to manually resolve.
When you encounter a merge conflict, Git warns you in the console that it could not automatically merge.
The content from your current HEAD (the branch you are trying to merge content into) is displayed between the <<<<<<< HEAD and =======
The content from the branch you are trying to merge from is displayed between the ======= and >>>> symbols.
<<<<<<< HEAD I have 2 cats I also have chickens ======= I used to have a dog :( >>>>>>> bug-fix
Whenever you encounter merge conflicts, follow these steps to resolve them:
Open up the file(s) with merge conflicts
Edit the file(s) to remove the conflicts. Decide which branch's content you want to keep in each conflict. Or keep the content from both.
Remove the conflict "markers" in the document
Add your changes and then make a commit using the message “resolve conflicts”!
Or you can use VSCode to resolve the conflicts