I find cherry-pick
particularly useful in some cases, e.g., when I have a feature1
branch, and a test-feature1
branch, and I want to apply corrections found in tests; or the other way, I want to test new functions, for which I need those new functions in the test branch.
The advantage of cherry-pick
here is that I can choose the specific changes I want to apply in the other branch; maybe merging the whole branch is not interesting.
I've been using this in past projects but I think this practice leads to inconsistent workflows. Is cherry-pick
-ing a not recommended and avoidable practice?
Reasons to avoid cherry-picking The primary reason is that it creates duplicate commits, but you also lose the ability to track your commit history. If you're cherry-picking a lot of commits out of order, those commits will be recorded in your branch, and it might lead to undesirable results in your Git branch.
I found the answer is git reset --merge - it clears the conflicted cherry-pick attempt.
You should cherry-pick a commit when you need the change contained in a single commit, but you can't or don't want to pull the entire contents of that branch into another. You can use the GitLab UI to cherry-pick single commits or entire merge requests. You can even cherry-pick a commit from a fork of your project.
Using git cherry-pick
is not bad practice. What you do with it may or may not be. That is true for many things; is git push -f --no-verify origin master
bad? It may save your life or get you in trouble if you're not careful or don't know what you're doing.
The following workflow is not uncommon:
You implement in the develop
branch, after two weeks you release code to your beta testers. Two weeks after that, if nothing came up, your promote your beta release to a production release:
develop --a--b--c--d
\
release-beta -------------d'
\
release-prod ---------------d''
This goes on and on, until one day an issue is found in production... Luckily commit f
in your develop
branch will fix it.
You have a few options:
You can merge develop
into release-beta
, fast track the beta testing cycle and release to production immediately. The issue with this is that you may or may not release code a bit prematurely. Your beta testers may not have the opportunity to find some nasty bugs.
Or you can just cherry-pick f
onto the release-prod
branch, run your tests and release to production if you're happy with the result:
+---- hot fix
|
v
develop --a--b--c--d--e--f--g
\ \
release-beta -------------d' \
\ \
release-prod ---------------d''---f'
The curse (or blessing) of git cherry-pick
is that it will expose how good or bad you are at making small, self-contained units of change.
Consider this scenario:
// foo.js
function foo() {
...
}
// foo.test.js
test.todo('foo does something awesome', () => {
// TODO
})
But you commit these two files in two separate commits...
123abc fix: implement foo function to fix issue in production
456fgh fix: implement tests for foo function
In some testing frameworks, a .todo
annotation will automatically fail your test run as a reminder that you still need to implement the test... Awesome! So your develop
branch fails but you know why.
Remember that commit f
above? Turns out that it contained only the code and not the test... So when you ran your tests in the release-prod
branch nothing failed... because that commit didn't introduce the failing test!
But things get worse... commit f
fixed one production issue but created another one! This could have been avoided if you shipped the code and the tests in one single commit.
In my humble opinion there are no fundamental bad practices; you can only assess what are your options in a given situation. Knowing which ones is the best comes from practice and experience. There is no silver bullet.
This may not be the answer you wanted: git cherry-pick
isn't bad practice. It is a useful tool if you know how and when to use it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With