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

Safe experiments: working with branches

C# SELF
Level 26 , 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 lets you run multiple lines of development in parallel inside one repository. Branching makes Git a powerful tool for collaboration, experiments, 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 branches off the main branch main for safe development. After the work is done it gets merged back into main.

Imagine you want to seriously rework something in your project or run a risky experiment. How would you do it without Git? Most likely you'd copy the whole project into a new folder and work there. If the result is good — you'd move it into the main folder. If not — you'd just delete the copy.

Branches in Git work on the same idea, but way more elegantly. Let's look at an example of writing a book:

  1. You have a finished manuscript (that's your main branch main).
  2. You want to write an alternate ending (you create a new branch, e.g. feature/new-idea).
  3. You write the new ending without touching the main manuscript (you work in the new branch).
  4. If the new ending is better, you replace the old one with it (you merge branches — merge).
  5. The old draft with the unwanted 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 top IDE panel there's a widget showing the current branch name (by default — main). Click it and choose + New Branch.

Step 2. Name your new branch.

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

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

Step 3. Make and commit changes.

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

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 again.

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

Step 3. Check the result.

As soon as you switch, open README.md. You'll see that the usage examples section is not there! It stayed in the other branch. This way you can work on new features without touching the stable version in main.

4. Merging branches (Merge)

The merge command takes all commits from branch feature/add-examples (in this case commit C3) and combines them into the current branch main, 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 your task in branch feature/add-usage-examples and want to add those changes into the main project.

Step 1. Switch to the target branch.

Make sure you're on the branch you want to add changes TO. In our case that's main.

Step 2. Perform the merge.

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

Step 3. Check the result.

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

5. Merge conflicts: don't be afraid, it's normal!

Sometimes conflicts happen when merging branches. This occurs when the same lines in the same file were changed in both branches. Git can't decide which version is correct and asks for your help.

            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) based on a common ancestor (C1). This will definitely cause a conflict when merging.

Let's simulate a conflict:

  1. Make sure you're on branch main and have no uncommitted changes.
  2. Immediately create a new branch feature/new-title but don't check it out yet. Make sure the Checkout branch checkbox is unchecked.
  3. Now, while on main, change the first line in README.md to "My Awesome Project" and make a commit.
  4. Switch to feature/new-title. You'll see the first line in README.md stayed old: that's the file state at branch creation. Change that same line to "My Super Project" and make a commit.
  5. Return to main and merge feature/new-title.

Now Git sees both branches have new, diverging histories from their common ancestor. The same line was changed in both histories, so Git can't pick which version is right and will show you the conflict resolution window.

Merge Revision

What you see here:

  • Left (Your changes): the file version from your current branch (main).
  • Right (Changes from branch...): the file version from the branch you're merging.
  • Center (Result): the final file version you need to assemble.

You can click the arrows >> or << to accept an entire side.

When the center result satisfies you, click Apply. The IDE will create the merge commit for you and the conflict will be resolved.

Why no conflict happened?

There may be a situation where you followed all steps but no conflict occurred. Most often that's because Git was able to do a fast-forward merge, since one branch's history simply continued the other's. For a guaranteed conflict the branches' histories must diverge from the common ancestor in different ways.

Example:

  1. You have some commit on main (call it C1).
  2. You make a new commit on main with text "My Awesome Project". Now main points to commit C2 (main -> C1 -> C2).
  3. You create branch feature/new-title from the current main. That means the new branch also starts from commit C2.
  4. You commit on feature/new-title with text "My Super Project". This branch moves forward and now points to commit C3 (feature/new-title -> C1 -> C2 -> C3).
  5. You go back to main (still at C2) and request to merge feature/new-title.

Git looks and sees that main is a direct ancestor of feature/new-title. No new commits were added to main while you worked in the other branch. Git thinks: "Oh, just fast-forward main to C3. No conflicts." And it simply moves the main pointer to commit C3.

            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 change history

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

Open the Git tab at the bottom of the IDE and select Log. You'll see a graphical representation of all your branches and commits. This helps you visually track which branch branched from where and where they were merged.

There you can click any commit to see what changes went into it, 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