CodeGym /Courses /C++ SELF /Safe experiments: working with branches

Safe experiments: working with branches

C++ SELF
Level 36 , Lesson 2
Available

1. What are branches and why do you need them?

Working with branches in Git — is one of the key aspects of version control that allows you to run multiple development lines in parallel within a single repository. Branching makes Git a powerful tool for collaboration, experimentation, and managing different versions of a project.

            gitGraph
            commit id: "Initial setup"
            commit id: "Add base features"
            branch feature/new-idea
            checkout feature/new-idea
            commit id: "Implement new logic"
            commit id: "Refactor the logic"
            checkout main
            commit id: "Urgent bugfix on main"
            merge feature/new-idea
            commit id: "Prepare for release"
        
A new branch feature/new-idea diverges from the main branch main for safe development. After the work is done it gets merged back into main.

Imagine you want to make a major change in your project or run a risky experiment. How would you do that without Git? Most likely you would copy the whole project to a new folder and work there. If the result is good — you would move it to the main folder. If not — you would simply delete the copy.

Branches in Git work on the same principle but much more elegantly. Let's consider an example of writing a book:

  1. You have a finished manuscript (this is your main branch main).
  2. You want to write an alternative ending (you create a new branch, for example feature/new-idea).
  3. You write the new ending without touching the main text (you work in the new branch).
  4. If the new ending turns out better, you replace the old one with it (you merge the branches — merge).
  5. The old draft with the unnecessary ending can be deleted (you delete the branch).

2. Creating a new branch and working in it

Step 1. Open the branch management menu.

On the main toolbar, next to the project name, there is a widget that shows the current branch name (by default — main). Click it and select + New Branch.

Branches widget in the top-left corner

Step 2. The new branch name.

Good practice is to name branches according to the task you are solving. For example, feature/add-usage-examples.

New branch creation dialog

After creating the branch the IDE will automatically switch to it. You will see the new name in the same widget.

Step 3. Make and commit changes.

Now you are in your "sandbox". Let's add a new section with usage examples to our README.md file. Make the changes and create a commit, as you learned in the previous lecture.

Commit in the new branch

3. Switching between branches

Your changes with usage examples are now safely stored in the feature/add-usage-examples branch. Let's go back to the main branch main and see what's there.

Step 1. Click the widget with the current branch name in the top-left corner again.

Step 2. In the Local or Recent list select the main branch, and in the submenu click Checkout.

Switching to the main branch

Step 3. Check the result.

Once you switch, open the README.md file. You will see that the usage examples section is not there! It remained in the other branch. This way you can work on new functionality without affecting the stable version in the main branch.

File unchanged from another branch

4. Merging branches

The merge command takes all commits from the feature/add-usage-examples branch (in this case commit C3) and combines them with the current main branch, creating a new merge commit.

            gitGraph
            commit id: "C1"
            commit id: "C2"
            branch feature/add-examples
            checkout feature/add-examples
            commit id: "C3: Add new section"
            checkout main
            merge feature/add-examples
        

So, you've finished work on your task in the feature/add-usage-examples branch and want to add these changes to the main project.

Step 1. Switch to the target branch.

Make sure you are on the branch you want to add changes TO. In our case it is main.

Step 2. Perform the merge.

Click the branch management widget again. In the list select the branch you want to take changes FROM (feature/add-usage-examples), and in the submenu choose Merge 'feature/add-usage-examples' into 'main'.

Performing a branch merge

Step 3. Check the result.

Now your new usage examples section appears in the README.md file on the main branch. You have successfully merged your work into the main project!

Successful merge

5. Merge conflicts

For newcomers the word "conflict" often sounds scary, but in team development it is totally normal. A conflict happens when the same lines in the same file were changed in both branches being merged. Git cannot decide which version is correct and asks for your help.

This is where the full power of IntelliJ IDEA (and CLion) shows up. Resolving conflicts in the terminal can be unpleasant, but the IDE's built-in three-way merge tool makes this task visual and simple.

            gitGraph
            commit id: "C1: Common base"
            branch feature/new-title
            checkout main
            commit id: "C2: Change in main"
            checkout feature/new-title
            commit id: "C3: Change in feature"
        
Both branches, main and feature/new-title, have new commits (C2 and C3) that are based on a common ancestor (C1). This will certainly lead to a conflict when merging.

Let's simulate a conflict:

  1. Make sure you are on the main branch and you have no unstaged changes in the Commit tool window.
  2. Create a new branch feature/new-title, but do not switch to it yet. Make sure the Checkout branch checkbox is unchecked.
  3. Now, while staying on main, change the first line in README.md to “My Awesome Project” and commit it.
  4. Switch to the feature/new-title branch. You will see that the first line in README.md here is still the old one: that's the file state at the time the branch was created. Change that same line to “My Super Project” and commit it.
  5. Return to the main branch and merge feature/new-title.

Now Git will see that both histories changed the same place. It will show you the merge conflict resolution window (Merge Conflicts).

Conflict detection window

Click the Merge button to open the conflict resolution tool. What you see here:

  • Left (Your changes): the file version from your current branch (the branch you are merging into — main).
  • Right (Changes from branch): the file version from the branch being merged.
  • Center (Result): the resulting file version you must assemble manually.
Three-way merge conflict window

You can click the arrows >> or << (or the crosses to cancel) to accept one variant entirely. You can also simply type the correct text in the central panel.

When the result in the center panel satisfies you and all conflicts are resolved, click Apply (or Save Changes and Finish). The IDE will create a special merge commit for you and the conflict will be resolved.

Why sometimes there is no conflict?

It may happen that you followed all the steps but no conflict occurred. Most often this is because Git was able to perform a fast-forward merge. This happens when the history of one branch simply continued the history of the other and they did not diverge in parallel.

Example:

  1. You have some commit in main (say, C1).
  2. You make a new commit in the main branch with the text “My Awesome Project”. The main branch now points to commit C2 (main -> C1 -> C2).
  3. You create the feature/new-title branch from the current position of main. That means the new branch also starts from commit C2.
  4. You make a commit in feature/new-title with the text “My Super Project”. That branch moves forward and now points to commit C3 (feature/new-title -> C1 -> C2 -> C3).
  5. You go back to main (which is still at commit C2) and command merge feature/new-title.

Git looks at the situation and sees that main is a direct ancestor of feature/new-title. There were no new commits on main while you worked on the other branch. Git thinks: "Ah, we just need to fast-forward main to commit C3. No conflicts." And it simply moves the main pointer to C3 without conflicts.

            gitGraph
            commit id: "C1"
            commit id: "C2"
            branch feature/new-title
            checkout feature/new-title
            commit id: "C3"
            checkout main
            merge feature/new-title
        

6. Viewing the history of changes

To better understand what's happening in your project, it's useful to look at its history.

Open the Git tool window (usually an icon on the left sidebar or at the bottom of the IDE) and select the Log tab or click Show Git Log in the Git toolbar. You will see a graphical representation of all your branches and commits. This helps visualize which branch diverged from which and where they were merged.

Git log window

Here you can click any commit to see which changes it contains, who made it and when. It's a real time machine for your code!

Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION