Since you have reached to advanced git concept, I welcome you to get yours hand dirty with the given example and get a deep understanding of git. But if you are here, by mistake or your are new to git, then first go through the blog: Vocabulary of git - a beginner guide , also get your feet wet before diving deep into git from blog :How to get Started with git - a beginner cheat sheet .
Hence this blog is a third blog on series: Git basic to Advanced. Now, lets get started:
Git stash temporary shelves (or stashes) changes you've made to your working copy so you can work on something else, and then come back and re-apply them later on. Stashing is handy if you need to quickly switch context and work on something else, but you're mid-way through a code change and aren't quite ready to commit.
E.g. Let's say you are working on a new feature in your Git repository. You have made some modifications to multiple files but haven't completed the implementation yet . However, your team lead asks you to switch to a different branch urgently to fix a critical bug. Since you are not completed with the feature so it's not a good practice to commit the half done code, instead in this case you will need to use git stash command to temporarily add your current version of code to somewhere safe so you can get back later at the current version once you are done with the fix that was urgent.
$ git status
On branch main
Changes to be committed:
new file: style.css
Changes not staged for commit:
modified: index.html
Now you want to switch branches, but you don’t want to commit what you’ve been working on yet, so you use git stash or git stash push alternatively , to store the working directory to somewhere safe so you can get it back later at the current state.
$ git stash
Saved working directory and index state
"WIP on main: 5002d47 our new homepage"
HEAD is now at 5002d47 our new homepage
(To restore them type "git stash apply")
Now after this commad you can see your working directory is absolutely clean
$ git status
On branch main
nothing to commit, working tree clean
After this point you can switch to any of the branch and do your work to whatever branch and later on get on your earlier point.
By default, git stash will stash only modified and staged tracked files. You can also stash untracked files using flag
Flags:
--include-untracked or -u : Includes untracked file in stash
--all or -a : includes untracked file and ignored files as well
$ git stash --include-untracked
List all the stashes: as you can add any no of stashes in git you can list using command git stash list or git stash show as below
$ git stash list
stash@{0}: WIP on master: 049d078 Create index file
stash@{1}: WIP on master: c264051 Revert "Add file_size"
stash@{2}: WIP on master: 21d80a5 Add number to log
You can view your stashes with the command: git stash list or git stash show
There can be multiple stashes at same time:
To make the get all the changes in last stash in working directory you can run
$ git stash pop
or
$ git stash apply
$ git stash apply
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: index.html
modified: lib/simplegit.rb
no changes added to commit (use "git add" and/or "git commit -a")
If you want to apply one of the older stashes, you can specify it by naming it, like this:
$ git stash pop stash@{1}
or
$ git stash apply stash@{1}
git stash clear empties the stash list by removing all the stashes.
git stash drop stash@{2} : Deletes a particular stash and the changes from the stash list.
Sometime ,you may want to move the specific or recent stash to a new branch instead of continuing in same branch then you can use command
git stash branch
This command creates a new branch for you with your selected branch name, checks out the commit you were on when you stashed your work, reapplies your work there, and then drops the stash if it applies successfully:
$ git stash branch testchanges
M index.html
M lib/simplegit.rb
Switched to a new branch 'testchanges'
On branch testchanges
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: index.html
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: lib/simplegit.rb
Dropped refs/stash@{0} (29d385a81d163dfd45a452a2ce816487a6b8b014)
The git reset command is a complex and versatile tool for undoing changes.
Git reset is a command that allows developers to manipulate the commit history in a Git repository. It provides flexibility in undoing changes, discarding commits, and rewriting history.
It has three primary forms of invocation. These forms correspond to command line arguments --soft, --mixed, --hard
git reset --soft
git reset --mixed
git reset --hard
In Git, the git revert command is used to create a new commit that undoes the changes made in a previous commit. It allows you to revert or undo the effects of a specific commit while preserving a complete history of the project.
When you run git revert
The git revert command is different from other Git commands like git reset or git checkout, which manipulate the commit history directly. Instead of modifying the commit history, git revert creates a new commit that negates the changes made by a specific commit.
By using git revert, you can safely undo changes without rewriting history, which is useful when you want to preserve the integrity of the commit history and collaborate with others.
Git Clean
It generally removes all the files that are untracked. From working directory i.e. When running git clean all files that are not added to git are removed and the removal is permanently deleted. It does not remove untracked or ignored files
git clean: Removes untracked files from the working directory (with safety precautions).
git clean -n: Performs a dry run or shows a list of files that would be deleted(i.e. Only shows).
git clean -f: Forcefully removes untracked files (including directories).
git clean -df: Forcefully removes untracked files and directories.
git clean -xf: Forcefully removes untracked files and ignored files.
Sometimes commit are done too early and possibly forget to add some files that were to be added in the last commit history, or you mess up your last commit message. If you want to redo that commit, make the additional changes you forgot, stage them, and commit again but in same history then you can use the --amend option:
$ git commit --amend
The git commit --amend command is a convenient way to modify the most recent commit.
$ git commit --amend --no-edit
It lets you combine staged changes with the previous commit instead of creating an entirely new commit. The --no-edit flag will allow you to make the amendment to your commit without changing its commit message.
$ git commit --amend -m "an updated commit message"
If you want to change the last commit messager then you run git commit --amend -m "new commit message"
It’s also possible to take a series of commits and squash(crush or squeze) them down into a single commit with the interactive rebasing tool. In Git, the git squash command is not a built-in command, but rather a technique used to combine multiple commits into a single commit. It allows you to condense a series of commits into a cleaner and more cohesive commit history.
The general process of squashing commits involves combining commits that are related or represent a single logical change. This can be useful to create a more concise and organized commit history before pushing your changes to a shared repository or submitting a pull request.
- To squash commits, you typically use the git rebase command in interactive mode (git rebase -i).
Here's a step-by-step example:
After these steps, Git will apply the changes of the squashed commits and create a new consolidated commit with a new commit message. The previous individual commits will be replaced with the squashed commit.
It's worth noting that squashing commits alters the commit history, so it should be used with caution, especially if you've already pushed the commits to a shared repository. Squashing is more appropriate for local branches or feature branches before integration into the main branch.
The primary reason for rebasing is to maintain a linear project history. For example, consider a situation where the main branch has been changed(progressed) since you started working on a feature branch. You want to get the latest updates to the main branch in your feature branch, but you want to keep your branch's history clean so it appears as if you've been working off the latest main branch. This gives the later benefit of a clean merge of your feature branch back into the main branch.
Rebasing is the process of moving or combining a sequence of commits to a new base commit. Rebasing is most useful and easily visualized in the context of a feature branching workflow.
It allows you to integrate changes from one branch onto another by moving, combining, or modifying commits.
git rebase branch-name
$ git rebase main
Running git rebase with the -i flag begins an interactive rebasing session. Instead of blindly moving all of the commits to the new base, interactive rebasing gives you the opportunity to alter individual commits in the process. This lets you clean up history by removing, splitting, and altering an existing series of commits.
The golden rule of Rebase :
Not only does rebase come with a good part, it has some dangers associated with it, So, before you run git rebase, always ask yourself, “Is anyone else looking at this branch?” If the answer is yes, take your hands off the keyboard and start thinking about a non-destructive way to make your changes (e.g., the git revert command).
The fundamental similarities between rebase and merge is Rebasing and merging are two methods in Git used to integrate changes from one branch to another. Both approaches aim to bring together the modifications made in separate branches into a consolidated branch; in other words Both of these commands are designed to integrate changes from one branch into another branch—they just do it in very different ways.
The main differences between these two approaches is
Merging and Rebasing are essential operations in Git that help manage the complexities of collaborating on a shared codebase. They are necessary when multiple developers are working on different branches or when changes need to be integrated from one branch to another. Here's some background on why merging and rebasing are required:
Merging combines the changes from one branch into another by creating a new merge commit. This commit has two or more parent commits, representing the branches being merged. While instead of creating a merge commit, rebase rewrites the commit history of the branch being rebased.
When you merge a branch, the commit history of both branches is preserved, and a new commit is created to represent the merge itself. This often results in a "merge bubble" or a merge commit, which can help track the integration of changes while rebase changes made on the branch are rebased, incorporating the changes of the third branch. This results in a linear commit history, as if the work was done sequentially on a single branch.
Merge is a non-destructive operation that does not modify the existing commits on either branch. It's useful for combining branches with different commit histories or when multiple developers are working on a project simultaneously while rebase is useful for maintaining a cleaner and more linear commit history, especially when incorporating changes from a long-lived branch or preparing changes for integration into a main branch.
Which one is actually better ?
Which is better between merge and rebase solely depends on the team and their preferences. There are two alternative ideas regarding it,
One who supports merging, point of view explains that your repository’s commit history is a record of what actually happened. It’s a historical document, valuable in its own, and shouldn’t be modified , if you and the repository should preserve that for posterity , if your team is driven by this mental picture you may use merge instead of rebase.
The other point of view is that the commit history must look like a story that your project is ongoing, For e.g. it is like writing a book , you wouldn’t publish the first draft of a book, so why to show the mess? When you’re working on a project, you may need a record of all your missteps and dead-end paths, but when it’s time to show your real work to the world, you may want to tell a more coherent story of how to get from A to B.
Teams in this thought process use tools like rebase and filter-branch to rewrite their commits before they’re merged into the mainline branch. They use tools like rebase and filter-branch, to tell the story in the way that’s best for future readers.
Hence, there is no such thing as a better one over other , it depends solely on the team preference and what the team wants the code to look like.
Resolving and understanding git conflicts can be challenging but is actually manageable with the right approach. Here are some steps to help you resolve conflicts effectively and gain a better understanding of the process:
Take a deep breath and stay calm: Conflicts can be frustrating, but it's essential to approach them with a calm and patient mindset. Remember that conflicts are a normal part of collaborative development.
Review the conflict: When you encounter a conflict, Git will mark the conflicting sections with special markers (<<<<<<<, =======, >>>>>>>). Take a moment to understand what these markers represent. The <<<<<<< marker indicates the beginning of the conflicting changes from your branch, followed by =======, which separates your changes from the incoming changes (>>>>>>>).
Understand the conflicting changes: Read through the conflicting sections and try to understand the changes made by both parties. Pay attention to the context of the changes and the lines involved. This understanding will help you make informed decisions during the resolution process.
Communicate with your team: If you're working in a team, reach out to your teammates to discuss the conflicting changes and ensure everyone is on the same page. Collaboration and clear communication can help in resolving conflicts efficiently.
Decide on the resolution strategy: Consider the conflicting changes and decide on the best strategy to resolve them. Some common approaches include:
Test your changes: After resolving the conflicts, test your changes to ensure they work as expected. Run any relevant tests, verify the functionality, and ensure that the resolution did not introduce any errors.
Commit and push the resolved changes: Once you're satisfied with the resolution, use git add to stage the resolved files, followed by git commit to create a new commit. Provide a clear and descriptive commit message that explains the conflict resolution. Finally, push the changes to the remote repository using git push to make them available to others.
Reflect and learn: After resolving conflicts, take the opportunity to reflect on the process and learn from it. Consider what led to the conflicts and explore ways to prevent similar conflicts in the future, such as improving communication or establishing coding conventions.
The purpose of any version control system is to record changes to your code. This gives you the power to go back into your project history to see who contributed what, figure out where bugs were introduced, and revert problematic changes. In addition to see git commit logs there are other functions of git Log :
Basic git log: Running git log without any flags will display the commit history in reverse chronological order, starting from the most recent commit at the top.
$ git log
commit 1c910476b213bf7b149fea281edd16c9ee3c9ddd
Author: Sagar Chapagain saagarchapagain@gmail.com
Date: Thu Jun 29 15:49:22 2023 +0545
Design: Finalize design of Detail page
commit 79835d5bbf36f6685bfbf42aa3cd76407917d881
Author: Sagar Chapagain saagarchapagain@gmail.com
Date: Tue Jun 27 01:09:08 2023 +0545
Bug:Fixed bug in search in car filter
--oneline flag: The --oneline flag provides a concise representation of each commit on a single line. It includes the commit hash and the commit message.
$ git - -oneline
95afde5 (origin/filter) final issues solved for brand model
fde6c7a bug:completed brand model dynamic checkbox selection
--author flag: You can use the --author flag to filter the commit history by a specific author. For example, to view the commits made by a user named "John Doe," you can use the following command:
$ git log --author="Sagar Chapagain"
commit 043f63a7b8841414f928e67ea1942726fcc61dc1 (HEAD -> Designv3.0)
Author: Sagar Chapagain saagarchapagain@gmail.com
Date: Wed Jul 5 12:28:21 2023 +0545
bug fixes for the latest support issues
working on bugs
commit 9b16b7130d292a313fbfd2dc3d7d37cb93ca9903
Author: Sagar Chapagain saagarchapagain@gmail.com
Date: Sat Jun 24 20:37:10 2023 +0545
updated changes for New design of home page
--since and --until flags: The --since and --until flags allow you to specify a time range to filter the commits. For example, to view the commits made between two specific dates, you can use the following command:
$ git log --since="2023-01-01" --until="2023-06-30"
--grep flag: The --grep flag lets you search for commits that match a specific pattern in the commit message. For example, to find commits with the word "bug" in the commit message, you can use the following command:
$ git log --grep="bug"
commit 043f63a7b8841414f928e67ea1942726fcc61dc1 (HEAD -> Designv3.0)
Author: Sagar Chapagain saagarchapagain@gmail.com
Date: Wed Jul 5 12:28:21 2023 +0545
bug fixes for the latest support issues
working on bugs
commit bf377a381a92df4760adb56566d97567cb72356a
Author: sagar chapagain saagarchapagain@gmail.com
Date: Thu Mar 18 15:06:54 2021 +0545
completed some bugs 2021-03-18
commit 9842e7910ff147dbd107324c4d48a59cd5f23230
Author: sagar chapagain saagarchapagain@gmail.com
Date: Fri Feb 12 06:49:16 2021 +0545
-p or --patch flag: The -p or --patch flag shows the detailed changes made in each commit, including the diff (difference) between the commit and its parent commit. This provides a comprehensive view of the modifications introduced in each commit.
$ git log -p
--graph flag: The --graph flag adds ASCII art-based graph lines that illustrate the branching and merging of commits. This option is particularly useful when working with complex branching and merging scenarios.
git log --graph
* commit 043f63a7b8841414f928e67ea1942726fcc61dc1 (HEAD -> Designv3.0)
| Author: Sagar Chapagain saagarchapagain@gmail.com
| Date: Wed Jul 5 12:28:21 2023 +0545
|
| bug fixes for the latest support issues
|
| working on bugs
|
* commit 9b16b7130d292a313fbfd2dc3d7d37cb93ca9903
| Author: Sagar Chapagain saagarchapagain@gmail.com
| Date: Sat Jun 24 20:37:10 2023 +0545
|
| updated changes
|
* commit 42b08eca84cf425facd333ebce6c06444027a2b4 (origin/Designv3.0)
| Author: Sagar Chapagain saagarchapagain@gmail.com
| Date: Thu Mar 2 09:49:02 2023 +0545
Git Fork: Forking is a feature provided by Git-based version control systems, such as GitHub and GitLab, that allows developers to create a personal copy of a repository. When you fork a repository, you create a separate copy of the entire repository, including all its files, branches, and commit history. This copy is stored in your personal GitHub or GitLab account.
A pull request is a feature provided by Git-based version control systems, such as GitHub and GitLab, that allows developers to propose changes to a codebase to the internal team or a open source team.
In their simplest form, pull requests are a mechanism for a developer to notify team members that they have completed a feature. Once their feature branch is ready, the developer files a pull request via their git account. This lets everybody involved know that they need to review the code and merge it into the main branch.
But, the pull request is more than just a notification—it’s a dedicated forum for discussing the proposed feature. If there are any problems with the changes, teammates can post feedback in the pull request and even tweak the feature by pushing follow-up commits. All of this activity is tracked directly inside of the pull request.
Steps of Pull Requests
Git bisect is a powerful tool for finding the commit that introduced a bug. It performs a binary search through your commit history, allowing you to quickly identify the exact commit that caused the issue.It automates the process of narrowing down the range of commits to identify the exact commit where the issue was introduced.
Here's a step-by-step overview of how to use Git bisect:
Start the Bisect: Use the command git bisect start to begin the bisect process. You can also specify a range of commits to limit the search, or simply let Git consider the entire commit history.
Identify Good and Bad States: Identify a known "good" state (a commit where the issue is not present) and a known "bad" state (a commit where the issue is present). Use the commands git bisect good
Git bisect automatically checks out a commit in the middle of the range between the good and bad states. It allows you to test and determine if the issue exists in that commit.
Test and Determine: After checking out a commit, perform tests or run your application to observe if the issue is present. Based on the outcome, use git bisect good or git bisect bad to mark the commit as good or bad, respectively.
Repeat: Git bisect will automatically select another commit in the middle of the remaining range based on the previous result. Repeat the testing process by running your tests or application and marking the commit accordingly.
Continue until the bad commit is found: Repeat the process of testing and marking commits as good or bad until Git identifies the specific commit that introduced the bug. Once the bad commit is found, Git bisect will print the commit hash and additional information.
Stop the Bisect: Use the command git bisect reset to end the bisect process. It will return your repository to the original state, with the HEAD set to the commit where you started the bisect.
A Git workflow is a recipe or recommendation for how to use Git to accomplish work in a consistent and productive manner.
In other words, Git workflows are a set of guidelines and practices that help teams collaborate and manage changes to a codebase using Git, a popular version control system. There are several commonly used Git workflows, each with its own advantages and suited for different types of projects and team structures.
Here are some of the most popular Git workflows:
1. Centralized Workflow:
2. Feature Branch Workflow:
3. Gitflow Workflow:
Gitflow is a branching model that provides a strict structure for managing larger projects.
It defines long-lived branches such as 'master' for production-ready code and 'develop' for ongoing development.
Features, bug fixes, and releases are developed in separate branches and merged into 'develop' or 'master' based on the stage of development.
It provides a clear separation of features and stability levels, making it suitable for complex projects and teams.
In Gitflow, the two main branches are:
Master (or Main): The master branch represents the mainline branch of development. It contains the stable and production-ready code.
Develop: The develop branch is where ongoing development and integration of new features take place. It acts as a branch for the next release. Developers create feature branches from the develop branch to work on specific features or tasks
Apart from these two primary branches, Gitflow also defines additional branches for different purposes:
Feature branches: Developers create feature branches from the develop branch to work on specific features or tasks. These branches are short-lived and are used for developing new features or making significant changes.
Release branches: Release branches are created from the develop branch when preparing for a new release. The release branch allows for final testing, bug fixes, and last-minute changes before merging into the master branch.
4. Forking Workflow:
Trunk Workflow:
The term "trunk" refers to the main branch of development, typically named 'main' or 'trunk' itself.
Trunk-based development is a version control management practice where developers merge small, frequent updates to a core “trunk” or main branch. Since it streamlines merging and integration phases, it helps achieve CI/CD and increases software delivery and organizational performance.
The Trunk-Based Development workflow aims to minimize branching and promote frequent integration of changes, leading to faster feedback loops, reduced conflicts, and increased development velocity. It emphasizes maintaining a single, always-deployable main branch, referred to as the trunk.
Here are some key differences between the Git workflows & Trunk workflow
Branching Model:
Gitflow defines multiple long-lived branches, such as 'master', 'develop', feature branches, release branches, and hotfix branches while TBD emphasizes a single main branch, often named 'main' or 'trunk', where all development takes place.
Branching Strategy:
Gitflow encourages the creation of feature branches for each new feature or task. Developers work on these branches and merge them back into the 'develop' branch once the work is completed while TBD discourages long-lived feature branches. Instead, developers work directly on the main branch, committing their changes frequently and integrating them into the main branch as soon as possible.
Release Process:
Gitflow has a defined release branch for preparing and stabilizing releases. The release branch allows for final testing, bug fixes, and last-minute changes before merging into the 'master' branch while TBD typically relies on feature flags or toggles to control the visibility and activation of new features. Continuous deployment is often practiced, allowing for frequent releases directly from the main branch.
Complexity:
Gitflow provides a more complex branching model with multiple branches, which can be beneficial for larger teams or projects that require strict separation of development stages .TBD simplifies the branching model by focusing on a single main branch. It works well for smaller teams or projects with a need for rapid development and frequent releases.
To Conclude:
Gitflow offers a structured and controlled release process, whereas Trunk-Based Development prioritizes simplicity, continuous integration, and rapid deployment from a single main branch.
Git worktree is a feature introduced in Git 2.5 that allows you to maintain multiple working trees or working directories from a single Git repository. It enables you to have separate instances of your repository, each with its own working directory and checked-out branch.
Multiple Working Trees: With Git worktree, you can create additional working trees associated with the same repository. Each working tree is an independent copy of the repository, allowing you to work on different branches or commits simultaneously.
Isolated Changes: Each worktree has its own working directory, allowing you to make changes, switch branches, or perform operations without affecting other worktrees or the original repository.
Shared Repository: All worktrees created with Git worktree share the same repository data, such as object database and reflogs. This means they do not require additional disk space for duplicate repository data.
Usage: Git worktree is useful in various scenarios, such as working on multiple branches concurrently, testing changes without interrupting ongoing work, or reviewing different versions of the codebase.
Worktree Commands: Git provides commands to manage worktrees. Some commonly used commands include:
git worktree add
git worktree list: Lists all the existing worktrees.
git worktree prune: Cleans up stale or unused worktrees.
git worktree remove
It's important to note that worktrees are designed for temporary or short-lived use. If you need a separate, long-term repository with its own remote, you should consider creating a clone instead of using Git worktree.
Git worktree is a powerful feature that provides flexibility and convenience when working on multiple aspects of a project simultaneously. It helps maintain separate working environments while keeping repository data shared and in sync.
Git hooks are scripts that Git can execute at specific points during its workflow. These scripts allow you to automate or customize certain actions before or after specific Git events occur, such as committing code, pushing changes to a remote repository, or merging branches. Git hooks are typically written as shell scripts, but they can be written in any scripting language that can be executed on your system.
To use Git hooks, you need to create executable scripts in the appropriate .git/hooks directory within your local repository or on the remote server. Git provides template files for each hook that you can customize by removing the .sample extension and adding your desired logic.
By leveraging Git hooks, you can automate repetitive tasks, enforce coding standards, ensure code quality, and implement custom workflows as part of your Git process.
Git provides two types of hooks: client-side hooks and server-side hooks. Client-side hooks run on the developer's local machine, while server-side hooks run on the remote repository server.
Reflog, short for "reference log," is a feature in Git that records all changes to the tips of branches and other references in your repository. It serves as a safety net by maintaining a log of all previous reference states, even those that are no longer accessible through regular branch references. It can be useful for recovering lost commits or branches that were accidentally deleted.
Git cherry-pick is a powerful command that enables arbitrary Git commits to be picked by reference and appended to the current working HEAD. Cherry picking is the act of picking a commit from a branch and applying it to another. git cherry-pick can be useful for undoing changes. For example, say a commit is accidently made to the wrong branch. You can switch to the correct branch and cherry-pick the commit to where it should belong.
Useful Scenario to use Cherry pick
Team collaboration:
Suppose a new product feature has a backend and frontend component. Maybe the backend developer creates an API structure that the frontend will also need to utilize. The frontend developer could use git cherry-pick to pick the commit .This pick would enable the frontend developer to continue progress on their side of the project.
Bug hotfixes:
Suppose a developer has started working on a new feature. During that new feature development they found a pre-existing bug. The developer creates an explicit commit patching this bug. This new patch commit can be cherry-picked from current branch directly to the main branch to fix the bug
Undoing changes and restoring lost commits:
Sometimes a pull request might get closed or mistaken without merging. Git never loses those commits and through commands like git log and git reflog they can be found and cherry picked back to life.
Here's how the cherry-pick command works:
Identify the Commit: First, you need to identify the commit you want to apply to another branch. You can find the commit hash using Git log or other Git visualization tools.
$ git log
Switch to the Target Branch: Checkout or switch to the branch where you want to apply the selected commit. This branch will be the destination branch for the cherry-picked commit.
$ git checkout <branch-name>
Execute the Cherry-pick Command: Use the following syntax to apply the commit to the current branch:
$ git cherry-pick <commit-hash>
Resolve Conflicts (if any): If there are any conflicts between the cherry-picked commit and the destination branch, Git will pause the cherry-pick process and indicate the conflicting files. You need to manually resolve the conflicts by editing the affected files, marking the conflicts as resolved, and staging the changes. Then you can continue the cherry-pick process by running :
$ git cherry-pick --continue
Repeat Cherry-picks (optional): If you want to cherry-pick multiple commits, you can repeat steps 1-4 for each commit.
Finish Cherry-picking: After applying all the desired commits, you can commit the changes created by the cherry-picks to complete the process.
Note: It's important to note that cherry-picking creates new commits in the destination branch with the same changes as the selected commits. The new commits will have different commit hashes, as they are not direct copies of the original commits.
Other blogs from this Series: