TT Lab
Get started
Learn Learning paths Courses

Git in Practice

Branching Strategy in Practice

Continue in TT Lab

Goal

You create a repository from scratch, see with your own eyes how the results of three merge methods (no-ff merge, fast-forward, cherry-pick) remain differently in the history, then count the results as numbers and write a strategy comparison table.

Why it matters

Arguments about branching strategy usually end as a fight over taste. But the real question that decides is one: when an outage happens, how do we plan to find the culprit commit in this repository? A --no-ff merge leaves "when this bundle was integrated", fast-forward gives a straight-line history but erases the integration point, and a squash merge fixes the bisection resolution at the PR size and makes it so that, from Git's point of view, the branch has never been merged. This difference stays with you not by reading an explanation but by counting with git rev-list --min-parents=2.

Steps

This image has no global git identity configured. In every repository you create, if you do not set git config user.email / git config user.name locally, commits fail.

  1. Create a repository at /root/gitx1/repo. The current branch must be main, this repository must have a local user.email and user.name set, and there must be at least 1 commit containing README.md.
  2. Create a feature/login branch and stack 2 commits. The commit subjects must be exactly login: form and login: validation, and the branch must have a login.txt file. There must be exactly 2 commits that start with login: .
  3. Move to main and merge feature/login so that a merge commit remains (a commit with two parents). After the merge, main must have login.txt.
  4. From main, create a feature/quick branch and make one commit that adds quick.txt. The subject is exactly quick: typo. Then merge it into main by fast-forward only. This commit must have 1 parent, and the number of merge commits on main must remain the 1 created in step 3.
  5. At the current position of main, attach an annotated tag v1.0.0. The tag message must not be empty.
  6. From the point v1.0.0, create a release/1.0 branch and make a commit that adds hotfix.txt. The subject is exactly hotfix: null guard. Then apply the same change to main as well. Conditions: the contents of hotfix.txt on the two branches must be the same, both must have a hotfix: null guard commit, but the hashes of the two commits must be different.
  7. Clean up the branches. Delete feature/quick, keep feature/login, and create a new feature/wip branch and stack at least 1 commit on it that is not in main (it must still be unmerged).
  8. Write /root/gitx1/strategy.md. It must include:
    • merge_commits= — the number of merge commits on main
    • branches= — the number of local branches in this repository
    • tags= — the number of tags
    • An explanation of the three strategies: Git Flow / GitHub Flow / Trunk-Based
    • A judgment of which strategy this repository is closest to (one of the expressions 'this repository', 'we' or 'currently' must appear)

Notes

Create the repository and set the identity

Create a repository at /root/gitx1/repo. The current branch must be main, this repository must have a local user.email and user.name set, and there must be at least 1 commit containing README.md.

Run git init in /root/gitx1/repo, but make the default branch name main. This image has no global git identity, so if you do not set user.email and user.name directly in this repository, the commit itself fails.

Stack 2 commits on a feature branch

Create a feature/login branch and stack 2 commits. The commit subjects must be exactly login: form and login: validation, and the branch must have a login.txt file. There must be exactly 2 commits that start with login: .

Create the feature/login branch and commit login.txt in two parts. The commit subjects must be exactly the same as the instructed strings, and there must be exactly 2 commits that start with login:.

Merge without fast-forward

Move to main and merge feature/login so that a merge commit remains (a commit with two parents). After the merge, main must have login.txt.

Move to main and merge feature/login, but merge it so that a commit with two parents remains. A plain merge fast-forwards and the integration record disappears.

Raise a small fix by fast-forward

From main, create a feature/quick branch and make one commit that adds quick.txt. The subject is exactly quick: typo. Then merge it into main by fast-forward only. This commit must have 1 parent, and the number of merge commits on main must remain the 1 created in step 3.

Create feature/quick, commit quick.txt, and merge into main by fast-forward only. If a merge commit is created, this step fails. If you use --ff-only, it refuses altogether when the condition is not met.

Attach a release tag

At the current position of main, attach an annotated tag v1.0.0. The tag message must not be empty.

Attach the v1.0.0 tag to main. A lightweight tag is just a pointer, so the author and message are not kept. Use the option that creates a tag object.

Bring the release branch hotfix into main

From the point v1.0.0, create a release/1.0 branch and make a commit that adds hotfix.txt. The subject is exactly hotfix: null guard. Then apply the same change to main as well. Conditions: the contents of hotfix.txt on the two branches must be the same, both must have a hotfix: null guard commit, but the hashes of the two commits must be different.

Create release/1.0 from v1.0.0, commit hotfix.txt, and then apply the same change to main as well. Do not merge the whole branch; bring over just that one commit.

A cherry-pick re-applies the change and creates a new commit — it does not move anything. However, as in this lab, when release/1.0 was branched right at the tip of main, the parents of the two commits are the same. So use git cherry-pick -x. One line, (cherry picked from commit ...), is added to the message, so where it came from remains in the history, and thanks to that line the commit objects are also reliably distinguished. This is exactly the approach recommended in practice when applying a hotfix to several branches.

Clean up only the merged branches

Clean up the branches. Delete feature/quick, keep feature/login, and create a new feature/wip branch and stack at least 1 commit on it that is not in main (it must still be unmerged).

Delete branches that have already been merged and keep branches that have not. First check what can be safely deleted with git branch --merged main. Using -d instead of -D prevents the accident of deleting an unmerged branch by mistake.

Count the repository state and write the strategy comparison table

Write /root/gitx1/strategy.md. It must include:

In /root/gitx1/strategy.md, write the three lines merge_commits= / branches= / tags= with values counted in the actual repository, compare the three branching strategies, and then write a judgment of which this repository is closest to. Count the numbers with git commands.