Git - Is cherry-picking a bad practice if I want to have a consistent workflow? [closed]
Asked Answered
S

3

13

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?

Samella answered 10/11, 2015 at 9:36 Comment(3)
Your question was not fully clear to me, at least the sentence with "viceversa" in it (don't see the difference between this and the previous sentence). That said, git cherry-pick is a great command. In the typical software cycle, we have our dev branch and our release branches. As we encounter bugs in the release, we fix them on dev then cherry-pick them over to release so that when we make a bug fix release, it's ready to go. Your use seems to be quite similar, but without knowing more about your code and how you test, I can't recommend a better git work flow.Endways
For that workflow specifically, I personally would set feature1 as the upstream branch for test-feature1, and then rebase test-feature1 whenever feature1 changes. Then for fixes that I find in test-feature1 I would cherry-pick them down to feature1, or rebase them if there are a lot of commits to apply.Symphysis
If you need a feature on two different branches, you can always start a third branch at the branching point, add that double-use feature there, and then merge it into both branches. That way, there is only a single commit that provides that feature, and git will have zero trouble with the handling of the changes it introduces.Intoxicate
F
14

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.

Featherhead answered 23/4, 2020 at 16:29 Comment(0)
D
4

From my experience, cherry pick is undesirable for the following reason:

- cherry-picking is a signal you are about to do something that is not part of normal code flow, so treat it as "at your own risk"

1)

In normal everyday use, you should avoid randomly bringing in commits from other feature branches because if some code has not reached the main branch (dev, master, trunk - whichever, depends on your branching strategy) then, most probably, the code is not mature enough. It has not passed a merge request, has not been validated by code reviewers etc.

So, when you bring in some foreign code, you become responsible for it.

When you later create a merge request to integrate your branch into the main, code reviewers will treat all the code as yours. Then you'll have to make excuses "yeah, but that's not my code, a colleague wrote it, I just borrowed it". No way. You are now responsible for it.

And also, later when the same code comes in as a merge request from the original branch, it will have to be reviewed by someone. Now you have the same code being validated twice. It's a waste of time.

Be patient, wait for some feature to become stable and reach the main branch, so that you can pull it into your branch without becoming responsible for it.

2)

Sometimes there are situations when you are forced by somebody to use cherry-picking. For example, some manager says: "We need this fix from that branch right now, but we don't need any other changes; please, pick it and merge it into our new hotfix branch". Then it becomes their decision and their responsibility to deal with the consequences. Make it clear to them that they are violating your normal code flow.

An alternative to picking urgent fixes from dev into master is to create a new hotfix branch from the last released tag, fix the issue there, test it, release the hotfix and only then merge the hotfix up into dev.

Why so? Because if you fix the issue in dev first and then cherry-pick it into master, there is some risk that dev branch has some critical code changes that would make the fix incompatible with the master. So, after a cherry-pick you might end up rewriting the entire fix specifically for the master/release branch.

I have been in this situation many times (oh, I'll just cherry-pick this fix from dev... crap, it doesn't even build on my very urgent hotfix branch, have to rewrite it).

Project managers want to release hotfixes sooner, they usually don't care much about development branches. Thus it makes more sense to implement a fix based on the stable release (master) branch, release the hotfix and only then merge it back into the main development branch (again, possibly having to rewrite the fix because it's incompatible with the latest changes in dev).

Delegation answered 23/4, 2020 at 15:20 Comment(1)
This is the right answer. And to add on to the second point, it is also better to use a hotfix branch based on prod so you do not end up creating multiple copies of essentially the same commit, which cherry-picking forces you to do. If the fix is meant to be deployed to prod ahead of whatever changes are on dev currently, then create a new branch based on prod and only then merge down to dev when it is ready.Elevate
D
1

From my point of view, git cherry-pick is not a bad practice. Generally, you don't use it every day but for special occasions (need to report a fix with limited impact on the code, quick test or whatsoever, wants to keep a clean branch history with your beautiful commit on top of it...). I agree with what was said before "using git cherry-pick is not bad practice but what you do with it may or may not be.".

Doti answered 18/12, 2020 at 10:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.