I'm trying to incorporate a community maintained patch on OpenSSH (Roumen Petrov's X.509v3 implementation) along with our own patches. This does not fit regular solutions as far as I know, as this patch is huge and all releases of this patch are very much bound to a specific upstream version of OpenSSH. The obvious upgrade of OpenSSH on top of the patched version is a plain merge conflict and exactly what I want to avoid, yet keeping the upstream and patched version distinct in Git.
Right now, I have done this in Git using branches:
master
gert/develop
vendor/orig
vendor/roumenpetrov
With
vendor/orig
being a plain, original OpenSSH branch of code with every commit one of the OpenSSH release versions, also tagged, e.g.5.9p1
vendor/roumenpetrov
being a branch forked fromvendor/orig
with the corresponding patch applied, also tagged, e.g.5.9p1+x509-7.1
gert/develop
being the "daily development" branch, based off thevendor/roumenpetrov
, now with a few local low-impact commits.master
being the branch for release-ready code
My goals are basically this:
- Detectability of all changes in code. E.g. "Are we on 6.0p1 already in
master
?" ->git branch --contains <commit-of-openssh-6.0p1>
yes/no answer. - Easy upgrade of both OpenSSH as well as the patches from Roumen, with the least effort on conflicts with the local patches.
- View upgrades new versions as single commits: e.g. "Upgrade to patch to X509-7.4" along with "Upgrade to new upstream 6.0p1".
Practically I have an issue with the model above. Suppose I want to upgrade to 6.0p1 along with the corresponding new 7.4 patch from Roumen. What should I do? I found the following options:
upgrade, revert, upgrade, merge
- In
vendor/orig
, upgrade the OpenSSH version. - In
vendor/roumenpetrov
, revert the previous commit (git revert 12345678
, the 7.1 patch). - In
vendor/roumenpetrov
, merge withvendor/orig
. - In
vendor/roumenpetrov
, apply the new patch and commit. - In
gert/develop
, merge withvendor/roumenpetrov
Problems: 1) a lot of actions to take, 2) The revert action is a separate commit confusing when reading the log ("6.0p1 release" -> "revert X509 7.1" -> "merge vendor/orig" -> "apply X509 7.4".), 3) the revert with subsequent re-patch actions could cause more than ideal probability of conflicts, right?
Plus side:
git log vendor/orig..vendor/roumenpetrov
shows me actual changes, although listing four commits.- In
same, but with
--no-commit
- In
vendor/roumenpetrov
:git revert -n <patch-7.1>
- In
vendor/roumenpetrov
:git cherry-pick -n <openssh-6.0p1>
- In
vendor/roumenpetrov
:git commit
magically recognizes this as the the same commit as from the message.
Problem:
git log vendor/roumenpetrov..vendor/orig
shows openssh-6.0p1 not being applied because it has a different commit hash (diff=empty).- In
merge
--squash
Problem: same as above, but for another reason.
rebase
Problem: we push this repository to a central (not-yet-public) location. Rebasing in the
vendor/roumenpetrov
branch on a newervendor/orig
is therefore not an option as far as I know if other people are working on this branch as well. This also holds for the other remote branches. See this answer as for why I believe rebasing is not an option for my case.And, is it true what svnpenn mentions?
without a rebase you have no other choice than to do ugly merge commits.
So, taking a step back, what is my best option here to have this maintainable? Do I have to take sacrifices for the inevitable reason being the patch from Roumen depending on a specific OpenSSH version? Do I have to revise this whole branching model? Or am I missing out on something very basic?