Branching
Branching in Git allows developers to create separate lines of development, making it easier to work on new features, bug fixes, or experiments without affecting the main codebase.
Branches
Commands
git branch- show all local branches in the repository, current branch marked with and asterisk(*).git branch -a- Lists both local and remote branches.git branch <branch-name>- Creates a new branch but does not switch to it.git branch -m <new-name>- rename current branch.git branch -m <old-name> <new-name>- rename specific branch.git branch -d <branch-name>- Deletes a local branch (only if it has been merged). If the branch contains unmerged changes, Git will prevent deletion.git branch -D <branch-name>- Forcefully deletes a branch, even if it has unmerged changes.git branch -v- Displays the latest commit message for each branch.git branch --merged-- `` - Lists branches that have already been merged into the current branch.
git branch --no-merged- Lists branches that have not been merged yet.git branch -r- Lists remote branches.git branch --show-current- Check the current branch.
Switching Branches
Commands
git checkout <branch-name>- Moves to the specified branch. Updates the working directory to match the branch's latest commit.git checkout -b <new-branch>- Creates a new branch and immediately switches to it.git checkout <commit-hash>- Moves to a previous commit in "detached HEAD" mode. This means you are not on any branch, just viewing an old commit.git checkout <branch-name> -- <file-path>- Restores a specific file from another branch without switching branches.git checkout -- <file-path>- Resets a file to its last committed state.git checkout HEAD -- <file-path>- Recovers a deleted file that was last committed.git checkout HEAD .- Resets all files in the working directory to the last committed version.
Merging Branches
It combines the commit history of two branches and creates a new merge commit.
Commands
git merge <branch-name>- Merges<branch-name>into the current branch. Creates a new commit combining changes from both branches.git merge --ff <branch-name>- If possible, Git moves the branch pointer forward without creating a merge commit(Fast-Forward Merge). Works only if there are no diverging commits.git merge --no-ff <branch-name>- Forces Git to create a merge commit(No Fast-Forward) even if a fast-forward merge is possible. Preserves branch history.git merge --commit <branch-name>- Merges the branch and immediately creates a merge commit. This is the default behavior.git merge --no-commit <branch-name>- Merges changes but does not create a merge commit. Allows reviewing or modifying files before committing.
Fast-Forward Merge
A Fast-Forward Merge happens when there is a linear commit history between branches. In this case, Git simply moves the branch pointer forward to the latest commit of the merged branch instead of creating a new merge commit.
When Fast-Forward Merge Happens
- The feature branch is ahead of the main branch.
- No new commits were made on the main branch after branching.
Example
- Just commited in main branch.
- Created new branch.
- Make some changes in new branch.
- Committed the changes.
- Merge main and new branch.
Since main has not progressed after the branch was created, Git moves the main pointer to the latest commit of new-branch, effectively "fast-forwarding" it.
Output:
Updating f3a29c1..e3a1b5c
Fast-forward
file.txt | 1 +
Fast-Forward Merge Visualization
Before Merge:
main: A --- B (Feature Branch)
|
v
A (Main Branch)
After Merge:
main: A --- B (Both Branches Point Here)
Since no new commits were added to main, it simply moves forward.
Recursive Merge
A Recursive Merge happens when both branches have diverged, meaning there are commits on both branches that are not shared.
When Recursive Merge Happens
- Both branches have new commits since they diverged.
- A new merge commit is created to combine the histories.
Example
- Just commited in main branch.
- Created new branch.
- Make some changes in new branch.
- Switch back to main branch and make some changes as well.
Now, both main and new-branch have unique commits.
Since both branches have diverged, Git performs a recursive merge and creates a new merge commit.
Output:
Merge made by the 'recursive' strategy.
Recursive Merge Visualization
Before Merge:
main: A --- C (Main Branch)
\
B --- D (Feature Branch)
After Merge:
main: A --- C --- M (Merge Commit)
\ /
B --- D (Feature Branch)
The merge commit M combines the histories.