Branching and Merging
git branch
Description
It is used to manage branches in a Git repository. It allows you to create, list, rename, and delete branches.
Usage
<branch-name>
: The name of the branch to create, rename, delete, or list.<start-point>
: (Optional) A commit, tag, or branch from which the new branch will start. Defaults to the current HEAD if not specified.
Options
-d
or --delete
: Deletes the specified branch. It must be fully merged in its upstream branch or in HEAD.
-D
: Forcefully deletes the specified branch, even if it has unmerged changes
-m
or --move
: Renames the current branch or a specified branch.
-r
or --remotes
: Lists remote-tracking branches.
-a
or --all
: Lists both local and remote branches.
--list
: Allows for pattern matching.
Branch Naming: Use descriptive branch names to make it clear what the branch is for (e.g., feature-login
, bugfix-issue123
, release-v1.0
).
Branch Lifecycle: Typically, you'll create a branch to work on a new feature or bug fix, merge it back into the main branch when done, and then delete it to keep your branch list clean.
Remote Branches: Working with remote branches involves using git fetch
, git pull
, and git push
to synchronize changes between local and remote repositories.
Common Use Cases
Example Workflow
Example Output
When running git branch
git checkout
Description
It is used for switching between branches, creating new branches, and checking out specific commits or files from your Git history. Although many of its functions have been replaced or supplemented by git switch
and git restore
, git checkout
is still a fundamental Git command with versatile uses.
Usage
Options
-b <new-branch>
: Creates a new branch and switches to it.
-B <new-branch>
: Creates a new branch (or resets an existing branch) to the current commit and switches to it.
-f
or --force
: Forces the checkout, discarding local changes.
--ours
/ --theirs
: During a merge conflict, checks out our/their version of a conflicted file.
If we want to checkout remote branch i.e. create new branch and add remote origin reference to it, then create a new branch in remote (Gitlab etc) via UI and do git pull in local to get reference to remote branch. Then we will be able to run checkout remote branch and git push, pull etc will work.h
Using git switch
and git restore
: For switching branches and restoring files, Git introduced git switch
and git restore
to make commands more intuitive.
Switch branches: git switch branch-name
Create and switch to a new branch: git switch -c new-branch
Restore files: git restore path/to/file
Detached HEAD State: Checking out a specific commit (not a branch) puts us in a detached HEAD state. Any commits made in this state are not associated with any branch and can be lost if not handled properly. See the detached head workflow below.
Example Workflows
Workflow involving creation of new branch
Workflow involving detached head and how to recover
Detached HEAD State: Be cautious when working in a detached HEAD state. If we make commits and do not create a new branch, these commits can be lost when we switch branches.
Example Output
When running git checkout branch-name
When creating and switching to a new branch with git checkout -b new-branch
git merge
Description
It is used to combine changes from different branches into a single branch. This is an essential feature for collaborative workflows, where multiple contributors work on different features or fixes in separate branches and then need to integrate these changes into a main branch.
Fast-forward Merges: These occur when the current branch has no new commits since the branch being merged was created, making it unnecessary to create a merge commit.
Three-way Merges: These occur when both branches have new commits since the last common ancestor, requiring Git to create a merge commit to combine the changes.
Merge Conflicts: Conflicts arise when changes in the two branches overlap. Git marks these conflicts in the files, and they must be resolved manually.
Usage
<branch>
: The branch that we want to merge into your current branch.
Options
--no-ff
: Creates a merge commit even if the merge resolves as a fast-forward. This preserves the feature branch's history.
--ff-only
: Ensures that the merge can only happen if it's a fast-forward merge. If not, the merge is aborted.
-squash
: Combines all changes from the branch being merged into a single commit on the target branch.
-m <message>
: Allows you to specify a commit message for the merge commit.
What It Does
Fast-forward Merge: If the current branch has not diverged from the branch being merged, Git simply moves the current branch pointer forward.
Three-way Merge: If the branches have diverged, Git performs a three-way merge using the common ancestor of the two branches. This can result in merge conflicts that need to be resolved manually.
Common Use Cases
Example Workflow
Example Output
When running git merge feature-branch
If a merge commit is created (for a three-way merge)
Merge Conflicts
If there are conflicting changes in the branches being merged, Git will highlight these conflicts, and we'll need to resolve them manually. After resolving conflicts, we need to stage the changes and complete the merge with -
Resolve Git Merge Conflicts
Merge conflicts occur when changes from different branches interfere with each other and Git can't automatically combine them. Resolving merge conflicts involves identifying conflicting changes, deciding which changes to keep, and then completing the merge process.
Example Workflow to Resolve Merge Conflicts
Tips for Resolving Conflicts
Use a Merge Tool: Tools like
kdiff3
,meld
, or IDE-integrated tools can help visualize and resolve conflicts.Commit Often: Smaller, frequent commits make it easier to resolve conflicts.
Communicate: Coordinate with your team to avoid overlapping changes.
Test Thoroughly: After resolving conflicts, ensure that the project works as expected.
git switch
Description
It is used to switch branches or restore working tree files. It was introduced to provide a more intuitive and focused way to switch branches compared to git checkout
, which can be confusing due to its multiple functionalities.
Usage
Options
-c <new-branch>
or --create <new-branch>
: Creates a new branch and switches to it.
-C <new-branch>
or --create-force <new-branch>
: Creates a new branch and switches to it, or resets an existing branch to start from the current HEAD.
--detach
: Switches to the specified commit without creating a new branch, putting you in a detached HEAD state.
-d
or --discard-changes
: Discards local changes in the working directory when switching branches.
--force
or -f
: Forces the switch, discarding local changes if necessary.
What It Does
Switches to an Existing Branch: Changes the current working branch to another specified branch.
Creates and Switches to a New Branch: Creates a new branch and switches to it in one command.
Detached HEAD State: Using git switch --detach commit-sha
puts you in a detached HEAD state, meaning you are not on a branch. Any commits made in this state are not associated with any branch and can be lost if not handled properly.
Switch vs. Checkout: While git switch
focuses on changing branches, git checkout
can also be used to check out files or commits. Git introduced git switch
and git restore
to make these operations more intuitive:
git switch
for switching branches.git restore
for restoring files.
Common Use Cases
Example Workflow
Example Output
When running git switch branch-name
When creating and switching to a new branch with git switch -c new-branch
git restore
Description
It is used to restore working tree files. It was introduced to provide a more focused way to undo changes and restore files compared to the multi-functional git checkout
command.
Usage
Options
--source=<tree>
: Specifies the source from which to restore the file. This can be a commit hash, branch name, tag, etc.
--staged
: Restores the specified file(s) from the staging area, effectively unstaging them.
--worktree
: Restores the specified file(s) in the working directory. This is the default behavior.
--force
or -f
: Forcefully restores the file, discarding any uncommitted changes.
What It Does
Restores Files to Their Last Committed State: Discards changes in the working directory, reverting files to their state at the last commit.
Unstages Files: Moves files from the staging area back to the working directory.
Restores Files from a Specific Commit: Reverts files to their state at a specific commit.
Safety: git restore
is a safer way to handle file restoration compared to git checkout
, as it is more explicit in its intentions and helps avoid unintended switches between branches or commits.
Common Use Cases
Example Workflow
Example Output
When running git restore file.txt
, we might see no output if the command succeeds, and the file will be reverted to its last committed state. If there are errors, such as the file not being in the specified source, Git will inform you of the issue.
git rebase
Description
It is used to integrate changes from one branch into another. It is an alternative to merging, but instead of creating a new commit that combines the changes from the branches, rebasing moves or reapplies commits from one branch onto another. This results in a cleaner, linear project history.
Usage
Options
-i
or --interactive
: Starts an interactive rebase session where you can edit, reorder, squash, or drop commits.
--continue
: Continues the rebase process after conflicts have been resolved.
-skip
: Skips the current commit and proceeds with the rebase
--abort
: Aborts the rebase process and resets the branch to its state before the rebase started.
--onto <newbase>
: Rebases the commits onto a new base.
What It Does
Moves Commits: Takes the commits from your current branch and applies them onto another branch.
Reapplies Commits: The commits are reapplied one by one on top of the new base commit.
Linear History: Rebasing is often used to maintain a linear project history, making it easier to follow and review.
Rewriting History: Rebase changes commit hashes, effectively rewriting history. This can cause issues if you rebase commits that have already been pushed to a shared repository.
Interactive Rebase: Interactive rebasing is powerful for cleaning up commits, such as combining multiple commits into a single commit or editing commit messages
Common Use Cases
Example Workflow
Example Output
When running git rebase main
If a conflict occurs, Git will provide instructions.
Rebase vs Merge
Feature | Git Rebase | Git Merge |
---|---|---|
Purpose | Reapply commits on top of another base branch | Combine the histories of two branches |
History | Creates a linear, cleaner history | Creates a history with merge commits |
Commit Hashes | Changes commit hashes (rewrites history) | Preserves commit hashes |
Usage Scenario | Clean up feature branch before merging into main | Regularly integrating changes from one branch to another |
Conflicts | Must be resolved during the rebase process | Must be resolved during the merge process |
Branch State After | Current branch starts from the tip of the target branch | Current branch includes a merge commit |
Merge Commits | No merge commits; commits are replayed individually | Creates a merge commit |
Local/Remote | Best for local branch integration | Commonly used for both local and remote integration |
Impact on History | Rewrites commit history | Adds to commit history |
Interactive Option | Supports interactive rebase to edit, squash, reword commits | Does not support interactive merges |
Conflicts Resolution | Conflicts need to be resolved as they appear and then continue | Conflicts resolved once during merge |
Usage Command |
|
|
Typical Use Case | Clean up commit history before merging feature branches | Regular updates and integration of branches |
Visual History | Linear and simplified | Branched with merge commits |
git tag
Description
It is used to create, list, delete, and verify tags in Git. Tags are used to mark specific points in the repository’s history, typically used for marking release points (e.g., v1.0.0, v2.0.0).
Usage
Example Workflow
Example output
Viewing Tag Information with git show v1.0.0
Last updated