In our project, we are implementing features on top of upstream software (U-Boot). Once every year or two, development is started for a new hardware and newer version of upstream software is taken as a base. Some of previously implemented features are suitable for new project almost as is, without much modifications.
Therefore, we need a workflow that allows to track and reuse work done in scope of particular feature, without resorting to scraping it out from entire code base. It shouldn't be perfect since it's not needed often, but shouldn't be painful either.
The main problem is that sometimes feature is fixed/adjusted few weeks/months after initial implementation, sometimes this repeats several times so vanilla "feature branch workflow" won't work as is.
Both team and code base are relatively small (~5 people, ~15 LoC on top of upstream code, respectively). Usually only one person works on a particualr feature at a time.
Here are two options we were able to come up with, I'll only describe handling the problematic scenario above, since it's the only source of complications.
Method A
Initial state: first/previous version of a feature is on branch X, last changed few months ago and merged to master
git checkout X; git merge --no-ff master- do the changes and commit
git checkout master; git pull; git merge --no-ff X; git push
Then git log --first-parent --no-merges shows a nice list of commits done on this branch from the very beginning.
The main problem of this approach is that it's fragile and restrictive:
- if someone does merge in step 1 with fast-forward, the above method for retrieving history won't work afterwards. AFAIK --no-ff can be forced on repo level, but everyone has to do it and not forget.
- rebase-and-then-merge in step 3 will also break history, and many people like this approach and rebasing in general. It's probably safer to forbid rebasing altogether, but I don't know how to enforce it.
Method B
Every time someone goes back to work on feature X, he creates a new X_fix_this, X_change_that, etc.
Drawbacks: ugly and cluttered branch list, scripting needed to produce a list of commits out of this.
Currently we keep a set of patches in quilt. While this perfectly solves the problem above, it's extremely ugly in other regards.
Any (better) ideas?