This lesson on Stash, Cherry-pick, Reset is hands-on and example-driven. After this lesson, you will be able to selectively transfer isolated changes, such as urgent bug fixes, from one development branch to another without integrating the entire branch history. You will master locating specific commit identifiers and executing single or multiple selective transfers while managing potential conflicts. This skill is crucial for maintaining stable mainline branches.
What You'll Be Able To Do
- Locate specific commit hashes using formatted log commands across different branches.
- Execute a single commit transfer onto a destination branch using its unique identifier.
- Apply a sequence of isolated commits in a specified order using a single command.
- Resolve merge conflicts that arise during the selective commit application process.
- Distinguish the use case for selective transfer versus full branch integration (merge/rebase).
Detailed Concept Walkthrough
1. Selective Commit Transfer (Cherry-Pick)
Cherry-picking applies the changes introduced by one specific commit onto a different branch, creating a new commit object. This technique is essential for transferring critical, isolated changes like hotfixes or dependency updates.
- Mechanism: Git identifies the exact diff (patch) introduced by the source commit and attempts to apply that patch cleanly to the current state (HEAD) of the destination branch.
- Under the Hood: The operation does not transfer the original commit object; instead, it generates a brand new commit on the destination branch. This new commit has a different hash and timestamp but contains the identical content changes.
- Best Practice: Use cherry-pick sparingly, primarily for urgent fixes or when integrating a small, self-contained change. For integrating entire feature histories, prefer
git mergeorgit rebase.
# 1. Ensure you are on the receiving branch
git checkout main
# 2. Apply the changes from the specific commit hash
git cherry-pick 1a2b3c4d
# 3. Verify the new commit was created
git log --oneline
Key Takeaway: Cherry-pick transfers content changes, not history, resulting in a new, unique commit on the target branch.
2. Identifying Target Commit Hashes
To execute a cherry-pick, you must provide the unique SHA-1 identifier (hash) of the commit you wish to transfer. This requires inspecting the history of the source branch without checking it out.
- Execution Flow: The
git logcommand is used to view the commit history, displaying the full commit hash, author, date, and message for every commit. - Syntax Rule: By specifying the source branch name (e.g.,
git log feature/bugfix), you can inspect its history from your current location, allowing you to locate the required hash. - Mechanism: The
--onelineoption is highly recommended as it condenses the output, showing only the first few characters of the hash and the commit message, simplifying the identification and copying process.
# View commits on the 'hotfix' branch, showing hashes and messages
git log hotfix --oneline
# Example output: Copy the hash (e.g., 5e6f7g8)
# 5e6f7g8 Fix: Critical security vulnerability
Key Takeaway: Use
git log [branch] --onelineto efficiently locate and copy the necessary commit identifier.
3. Executing Multiple Transfers
Multiple commits can be transferred sequentially in a single command by listing their hashes. Git applies these patches one after the other in the order specified by the user.
- Execution Flow: The command processes the hashes from left to right, attempting to apply the first commit, then the second, and so on, pausing immediately if any conflict occurs.
- Mechanism: Each successfully applied hash results in a distinct, new commit on the destination branch, effectively replicating the sequence of changes from the source branch.
- Best Practice: Ensure the listed hashes are in the chronological order they were originally created, especially if they are interdependent, to maintain a logical application flow and minimize conflicts.
# Apply commit 1a2b, then commit 5e6f, onto the current branch
git cherry-pick 1a2b3c4d 5e6f7g8h
Key Takeaway: List multiple hashes in the desired application order to transfer a sequence of changes in one operation.
4. Handling Conflicts and Immutability
If the transferred changes overlap with existing code on the destination branch, a merge conflict occurs, halting the cherry-pick process until the conflict is manually resolved.
- Mechanism: When a conflict arises, Git marks the conflicting files and enters a paused state. The user must manually edit the files to choose the correct resulting code state.
- Under the Hood: Cherry-pick is an atomic operation; it must either complete fully or be aborted. Once conflicts are resolved and files are staged, the process is finalized using the
--continueflag. - Best Practice: After resolving all conflict markers in the files, stage the changes (
git add .) and then usegit cherry-pick --continueto complete the creation of the new commit.
# 1. Resolve conflict markers in files
git add .
# 2. Finalize the cherry-pick operation
git cherry-pick --continue
# To abandon the operation entirely:
# git cherry-pick --abort
Key Takeaway: Resolve conflicts manually, stage the files, and use
--continueto finalize the new commit creation.
Topics Covered in Stash, Cherry-pick, Reset
- Defining Cherry-Pick (00:30 - 01:03) — Cherry-pick applies changes from a single existing commit onto a different branch, unlike merge or rebase.
- Identifying Target Hash (01:03 - 02:22) — Locating the unique commit identifier using
git log [branch name] --onelineis required before transfer. - Executing Single Transfer (02:22 - 03:05) — Check out the destination branch and run
git cherry-pick [hash]to create a new commit. - Executing Multiple Transfers (03:05 - 04:06) — Multiple hashes can be listed in a single command, applying the changes sequentially in the specified order.
- Handling Merge Conflicts (04:06 - 04:40) — If changes overlap, the process halts, requiring manual conflict resolution before continuing the operation.
- Immutability Principle (04:40) — Cherry-pick always creates a brand new commit object with a unique hash on the destination branch.
Git Cheat Sheet
-
git log [branch] --oneline— View concise commit history on a specified branchgit log feature/bugfix --oneline -
git cherry-pick [hash]— Apply changes from one commit onto the current branchgit cherry-pick 1a2b3c4d -
git cherry-pick [hash1] [hash2]— Apply multiple commits sequentially in the listed ordergit cherry-pick 1a2b 5e6f -
git cherry-pick --continue— Complete the operation after resolving merge conflictsgit cherry-pick --continue -
git checkout [branch]— Switch the working directory to the destination branchgit checkout main
Comparison Table
| Operation | Scope of Transfer | History Impact |
|---|---|---|
| git cherry-pick | Single or selected commits | Creates new, unique commit |
| git merge | Entire branch history | Creates a merge commit |
| git rebase | Range of commits | Rewrites history of commits |
Common Pitfalls
- Mistake: Forgetting to checkout the destination branch before running the command.
Avoid: Always run
git checkout [destination]first. - Mistake: Assuming the original commit hash is preserved on the new branch. Avoid: Recognize that a new commit with a new hash is always created.
- Mistake: Listing multiple hashes in the wrong chronological order. Avoid: List hashes from oldest to newest to maintain logical dependencies.
- Mistake: Resolving conflicts but forgetting to stage the files.
Avoid: Run
git add .before runninggit cherry-pick --continue.
FAQs
- Why does cherry-pick create a new commit hash? The new commit is created on a different branch with a different parent history, making it a unique object. It only replicates the content changes (the patch) of the original commit.
- When should I use cherry-pick instead of merge? Use cherry-pick when you need to grab an urgent, isolated change (like a hotfix) from a feature branch that is otherwise incomplete or unstable. Merge is for integrating the entire feature.
- What happens if I cherry-pick a commit that has already been merged? Git will likely apply the changes successfully but will result in duplicate content changes in your history, which can complicate future merges. Use caution to avoid duplication.
- Can I cherry-pick a range of commits?
Yes, you can specify a range using
git cherry-pick A..B, butgit rebaseis generally the safer and more idiomatic tool for transferring a continuous range of commits.