Key Point: I'd like to ensure that no commits and changes are missed in the step of creating a software release, especially if some commits have been cherry-picked or rebased due to prior testing.
Edit: It's clear that - in the end - a human has to judge if the commits are correct. But having a list of non-included commits would help and I hope to get that from git.
We try to follow the Git-Flow workflow to develop small to medium-sized (a couple of 10k LOC) embedded projects. 5 people are in the core team for that. We have a Bitbucket/Jira backend to track issues and to review pull-requests.
We have a couple of branches:
master
: Released and tested firmwaredevelop
: main integration branch, code here is compile-able and tested but not yet releasedfeature/...
: a lot of feature branchesbugfix/...
: a couple of bugfix branchesrelease/...
: release preparations, a "safety" barrier between develop and master where final adjustments and final tests can be made
Ideally, one branch for one issue ticket is created, using a naming scheme to include the issue's key and description for proper tracking and traceability.
Imagine this situation:
A feature request ticket "Add FIR filter module" with id "FW-5" in Jira is created and results in a feature branch "feature/FW-5-add-fir-filter-filter-module" in the corresponding git repository. Development is going well and the module is close to be ready. Probably a pull-request has already been openend to get this module reviewed by colleagues.
Then a second ticket comes in: "Add 10 Hz lowpass filter". This clearly depends on FW-5 which has not made it into develop yet since the pull-requests have not been reviewed. That means, we must branch from "feature/FW-5-add-fir-filter-filter-module" instead from develop.
The manager comes in and wants a just-in-time release of the current state, including the 10 Hz filter. It must be now, because a time slot in a test machine became available by chance. So we need to compile a pre-release from develop (since some other stuff could be integrated in the meantime) and our two feature branches. I'd start with develop, create a release branch from there, integrate the two feature branches by
git rebase
, eventually fix conflicts, increase version number and flash it to hardware.Everything went fine and the tests were successful. The pre-release is kept as it is and probably further development takes place. Then it's time for the "real" release. We know from step 3) that the hand crafted pre-release worked well. However the two feature pull requests have to be integrated to develop properly in the same way we've done this in the pre-release. Including fixing eventual merge conflicts in the same way. And that's the point I'm struggling with.
Question: How do I ensure that the changes made in the pre-release were integrated to the release exactly the same way? I can't compare the file contents 1:1, since in meantime develop has evolved further and files might look differently due to further commits in develop.
I've read about git branch --no-merged
and some git rev-list
ideas, but these operate on commit SHAs. So the rebased parts from the pre-release would appear as non integrated.
Is git cherry -v
the correct approach? It says (see: https://linux.die.net/man/1/git-cherry)
The changeset (or "diff") of each commit between the fork-point and is compared against each commit between the fork-point and . The commits are compared with their patch id, obtained from the git patch-id program.
...
Because git cherry compares the changeset rather than the commit id (sha1), you can use git cherry to find out if a commit you made locally has been applied under a different commit id. For example, this will happen if you're feeding patches via email rather than pushing or pulling commits directly.
Which sounds great, especially the last point, but I'm not sure if its understood correctly.
Is that the right tool to find out, if anything that should be part of the release has not been integrated yet? If yes - why do I find so few information about git cherry
? It's a killer tool.
If not - where's the missing point? And what's about the merge conflicts :)
Follow-up questions
- Is branching from the parent feature branch (step 2) okay or kind of smelly?
- Is rebasing in 3) the proper approach? Or would you rather use merge or cherry-pick?
- Should the child pull requests merge back to the parent or directly to develop?
- What alternatives would you see? I know it would be better to complete the pull-requests first and integrate it properly to develop, but sometimes this just doesn't work.
- Do you allow dependent feature branches in your workflow? Do you enforce an order when the pull-requests are integrated?
- If dependent feature branches are allowed, you also must allow rebase of these feature branches to get rid of the parent commits in the child, right? And you have to rebase the child ontop develop after the parent has been integrated. Or do you merge the children back to it's parent first which would mean that all children pull-requests have to be closed first.
Thank you!
From a technical standpoint, you can perform the task you're asking about, and
git cherry
can be part of that solution. Becausegit cherry
compares specific branches, I would combine it withgit for-each-ref
Because it operates on patch ID, it will get false positives in case of conflict resolution during the original rebae or cherry-pick. Assessing that as the reason the commit was not included would be part of the process of interpreting the output.
As for why you don't hear a lot about this... well, I understand that you believe it's a killer tool, but in practice I can't say I've seen many projects that want to approach the problem this way.
At the end fo the day, nobody cares which commits have been applied. They care what the sfotware does. If your tests are good enough to tell you whether the software behaves correctly, then important commits won't be missed and if a commit is missed there will be an explanation for why it doesn't matter. If your tests are not good enough, then the assurance that all the commits are accounted for doesn't really mean much.
I would also note that gitflow generally doesn't depend on a lot of commit-copying. Perhaps your workflow is some variation of gitflow, or maybe it's just disagreement about terminology, but I can't see how this would be an issue in a workflow that I would call gitflow.
Lastly, to address most of your follow-up questions:
Whether/when you create branches from "parent branches"[1] is a project workflow decision; we can't say if it's "good" or "bad". That said, gitflow has documented rules for where branches are created and where they're merged; if gitflow is your model, then those rules are the only external source that can say if a given merge is "smelly" as you say
[1] As an aside, "parent branch" is not a concept that exists in git. I know what you meant when you asked about it, but it can be very misleading to think of branches this way.