I'm currently working on an SCM migration in my company, we're moving from CVS to Git, but the CVS code was versioned differently, each branch is a different codebase, so I'd like to know how do I get to merge just one commit at a time with Git.
I'm currently working on an SCM migration in my company, we're moving from CVS to Git, but the CVS code was versioned differently, each branch is a different codebase, so I'd like to know how do I get to merge just one commit at a time with Git.
Each commit in a repository corresponds to a tree full of files. Typically, these files were created over several commits. But sometimes it is necessary to take the delta between two commits, and apply it to a different branch, as in your case.
In this case, you do not want to get the current state of the tree (which may have unfinished or untested changes); you just want to get the delta associated with that change.
On other version control systems, you would just have to create a diff based on the most recent change, and then fix the change in your release branch. Instead, with Git, we can use the cherry-pick
command to do the work for us:
git checkout master
echo Working >> file.txt
git commit -m "Working" file.txt
echo BugFix >> bugfix.txt
git commit -m "BugFix" bugfix.txt
echo More Working >> file.txt
git commit -m "More working" file.txt
# Vamos aplicar o 'bugfix' para release
git checkout release10
git cherry-pick master~1
[release10 41037ab] BugFix
0 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 bugfix.txt
This allowed us to make a single change - described here with master ~ 1 - and copy the delta into the release branch.
If we had several changes, we could have master ~ 3..master ~ 1. Unlike just generating a diff and patch of the current tree, this will copy the commits (and their relationships) on the new branch.
Finally, it is interesting to note that when you copy a change using this mechanism, the commit hash will change (notably because it will have a different hierarchy). Sometimes this does not matter, but if you want to record where the original change came from, you can run git cherry-pick-x. This inserts a commit message indicating where the original change came from:
git checkout release10
git cherry-pick -x master~1
git cherry-pick master~1
[release10 41037ab] BugFix (cherry picked from commit 938a4c0bbb3985524192aa8a926ea6757263e94b)
0 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 bugfix.txt
You can also make the cherry-pick from the SHA of the commit, just find the commit you want to bring to your branch and have it executed with the command:
git cherry-pick -x b53af978b3581509557c6e24923edf1c8a683e02
Whenever you are using the cherry-pick, especially if you are reordering commits, you are creating a new history. However, you never really throw away the old one, everything is available from the reflogs. You are not destroying history, you are creating other alternatives. All cherry picking gives you the ability to apply patches to other branches in a secure way with fewer errors.