> X decided to merge and deploy just the back-end changes, and then, once that was done and appeared successful, to merge the remaining front-end changes.
> "What should X have done in the first place to avoid the pickle?"
0. (Of course, not develop a 406 patch changeset and then have to pick it apart. Make smaller pushes, frequently.)
1. Create a topic branch right there at the tip where the 406 changes are locally committed.
2. Then use git's interactive rebase to rewrite this branch such that just the back-end commits are picked first, followed by the front end.
3. Make a back-end topic branch from the last back-end commit and test that. If it's cool, master can be rebased to that and pushed to origin/master upstream.
4. Test remaining front-end changes, rebase master to them, push.
Also:
3. a) If back-end changes need fixing, fix them on the back-end-topic branch. Then rebase the original topic to the back end topic to pick up these changes "under" it. (I.e. replay the front end over the new back end, and install as new front end).
2. Then use git's interactive rebase to rewrite this branch such that just the back-end commits are picked first, followed by the front end.
Probably how I'd do it, but I know it's not a popular workflow. The only project that I've seen publicly talk about expecting a changeset to rewritten from "history of fiddling around" into "series of incremental improvements to a codebase" is the linux kernel.
It's more work for every developer, and digs into more advance git operations, but it really helps keep the tree clean. Most projects don't have a velocity that requires such well-groomed changes, but this is an example of how failing that can make the history ugly and changes more difficult to work with.
My ex-employer (Meraki) was VERY insistent on people cleaning up their histories. It was very good not just for keeping a clean tree, but also for code quality - once you have code changes in neatly-separated commits with discrete chunks of functionality, any leftover test code or unrelated changes pop out immediately to both the original coder and the reviewer.
By the way, this also helps with the issue this developer faced because part of the problem seems to have been that the backend and frontend changes were mixed in the same commits (hence the ugly hack for committing). Doing this kind of history-cleaning as you go makes it much easier to manipulate the order of committing changes to master.
What to do with commits that touch both back-end and front-end code in step 2.? This amounts to manual run of git-filter-branch, which is a feature the author was unaware of. Without that tool this task is daunting. If the author is willing to manually rewrite potentially hundreds of commits that touch back-end code, then there are a lot of straightforward solutions. We're looking for something more elegant.
I have dealt with that sort of thing, and roughly as follows. Having somehow identified these commits, I would mark them "edit" in the interactive rebase workflow. Then when such a commit is applied and the interactive rebase stops on it, I would use "git reset --patch HEAD^" to undo some of its changes in the index (while keeping the working tree the same). Then do a "git commit --amend" to overwrite the commit with pruned one. At that point, all the rejected changes appear as local modifications. Another "git commit -a" creates a new commit out of them; so the original became two. If the commit needs to become three you can just "git commit --patch" twice. Or just reset the whole original commit to HEAD^ and do several "git commit --patch" ops. (Use -c <original sha> to re-use the commit message as a basis for the new commit messages).
Typically I will do a rebase pass through the commit stack to do nothing but these splits in that pass. Then when things are separated out, do another interactive rebase to do the re-ordering and squashing.
> "What should X have done in the first place to avoid the pickle?"
0. (Of course, not develop a 406 patch changeset and then have to pick it apart. Make smaller pushes, frequently.)
1. Create a topic branch right there at the tip where the 406 changes are locally committed.
2. Then use git's interactive rebase to rewrite this branch such that just the back-end commits are picked first, followed by the front end.
3. Make a back-end topic branch from the last back-end commit and test that. If it's cool, master can be rebased to that and pushed to origin/master upstream.
4. Test remaining front-end changes, rebase master to them, push.
Also:
3. a) If back-end changes need fixing, fix them on the back-end-topic branch. Then rebase the original topic to the back end topic to pick up these changes "under" it. (I.e. replay the front end over the new back end, and install as new front end).