Git - Managing Branches
Git - Managing Branches
Section titled “Git - Managing Branches”Branches in Git are incredibly lightweight and fundamental to modern development workflows. A branch represents an independent line of development. You can use branches to work on new features, bug fixes, or experiments without affecting the main codebase (e.g., the main branch). Once work on a branch is complete, it can be merged back into the main branch.
For example, if you’re releasing version 1.0 of your software from the main branch, you might create a develop branch for version 2.0 features, and separate feature branches off develop. Meanwhile, bug fixes for version 1.0 can be made on a hotfix branch created from main.
Create a Branch
Section titled “Create a Branch”Tom wants to create a new branch named new-feature. He can use the git branch <branch-name> command. This creates the new branch pointing to the current commit (HEAD), but doesn’t switch to it.
[tom@dev-machine project/src]$ git branch new-feature
[tom@dev-machine project/src]$ git branch* main new-featureThe git branch command lists all local branches. The asterisk * indicates the currently checked-out branch. Visually, if main was at commit C3: ... -> C1 -> C2 -> C3 (HEAD -> main). After git branch new-feature, it becomes: ... -> C1 -> C2 -> C3 (HEAD -> main, new-feature).
Switch Between Branches
Section titled “Switch Between Branches”Jerry uses the git switch <branch-name> command (or the older git checkout <branch-name>) to switch to an existing branch. This updates the files in the working directory to match the snapshot of the commit the branch points to, and updates HEAD to point to this branch.
[jerry@dev-machine project/src]$ git switch new-featureSwitched to branch 'new-feature'
[jerry@dev-machine project/src]$ git branch main* new-featureNow, HEAD points to new-feature.
Shortcut: Create and Switch Branch
Section titled “Shortcut: Create and Switch Branch”A common workflow is to create a new branch and immediately switch to it. You can do this in one step using git switch -c <branch-name> or git checkout -b <branch-name>.
[jerry@dev-machine project/src]$ git switch -c test-branchSwitched to a new branch 'test-branch'
[jerry@dev-machine project/src]$ git branch main new-feature* test-branchDelete a Branch
Section titled “Delete a Branch”Once a feature branch has been merged and is no longer needed, you can delete it using git branch -d <branch-name>. The -d option will only delete the branch if its changes have been merged. Use -D to force delete an unmerged branch (use with caution).
Jerry is currently on test-branch and wants to delete it. He first switches to another branch (e.g., main).
[jerry@dev-machine project/src]$ git branch main new-feature* test-branch
[jerry@dev-machine project/src]$ git switch mainSwitched to branch 'main'
[jerry@dev-machine project/src]$ git branch -d test-branchDeleted branch test-branch (was 5776472).Now, git branch will show only main and new-feature.
Rename a Branch
Section titled “Rename a Branch”To rename a branch, use git branch -m <old-name> <new-name>. If you are currently on the branch you want to rename, you can use git branch -m <new-name>.
[jerry@dev-machine project/src]$ git branch* main new-feature
[jerry@dev-machine project/src]$ git branch -m new-feature feature/wchar-support
[jerry@dev-machine project/src]$ git branch* main feature/wchar-supportMerge Two Branches
Section titled “Merge Two Branches”Merging takes the changes from one branch and integrates them into another. Typically, you merge a feature branch back into your main development branch (e.g., main or develop).
Jerry has been working on the feature/wchar-support branch and implemented a w_strlen function. After committing his changes to this branch, the history might look like: ...C2 -> C3 (main) -> C4 -> C5 (HEAD -> feature/wchar-support) where C4 and C5 are commits on the feature branch.
He commits his changes on feature/wchar-support:
[jerry@dev-machine src]$ git switch feature/wchar-support[jerry@dev-machine src]$ # ... makes changes to string_operations.c ...[jerry@dev-machine src]$ git add string_operations.c[jerry@dev-machine src]$ git commit -m "Added w_strlen for wide char support"[feature/wchar-support 64192f9] Added w_strlen for wide char support 1 file changed, 10 insertions(+)
[jerry@dev-machine src]$ git push origin feature/wchar-supportTom wants to integrate Jerry’s w_strlen function into the main branch. First, Tom ensures his main branch is up-to-date and then checks out main. Then he uses git merge.
[tom@dev-machine project]$ git switch mainSwitched to branch 'main'[tom@dev-machine project]$ git pull origin main # Ensure main is up-to-date
[tom@dev-machine project]$ git fetch origin # Fetch latest changes from remote, including Jerry's branch
[tom@dev-machine project]$ git merge origin/feature/wchar-supportUpdating 5776472..64192f9Fast-forward src/string_operations.c | 10 ++++++++++ 1 file changed, 10 insertions(+)In this case, Git performed a ‘fast-forward’ merge. This happens when the main branch hasn’t diverged from the feature/wchar-support branch since it was created. main simply moves its pointer forward to the latest commit of feature/wchar-support. The history becomes linear: ...C2 -> C3 -> C4 -> C5 (HEAD -> main, origin/feature/wchar-support).
If main had new commits not present in feature/wchar-support, Git would create a new ‘merge commit’ to tie the two histories together. This commit has two parents.
After testing, Tom pushes the updated main branch to the remote:
[tom@dev-machine project]$ git push origin mainRebase Branches
Section titled “Rebase Branches”git rebase is another way to integrate changes from one branch to another. Instead of creating a merge commit, rebase rewrites the commit history by taking all commits from your current branch and replaying them, one by one, on top of another branch (the base).
Imagine your main branch has commits A-B-C. You branched off main at C to create my-feature and added commits X-Y. So, my-feature is A-B-C-X-Y. Meanwhile, main has advanced with new commits D-E, so main is A-B-C-D-E.
If you run git rebase main while on my-feature, Git will take your commits X-Y, and re-apply them on top of main’s latest commit E. Your my-feature branch will now look like A-B-C-D-E-X’-Y’ (X’ and Y’ are new commits with the same changes but different IDs because their base changed). This results in a linear history, which some teams prefer.
Example: [jerry@dev-machine project]$ git switch my-feature then [jerry@dev-machine project]$ git rebase main.
Warning: Rebasing rewrites history. Never rebase commits that have already been pushed to a shared remote branch and are being used by others, as it will cause inconsistencies and problems for them. It’s generally safe to rebase your own local branches that haven’t been shared, or to rebase a feature branch onto an updated main/develop branch before merging (often done via git pull --rebase).