Most developers have faced this common scenario: you’re working on multiple versions of a project simultaneously and need to selectively merge changes between them. Let’s exeplore how to solve this problem using different Git tools.

The Everyday Problem

You have two versions of your project: one stable and one experimental. You’ve made improvements to documentation in both versions. Now you want to review and selectively incorporate only the documentation changes from your experimental branch into your stable one, without affecting other parts of the project.

The Technical Challenge

In our specific case:

  • We have a main branch with stable code
  • We have a feature/canary branch with experimental changes
  • We want to bring only the changes in the doc/ folder from feature/canary to main
  • We want to review these changes before committing them

Let’s look at three different approaches to solve this problem.

Solution 1: Git Command Line

The Git command line offers a powerful way to handle this situation using the git checkout command with a path specification:

# Make sure you're on the main branch
git checkout main

# Checkout only the doc/ directory from the feature/canary branch
git checkout feature/canary -- doc/
Bash

This command brings the entire doc/ directory from feature/canary into your working tree on the main branch. The changes will be staged, so you can:

  • Review the changes with git diff --staged
  • Unstage them with git restore --staged doc/ to examine each file individually
  • Selectively add the files you want with git add doc/file-you-want.md
  • Commit only the changes you want to keep

If you decide you don’t want any of the changes, you can reset with:

git restore doc/
Bash

Solution 2: Visual Studio Code Git Client

For those who prefer a graphical interface, VS Code’s Git integration makes this process visual:

  • Make sure you’re on the main branch
  • Open the Source Control view
  • Click on the “…” menu and select “Branch” → “Merge From…”
  • Select the feature/canary branch
  • Cancel when VS Code prompts to create a merge commit
  • Go to the Explorer view and right-click on the doc/ folder
  • Select “Compare with Selected Branch…”
  • Choose feature/canary from the dropdown
  • VS Code will show all differences between the folders
  • You can select individual files to see their differences and accept changes for specific files or sections

Solution 3: SmartGit

SmartGit offers a streamlined approach for this task:

  • Open SmartGit and make sure you’re on the main branch
  • Go to “Branch” → “Merge…” in the menu
  • Select the feature/canary branch but do not complete the merge
  • Go to “Local” → “Check Out…”
  • Select the feature/canary branch in the dialog
  • Enter doc/ in the “Paths” field
  • Check the option “Do not commit”
  • Click “Check Out”
  • Review each file in the Changes view
  • Stage and commit only the files you want to keep

Advanced Scenarios

Scenario 1: Handling Conflicts

If files in the doc/ folder have been modified in both branches, you might encounter conflicts.

Git Command Line:

# Try a merge instead
git merge --no-commit --no-ff feature/canary -- doc/
# Resolve conflicts
git mergetool
# Keep only what you want
git reset  # Unstage everything
git add doc/files-you-want.md
Bash

VS Code:

  • VS Code will highlight conflicts
  • You can accept current change, incoming change, or both changes
  • Or manually edit the file to combine changes

SmartGit:

  • SmartGit will detect conflicts and open its conflict resolver
  • You can select specific changes from either version

Scenario 2: Partial File Changes

Sometimes you might want only specific parts of a file rather than the entire file:

Git Command Line:

git checkout feature/canary -- doc/the-file.md
git add -p doc/the-file.md  # Prompts you for each chunk of changes
Bash

VS Code:

  • When viewing differences, accept specific changes by clicking the + icon next to individual change blocks

SmartGit:

  • The “Changes” view lets you select individual parts of a changed file using checkboxes

Scenario 3: Maintaining History

If you want to preserve the commit history of documentation changes:

Git Command Line:

# Use cherry-pick with path limitation
git checkout main
git cherry-pick --no-commit $(git log --oneline --reverse feature/canary ^main -- doc/ | cut -d' ' -f1)
Bash

VS Code and SmartGit:

  • Both tools have cherry-pick functionality
  • For path-specific cherry-picking, command line may be more efficient

Conclusion

Each approach has strengths:

  • Git Command Line: Most precise and scriptable
  • VS Code: Great visual diffing
  • SmartGit: Specialized features for complex operations

For most developers, the VS Code approach offers a good balance of power and usability, with the command line providing more flexibility as you become more comfortable with Git.


0 Comments

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *